aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/kr/syeyoung
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/kr/syeyoung')
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ApiFetchur.java238
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/PlayerProfile.java18
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonFloorStat.java8
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonHighestFloorStat.java8
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererLilyWeight.java68
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererRegistry.java3
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererTalismans.java117
7 files changed, 451 insertions, 9 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ApiFetchur.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ApiFetchur.java
index d5843e7b..046d9a8e 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ApiFetchur.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/ApiFetchur.java
@@ -21,12 +21,14 @@ package kr.syeyoung.dungeonsguide.features.impl.party.api;
import com.google.gson.*;
import com.mojang.authlib.GameProfile;
import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import kr.syeyoung.dungeonsguide.utils.XPUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
+import org.json.JSONObject;
import scala.tools.cmd.Opt;
import java.io.ByteArrayInputStream;
@@ -36,6 +38,9 @@ import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.concurrent.*;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
public class ApiFetchur {
private static final Gson gson = new Gson();
@@ -59,6 +64,8 @@ public class ApiFetchur {
completableFutureMap3.clear();
completableFutureMap4.clear();
invalidKeys.clear();
+ completableFutureMapLily= null;
+ constants = null;
}
public static JsonObject getJson(String url) throws IOException {
@@ -74,6 +81,27 @@ public class ApiFetchur {
return gson.fromJson(new InputStreamReader(connection.getInputStream()), JsonArray.class);
}
+ private static JsonObject constants;
+ private static CompletableFuture<JsonObject> completableFutureMapLily;
+ public static CompletableFuture<JsonObject> getLilyWeightConstants() {
+ if (constants != null) return CompletableFuture.completedFuture(constants);
+ if (completableFutureMapLily != null) return completableFutureMapLily;
+ CompletableFuture<JsonObject> completableFuture = new CompletableFuture<>();
+ completableFutureMapLily = completableFuture;
+ ex.submit(() -> {
+ try {
+ JsonObject jsonObject = getJson("https://raw.githubusercontent.com/Antonio32A/lilyweight/master/lib/constants.json");
+ constants = jsonObject;
+ completableFuture.complete(jsonObject);
+ completableFutureMapLily= null;
+ } catch (Exception e) {
+ completableFuture.completeExceptionally(e);
+ completableFutureMapLily= null;
+ }
+ });
+ return completableFuture;
+ }
+
private static final Map<String, CompletableFuture<Optional<GameProfile>>> completableFutureMap4 = new ConcurrentHashMap<>();
public static CompletableFuture<Optional<GameProfile>> getSkinGameProfileByUUIDAsync(String uid) {
if (UIDtoGameProfile.containsKey(uid)) {
@@ -460,7 +488,215 @@ public class ApiFetchur {
DungeonClass dungeonClass = DungeonClass.getClassByJsonName(id);
playerProfile.setSelectedClass(dungeonClass);
}
-
+ try {
+ calculateLilyWeight(playerProfile, playerData);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
return playerProfile;
}
+
+ private static void calculateLilyWeight(PlayerProfile playerProfile, JsonObject playerData) throws ExecutionException, InterruptedException {
+ JsonObject constants = getLilyWeightConstants().get();
+ double[] slayerXP = new double[4];
+ if (playerData.has("slayer_bosses")) {
+ slayerXP[0] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("zombie"), "xp", 0);
+ slayerXP[1] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("spider"), "xp", 0);
+ slayerXP[2] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("wolf"), "xp", 0);
+ slayerXP[3] = getOrDefault(playerData.getAsJsonObject("slayer_bosses").getAsJsonObject("enderman"), "xp", 0);
+ }
+ double skillWeight = 0;
+ double overflowWeight = 0;
+ {
+ JsonObject srw = constants.getAsJsonObject("skillRatioWeight");
+ int skillMaxXP = constants.get("skillMaxXP").getAsInt();
+ JsonArray overflowMultiplier = constants.getAsJsonArray("skillOverflowMultipliers");
+ JsonArray skillFactor = constants.getAsJsonArray("skillFactors");
+
+ double skillAvg = playerProfile.getSkillXp().entrySet().stream()
+ .filter(a -> a.getValue() != null)
+ .filter(a -> srw.has(a.getKey().getJsonName()))
+ .map(a -> XPUtils.getSkillXp(a.getKey(), a.getValue()).getLevel()).collect(Collectors.averagingInt(a -> a));
+
+ double n = 12 * (skillAvg/60)*(skillAvg/60);
+ double r2 = Math.sqrt(2);
+
+ for (Map.Entry<Skill, Double> skillDoubleEntry : playerProfile.getSkillXp().entrySet()) {
+ String jsonName = skillDoubleEntry.getKey().getJsonName();
+ JsonArray temp_srw = srw.getAsJsonArray(jsonName);
+ if (temp_srw == null) continue;
+ int lv = XPUtils.getSkillXp(skillDoubleEntry.getKey(), skillDoubleEntry.getValue()).getLevel();
+ skillWeight += n * temp_srw.get(lv).getAsDouble()
+ * temp_srw.get(temp_srw.size() - 1).getAsDouble();
+ skillWeight += temp_srw.get(temp_srw.size() - 1).getAsDouble() * Math.pow(lv/60.0, r2);
+ }
+
+ int cnt = 0;
+ for (Map.Entry<String, JsonElement> skillNames : constants.getAsJsonObject("skillNames").entrySet()) {
+ Skill s = getSkillByLilyName(skillNames.getKey());
+ double factor = skillFactor.get(cnt).getAsDouble();
+ double effectiveOver;
+ Double xp = playerProfile.getSkillXp().get(s);
+ if (xp == null) continue; xp -= skillMaxXP;
+ {
+ if (xp < skillMaxXP) effectiveOver = xp;
+ else {
+ double remainingXP = xp;
+ double z = 0;
+ for (int i = 0; i<= xp/skillMaxXP; i++) {
+ if (remainingXP >= skillMaxXP) {
+ remainingXP -= skillMaxXP;
+ z += Math.pow(factor, i);
+ }
+ }
+ effectiveOver = z * skillMaxXP;
+ }
+ }
+ double rating = effectiveOver / skillMaxXP;
+ double overflowMult = overflowMultiplier.get(cnt).getAsDouble();
+ double t = rating * overflowMult;
+ if (t > 0) overflowWeight += t;
+ cnt++;
+ }
+ }
+ double cataCompWeight, masterCompWeight;
+ {
+ JsonArray completionFactor = constants.getAsJsonArray("dungeonCompletionWorth");
+ JsonObject dungeonCompletionBuffs = constants.getAsJsonObject("dungeonCompletionBuffs");
+ double max1000 = 0;
+ double mMax1000 = 0;
+ for (int i = 0; i < completionFactor.size(); i++) {
+ if (i < 8) max1000 += completionFactor.get(i).getAsDouble();
+ else mMax1000 += completionFactor.get(i).getAsDouble();
+ }
+
+ max1000 *= 1000;
+ mMax1000 *= 1000;
+
+ double upperBound = 1500; double score = 0;
+
+ DungeonStat dStat = playerProfile.getDungeonStats().get(DungeonType.CATACOMBS).getData();
+ for (FloorSpecificData<DungeonStat.PlayedFloor> value : dStat.getPlays().values()) {
+ int runs = value.getData().getCompletions();
+ int excess = 0; if (runs > 1000) {
+ excess = runs - 1000; runs = 1000;
+ }
+
+ double floorScore = runs * completionFactor.get(value.getFloor()).getAsDouble();
+ if (excess > 0)
+ floorScore *= Math.log10(excess / 1000.0 + 1) / Math.log10(7.5) + 1;
+ score += floorScore;
+ }
+ cataCompWeight = (score / max1000 * upperBound);
+
+ dStat = playerProfile.getDungeonStats().get(DungeonType.MASTER_CATACOMBS).getData();
+ for (FloorSpecificData<DungeonStat.PlayedFloor> value : dStat.getPlays().values()) {
+ if (dungeonCompletionBuffs.has(value.getFloor()+"")) {
+ double threshold = 20;
+ if (value.getData().getCompletions() >= threshold) upperBound += dungeonCompletionBuffs.get(value.getFloor()+"").getAsDouble();
+ else upperBound += dungeonCompletionBuffs.get(value.getFloor()+"").getAsDouble() * Math.pow(value.getData().getCompletions()/threshold, 1.840896416);
+ }
+ }
+ score = 0;
+ for (FloorSpecificData<DungeonStat.PlayedFloor> value : dStat.getPlays().values()) {
+ int runs = value.getData().getCompletions();
+ int excess = 0; if (runs > 1000) {
+ excess = runs - 1000; runs = 1000;
+ }
+
+ double floorScore = runs * completionFactor.get(value.getFloor()+7).getAsDouble();
+ if (excess > 0)
+ floorScore *= Math.log10(excess / 1000.0 + 1) / Math.log10(5) + 1;
+ score += floorScore;
+ }
+
+ masterCompWeight = score / mMax1000 * upperBound;
+ }
+ double dungeonXPWeight = 0;
+ {
+ double dungeonOverall = constants.get("dungeonOverall").getAsDouble();
+ double dungeonMaxXP = constants.get("dungeonMaxXP").getAsDouble();
+
+ double cataXP = playerProfile.getDungeonStats().get(DungeonType.CATACOMBS).getData().getExperience();
+ XPUtils.XPCalcResult xpCalcResult = XPUtils.getCataXp(cataXP);
+ double level = xpCalcResult.getLevel();
+ if (xpCalcResult.getLevel() != 50) {
+ double progress = Math.floor(xpCalcResult.getRemainingXp() / xpCalcResult.getNextLvXp() * 1000) / 1000.0;
+ level += progress;
+ }
+
+ double n; double tempLevel = 0;
+ if (cataXP < dungeonMaxXP)
+ n = 0.2 * Math.pow(level / 50.0, 2.967355422);
+ else {
+ double part = 142452410;
+ tempLevel = 50 + (cataXP - dungeonMaxXP) / part;
+ n = 0.2 * Math.pow(1 + ((tempLevel - 50) / 50), 2.967355422);
+ }
+ if (level != 0) {
+ if (cataXP < 569809640) dungeonXPWeight = dungeonOverall * (Math.pow(1.18340401286164044, (level + 1)) - 1.05994990217254) * (1 + n);
+ else dungeonXPWeight =4000 * (n / 0.15465244570598540);
+ } else dungeonXPWeight = 0;
+ }
+ double slayerWeight = 0;
+ {
+ JsonArray slayerDeprecationScaling = constants.getAsJsonArray("slayerDeprecationScaling");
+ BiFunction<Double, Integer, Double> getSlayerWeight = (xp, type) -> {
+ double score = 0;
+ {
+ double d = xp / 100000;
+ if (xp >= 6416) {
+ double D = (d - Math.pow(3, (-5 / 2.0))) * (d + Math.pow(3, -5 / 2.0));
+ double u = Math.cbrt(3 * (d + Math.sqrt(D)));
+ double v = Math.cbrt(3 * (d - Math.sqrt(D)));
+ score = u + v - 1;
+ } else {
+ score = Math.sqrt(4 / 3.0) * Math.cos(Math.acos(d * Math.pow(3, 5 / 2.0)) / 3) - 1;
+ }
+ }
+ score = Math.floor(score);
+ double scaling = slayerDeprecationScaling.get(type).getAsDouble();
+ double effectiveXP = 0;
+ for (int i = 1; i <= score; i++)
+ effectiveXP += (i * i + i) * Math.pow(scaling, i);
+ effectiveXP = Math.round((1000000 * effectiveXP * (0.05 / scaling)) * 100) / 100.0;
+ double actualXP = ((score*score*score / 6) + (score*score / 2) + (score / 3)) * 100000;
+ double distance = xp - actualXP;
+ double effectiveDistance = distance * Math.pow(scaling, score);
+ return effectiveXP + effectiveDistance;
+ };
+
+ double zombie = getSlayerWeight.apply(slayerXP[0], 0);
+ double spider = getSlayerWeight.apply(slayerXP[1], 1);
+ double wolf = getSlayerWeight.apply(slayerXP[2], 2);
+ double enderman = getSlayerWeight.apply(slayerXP[3], 3);
+ double individual = zombie / 7000 + spider / 4800 + wolf / 2200 + enderman / 1000;
+ double extra = (slayerXP[0] + 1.6 * slayerXP[1] + 3.6 * slayerXP[2] + 10 * slayerXP[3]) / 900000;
+ slayerWeight = (individual + extra);
+ }
+
+ PlayerProfile.LilyWeight lilyWeight = new PlayerProfile.LilyWeight();
+ lilyWeight.setCatacombs_base(cataCompWeight);
+ lilyWeight.setCatacombs_master(masterCompWeight);
+ lilyWeight.setCatacombs_exp(dungeonXPWeight);
+ lilyWeight.setSkill_base(skillWeight);
+ lilyWeight.setSkill_overflow(overflowWeight);
+ lilyWeight.setSlayer(slayerWeight);
+
+ playerProfile.setLilyWeight(lilyWeight);
+ }
+
+ private static Skill getSkillByLilyName(String lilyName) {
+ switch(lilyName) {
+ case "experience_skill_enchanting": return Skill.ENCHANTING;
+ case "experience_skill_taming": return Skill.TAMING;
+ case "experience_skill_alchemy": return Skill.ALCHEMY;
+ case "experience_skill_mining": return Skill.MINING;
+ case "experience_skill_farming": return Skill.FARMING;
+ case "experience_skill_foraging": return Skill.FORAGING;
+ case "experience_skill_combat": return Skill.COMBAT;
+ case "experience_skill_fishing": return Skill.FISHING;
+ default: return null;
+ }
+ }
}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/PlayerProfile.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/PlayerProfile.java
index 0bb441d2..a9c1a272 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/PlayerProfile.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/api/PlayerProfile.java
@@ -70,4 +70,22 @@ public class PlayerProfile {
private List<Pet> pets = new ArrayList<>();
+
+ private Map<String, Object> additionalProperties = new HashMap<>();
+
+ private LilyWeight lilyWeight;
+
+ @Data
+ public static class LilyWeight {
+ private double skill_base;
+ private double skill_overflow;
+ private double catacombs_base;
+ private double catacombs_master;
+ private double catacombs_exp;
+ private double slayer;
+
+ public double getTotal() {
+ return skill_base + skill_overflow + catacombs_base + catacombs_exp + catacombs_master + slayer;
+ }
+ }
} \ No newline at end of file
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonFloorStat.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonFloorStat.java
index 1e844e13..627b1881 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonFloorStat.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonFloorStat.java
@@ -48,7 +48,7 @@ public class DataRenderDungeonFloorStat implements DataRenderer {
if (playedFloorFloorSpecificData != null) {
flag = true;
fr.drawString("§b" + floorName + " §a" + playedFloorFloorSpecificData.getData().getBestScore() + " §f" + playedFloorFloorSpecificData.getData().getCompletions() + "§7/§f" + playedFloorFloorSpecificData.getData().getWatcherKills() + "§7/§f" + playedFloorFloorSpecificData.getData().getTimes_played() + " §7(" + (int) (playedFloorFloorSpecificData.getData().getCompletions()*100 / (double) playedFloorFloorSpecificData.getData().getWatcherKills()) + "%)", 0, 0, -1);
- fr.drawString("§6S+ §e" + (playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "N/A") + " §6S §e" + (playedFloorFloorSpecificData.getData().getFastestTimeS() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "N/A"), 0, fr.FONT_HEIGHT, -1);
+ fr.drawString("§6S+ §e" + (playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A") + " §6S §e" + (playedFloorFloorSpecificData.getData().getFastestTimeS() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"), 0, fr.FONT_HEIGHT, -1);
}
}
if (!flag) {
@@ -90,9 +90,9 @@ public class DataRenderDungeonFloorStat implements DataRenderer {
"§bTotal Completions§7: §f"+playedFloorFloorSpecificData.getData().getCompletions(),
"§bTotal Watcher kills§7: §f"+playedFloorFloorSpecificData.getData().getWatcherKills(),
"§bTotal Runs§7: §f"+playedFloorFloorSpecificData.getData().getTimes_played(),
- "§bFastest S+§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "N/A"),
- "§bFastest S§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeS() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "N/A"),
- "§bFastest Run§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTime() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTime()) : "N/A"),
+ "§bFastest S+§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A"),
+ "§bFastest S§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeS() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"),
+ "§bFastest Run§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTime() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTime()) : "§7N/A"),
"§bMost Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMostMobsKilled(),
"§bTotal Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMobsKilled()
), mouseX, mouseY, scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonHighestFloorStat.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonHighestFloorStat.java
index dd14bee4..d19fa2f1 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonHighestFloorStat.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRenderDungeonHighestFloorStat.java
@@ -47,7 +47,7 @@ public class DataRenderDungeonHighestFloorStat implements DataRenderer {
if (playedFloorFloorSpecificData != null) {
flag = true;
fr.drawString("§bH: " + floorName + " §a" + playedFloorFloorSpecificData.getData().getBestScore() + " §f" + playedFloorFloorSpecificData.getData().getCompletions() + "§7/§f" + playedFloorFloorSpecificData.getData().getWatcherKills() + "§7/§f" + playedFloorFloorSpecificData.getData().getTimes_played() + " §7(" + (int) (playedFloorFloorSpecificData.getData().getCompletions() *100/ (double) playedFloorFloorSpecificData.getData().getWatcherKills()) + "%)", 0, 0, -1);
- fr.drawString("§6S+ §e" + (playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "N/A") + " §6S §e" + (playedFloorFloorSpecificData.getData().getFastestTimeS() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "N/A"), 0, fr.FONT_HEIGHT, -1);
+ fr.drawString("§6S+ §e" + (playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A") + " §6S §e" + (playedFloorFloorSpecificData.getData().getFastestTimeS() != -1 ? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"), 0, fr.FONT_HEIGHT, -1);
}
}
}
@@ -92,9 +92,9 @@ public class DataRenderDungeonHighestFloorStat implements DataRenderer {
"§bTotal Completions§7: §f"+playedFloorFloorSpecificData.getData().getCompletions(),
"§bTotal Watcher kills§7: §f"+playedFloorFloorSpecificData.getData().getWatcherKills(),
"§bTotal Runs§7: §f"+playedFloorFloorSpecificData.getData().getTimes_played(),
- "§bFastest S+§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "N/A"),
- "§bFastest S§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeS() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "N/A"),
- "§bFastest Run§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTime() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTime()) : "N/A"),
+ "§bFastest S+§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeSPlus() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeSPlus()) : "§7N/A"),
+ "§bFastest S§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTimeS() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTimeS()) : "§7N/A"),
+ "§bFastest Run§7: §f"+(playedFloorFloorSpecificData.getData().getFastestTime() != -1? TextUtils.formatTime(playedFloorFloorSpecificData.getData().getFastestTime()) : "§7N/A"),
"§bMost Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMostMobsKilled(),
"§bTotal Mobs Killed§7: §f"+playedFloorFloorSpecificData.getData().getMobsKilled()
), mouseX, mouseY, scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererLilyWeight.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererLilyWeight.java
new file mode 100644
index 00000000..a97ebae3
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererLilyWeight.java
@@ -0,0 +1,68 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
+import kr.syeyoung.dungeonsguide.utils.TextUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fml.client.config.GuiUtils;
+
+import java.awt.*;
+import java.util.Arrays;
+
+public class DataRendererLilyWeight implements DataRenderer {
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§eLily Weight §b"+String.format("%.3f", playerProfile.getLilyWeight().getTotal()), 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§eLily Weight §b300", 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+ PlayerProfile.LilyWeight lilyWeight= playerProfile.getLilyWeight();
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ GuiUtils.drawHoveringText(Arrays.asList(
+ "§bDungeon Weights§7: §e"+ String.format("%.3f",lilyWeight.getCatacombs_base()+lilyWeight.getCatacombs_master()+lilyWeight.getCatacombs_exp()),
+ " §bCatacomb Completion§7: §e"+String.format("%.3f",lilyWeight.getCatacombs_base()),
+ " §bMaster Completion§7: §e"+String.format("%.3f", lilyWeight.getCatacombs_master()),
+ " §bExperience§7: §e"+String.format("%.3f", lilyWeight.getCatacombs_exp()),
+ "§bSkill Weights§7: §e"+ String.format("%.3f", lilyWeight.getSkill_base() + lilyWeight.getSkill_overflow()),
+ " §bSkill Weight§7: §e"+String.format("%.3f", lilyWeight.getSkill_base()),
+ " §bOverflow Weight§7: §e"+String.format("%.3f", lilyWeight.getSkill_overflow()),
+ "§bSlayer Weight§7: §e"+String.format("%.3f", lilyWeight.getSlayer()),
+ "§bTotal§7: §e"+String.format("%.3f", lilyWeight.getTotal())
+ ),mouseX, mouseY,
+ scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererRegistry.java
index 7eab126b..56e69feb 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererRegistry.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererRegistry.java
@@ -56,5 +56,8 @@ public class DataRendererRegistry {
dataRendererMap.put("secrets", new DataRendererSecrets());
dataRendererMap.put("dummy", new DataRendererSetUrOwn());
+
+ dataRendererMap.put("talismans", new DataRendererTalismans());
+ dataRendererMap.put("weight", new DataRendererLilyWeight());
}
}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererTalismans.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererTalismans.java
new file mode 100644
index 00000000..2112362f
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/party/playerpreview/DataRendererTalismans.java
@@ -0,0 +1,117 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.features.impl.party.playerpreview;
+
+import kr.syeyoung.dungeonsguide.features.impl.party.api.PlayerProfile;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraftforge.fml.client.config.GuiUtils;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class DataRendererTalismans implements DataRenderer {
+ @Override
+ public Dimension renderData(PlayerProfile playerProfile) {
+ if (!playerProfile.getAdditionalProperties().containsKey("talismanCnt")) {
+ int[] cnts = new int[Rarity.values().length];
+ for (ItemStack talisman : playerProfile.getTalismans()) {
+ if (talisman == null) continue;
+ Rarity r = getRarity(talisman);
+ if (r != null) cnts[r.ordinal()]++;
+ }
+ for (ItemStack itemStack : playerProfile.getInventory()) {
+ if (itemStack == null) continue;
+ Rarity r = getRarity(itemStack);
+ if (r != null) cnts[r.ordinal()]++;
+ }
+ playerProfile.getAdditionalProperties().put("talismanCnt", cnts);
+ }
+ int[] rawData = (int[]) playerProfile.getAdditionalProperties().get("talismanCnt");
+ String str = "";
+ for (Rarity r : Rarity.values()) {
+ str = r.color+rawData[r.idx] +" "+ str;
+ }
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§eTalis §f"+str, 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+
+ private Rarity getRarity(ItemStack itemStack) {
+ NBTTagCompound display = itemStack.getTagCompound().getCompoundTag("display");
+ if (display == null) return null;
+ NBTTagList lore = display.getTagList("Lore", 8);
+ if (lore == null) return null;
+ for (int i = 0; i < lore.tagCount(); i++) {
+ String line = lore.getStringTagAt(i);
+ for (Rarity value : Rarity.values()) {
+ if (line.startsWith(value.getColor()) && line.contains("CCESSORY")) return value;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Dimension renderDummy() {
+ String str = "";
+ for (Rarity r : Rarity.values()) {
+ str = r.color+(r.idx+5)*2+" "+str;
+ }
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("§eTalis §f"+str, 0,0,-1);
+ return new Dimension(100, fr.FONT_HEIGHT);
+ }
+ @Override
+ public Dimension getDimension() {
+ return new Dimension(100, Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT);
+ }
+
+ @Override
+ public void onHover(PlayerProfile playerProfile, int mouseX, int mouseY) {
+ int[] rawData = (int[]) playerProfile.getAdditionalProperties().get("talismanCnt");
+ if (rawData == null) return;
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ List<String> list = new ArrayList<>();
+
+ for (Rarity r : Rarity.values()) {
+ list.add(r.getColor()+r.name()+"§7: §e"+rawData[r.idx]);
+ }
+ GuiUtils.drawHoveringText(list,mouseX, mouseY,
+ scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(), -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+
+
+ @AllArgsConstructor @Getter
+ public static enum Rarity {
+ COMMON("§f", 0), UNCOMMON("§a",1), RARE("§9",2), EPIC("§5",3), LEGENDARY("§6",4), MYTHIC("§d",5);
+
+ private String color;
+ private int idx;
+ }
+}