From 16b5aeb4647b13d49b8d679a417bdbc0b4ff6aba Mon Sep 17 00:00:00 2001 From: Cow Date: Sun, 30 May 2021 18:35:30 +0200 Subject: (Dungeons) player lookups additions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - added ironman icon ♲ - added average secrets per completion --- CHANGELOG.md | 7 +++++ .../cowtipper/cowlection/command/MooCommand.java | 3 +- .../cowtipper/cowlection/data/HySkyBlockStats.java | 33 ++++++++++++++++++++++ .../cowlection/listener/ChatListener.java | 26 ++++++++++++----- .../listener/skyblock/DungeonsPartyListener.java | 20 ++++++++++--- 5 files changed, 77 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7c7719..f3a0cde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [1.8.9-0.14.0] - unreleased +### Added +- (Dungeons) player lookups: + - added ironman icon ♲ + - added average secrets per completion + ## [1.8.9-0.13.0] - 25.04.2021 ### Added - Bestiary Overview: enhances tooltips of `/bestiary` ⬌ `/be` @@ -316,6 +322,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). *Note:* The 'best friends' list is currently available via ESC > Mod Options > Cowlection > Config > bestFriends. +[1.8.9-0.14.0]: https://github.com/cow-mc/Cowlection/compare/v1.8.9-0.13.0...master [1.8.9-0.13.0]: https://github.com/cow-mc/Cowlection/compare/v1.8.9-0.12.0...v1.8.9-0.13.0 [1.8.9-0.12.0]: https://github.com/cow-mc/Cowlection/compare/v1.8.9-0.11.0...v1.8.9-0.12.0 [1.8.9-0.11.0]: https://github.com/cow-mc/Cowlection/compare/v1.8.9-0.10.2...v1.8.9-0.11.0 diff --git a/src/main/java/de/cowtipper/cowlection/command/MooCommand.java b/src/main/java/de/cowtipper/cowlection/command/MooCommand.java index 7deec61..6e5cc0e 100644 --- a/src/main/java/de/cowtipper/cowlection/command/MooCommand.java +++ b/src/main/java/de/cowtipper/cowlection/command/MooCommand.java @@ -467,7 +467,8 @@ public class MooCommand extends CommandBase { wealthHover.appendFreshSibling(new MooChatComponent.KeyValueTooltipComponent("Co-ops' purses sum", Utils.formatNumberWithAbbreviations(activeProfile.getCoopCoinPurses(stalkedPlayer.getUuid())))); } - MooChatComponent sbStats = new MooChatComponent("SkyBlock stats of " + stalkedPlayer.getName() + " (" + activeProfile.getCuteName() + ")").gold().bold().setUrl("https://sky.shiiyu.moe/stats/" + stalkedPlayer.getName() + "/" + activeProfile.getCuteName(), "Click to view SkyBlock stats on sky.shiiyu.moe") + String gameModeIcon = activeProfile.getGameModeIcon(); + MooChatComponent sbStats = new MooChatComponent("SkyBlock stats of " + stalkedPlayer.getName() + EnumChatFormatting.RESET + EnumChatFormatting.GRAY + " (" + (gameModeIcon.isEmpty() ? "" : EnumChatFormatting.getTextWithoutFormattingCodes(gameModeIcon) + ", ") + activeProfile.getCuteName() + ")").gold().bold().setUrl("https://sky.shiiyu.moe/stats/" + stalkedPlayer.getName() + "/" + activeProfile.getCuteName(), "Click to view SkyBlock stats on sky.shiiyu.moe") .appendFreshSibling(new MooChatComponent.KeyValueChatComponent("Coins", coinsBankAndPurse).setHover(wealthHover)); // highest skill + skill average: if (highestSkill != null) { diff --git a/src/main/java/de/cowtipper/cowlection/data/HySkyBlockStats.java b/src/main/java/de/cowtipper/cowlection/data/HySkyBlockStats.java index 7673b60..8a3e067 100644 --- a/src/main/java/de/cowtipper/cowlection/data/HySkyBlockStats.java +++ b/src/main/java/de/cowtipper/cowlection/data/HySkyBlockStats.java @@ -9,6 +9,7 @@ import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StringUtils; import net.minecraftforge.common.util.Constants; import org.apache.commons.codec.binary.Base64; @@ -63,6 +64,7 @@ public class HySkyBlockStats { public static class Profile { private String cute_name; private Map members; + private String game_mode; private Banking banking; /** @@ -79,6 +81,15 @@ public class HySkyBlockStats { return members.get(UUIDTypeAdapter.fromUUID(uuid)); } + public String getGameModeIcon() { + if (StringUtils.isNullOrEmpty(game_mode)) { + return ""; + } else if ("ironman".equals(game_mode)) { + return EnumChatFormatting.GRAY + "♲"; + } + return ""; + } + public double getCoinBank() { return (banking != null) ? banking.balance : -1; } @@ -398,6 +409,18 @@ public class HySkyBlockStats { return dungeonTypesLevels.toString(); } + public int getTotalDungeonCompletions() { + int totalDungeonCompletions = 0; + if (dungeon_types != null) { + for (Type dungeonType : dungeon_types.values()) { + if (dungeonType != null && dungeonType.hasPlayed()) { + totalDungeonCompletions += dungeonType.getTotalTierCompletions(); + } + } + } + return totalDungeonCompletions; + } + public static class Type { private Map times_played; private Map tier_completions; @@ -425,6 +448,16 @@ public class HySkyBlockStats { return experience > 0 || best_score != null; } + public int getTotalTierCompletions() { + int totalTierCompletions = 0; + if (tier_completions != null) { + for (Integer completions : tier_completions.values()) { + totalTierCompletions += completions; + } + } + return totalTierCompletions; + } + /** * Level [lvl] ([amount]x Floor [highest]) * diff --git a/src/main/java/de/cowtipper/cowlection/listener/ChatListener.java b/src/main/java/de/cowtipper/cowlection/listener/ChatListener.java index b1afb47..e0ce09b 100644 --- a/src/main/java/de/cowtipper/cowlection/listener/ChatListener.java +++ b/src/main/java/de/cowtipper/cowlection/listener/ChatListener.java @@ -182,7 +182,7 @@ public class ChatListener { if (!joinedYourself && MooConfig.getDungPartyFinderPlayerLookupDisplay() != MooConfig.Setting.DISABLED) { // another player joined via Dungeon Party Finder String dungeonClass = dungeonPartyFinderJoinedMatcher.group(2) + " Lvl " + dungeonPartyFinderJoinedMatcher.group(3); - getDungeonPartyMemberDetails(messageSender, dungeonClass); + getNewDungeonPartyMemberDetails(messageSender, dungeonClass); } else if (joinedYourself && MooConfig.dungPartyFinderPartyLookup) { // successfully joined another party via Dungeon Party Finder main.getDungeonCache().lookupPartyMembers(); @@ -199,7 +199,7 @@ public class ChatListener { } } - private void getDungeonPartyMemberDetails(String playerName, String dungeonClass) { + private void getNewDungeonPartyMemberDetails(String playerName, String dungeonClass) { ApiUtils.fetchFriendData(playerName, stalkedPlayer -> { if (stalkedPlayer != null && !stalkedPlayer.equals(Friend.FRIEND_NOT_FOUND)) { ApiUtils.fetchSkyBlockStats(stalkedPlayer, hySBStalking -> { @@ -212,7 +212,8 @@ public class ChatListener { boolean outputAsChatMessages = MooConfig.getDungPartyFinderPlayerLookupDisplay() == MooConfig.Setting.TEXT; HySkyBlockStats.Profile.Member member = activeProfile.getMember(stalkedPlayer.getUuid()); - String armorLookupPrefix = " ❈ " + EnumChatFormatting.DARK_GREEN + playerName; + String gameModeIcon = activeProfile.getGameModeIcon(); + String armorLookupPrefix = " ➲ " + gameModeIcon + (gameModeIcon.isEmpty() ? "" : " ") + EnumChatFormatting.DARK_GREEN + playerName; String delimiter = "\n" + (outputAsChatMessages ? " " : ""); HySkyBlockStats.Profile.Dungeons dungeons = member.getDungeons(); @@ -233,25 +234,36 @@ public class ChatListener { String highestFloorCompletions = "\n" + (outputAsChatMessages ? " " : "") + EnumChatFormatting.GRAY + "Completed no dungeons yet"; String skyBlockDetails; + boolean hasPlayedDungeons = dungeons != null && dungeons.hasPlayed(); + int totalDungeonCompletions = hasPlayedDungeons ? dungeons.getTotalDungeonCompletions() : 0; if (outputAsChatMessages) { // highest floor completions: - if (dungeons != null && dungeons.hasPlayed()) { + if (hasPlayedDungeons) { highestFloorCompletions = dungeons.getHighestFloorCompletions(1, true).toString(); } skyBlockDetails = armorLookupPrefix + armorLookupResult + petInfo + highestFloorCompletions; } else { // as a tooltip: == MooConfig.Setting.TOOLTIP - if (dungeons != null && dungeons.hasPlayed()) { + if (hasPlayedDungeons) { // highest floor completions: highestFloorCompletions = dungeons.getHighestFloorCompletions(3, false).toString(); } - skyBlockDetails = EnumChatFormatting.BOLD + playerName + armorLookupResult + petInfo + highestFloorCompletions; + skyBlockDetails = gameModeIcon + (gameModeIcon.isEmpty() ? "" : " " + EnumChatFormatting.WHITE) + EnumChatFormatting.BOLD + playerName + armorLookupResult + petInfo + highestFloorCompletions; } ApiUtils.fetchHyPlayerDetails(stalkedPlayer, hyPlayerData -> { String foundDungeonsSecrets = ""; if (hyPlayerData != null) { - foundDungeonsSecrets = "\n" + (outputAsChatMessages ? " " : "") + EnumChatFormatting.GRAY + "Found secrets: " + EnumChatFormatting.GOLD + hyPlayerData.getAchievement("skyblock_treasure_hunter"); + int foundSecrets = hyPlayerData.getAchievement("skyblock_treasure_hunter"); + foundDungeonsSecrets = "\n" + (outputAsChatMessages ? " " : "") + EnumChatFormatting.GRAY + "Found secrets: " + EnumChatFormatting.GOLD + foundSecrets; + + String averageSecretsPerCompletion = null; + if (foundSecrets > 0 && totalDungeonCompletions > 0) { + averageSecretsPerCompletion = Utils.formatDecimal(foundSecrets / (1d * totalDungeonCompletions)); + } + if (averageSecretsPerCompletion != null) { + foundDungeonsSecrets += EnumChatFormatting.GRAY + " (" + EnumChatFormatting.YELLOW + averageSecretsPerCompletion + EnumChatFormatting.GRAY + "/completion)"; + } } MooChatComponent armorLookupComponent; diff --git a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsPartyListener.java b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsPartyListener.java index 9b11940..dd8bec0 100644 --- a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsPartyListener.java +++ b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsPartyListener.java @@ -213,8 +213,6 @@ public class DungeonsPartyListener { continue; } UUID uuid = partyMember.getValue().get(); - // player name: - playerEntry.append(" ").append(EnumChatFormatting.DARK_GREEN).append(partyMemberName).append(EnumChatFormatting.LIGHT_PURPLE).append(" ➜ ").append(EnumChatFormatting.GRAY); HySkyBlockStats sbStats = partyMemberStats.get(partyMemberName); if (sbStats != null && sbStats.isSuccess()) { @@ -227,13 +225,17 @@ public class DungeonsPartyListener { continue; } // ^ abort if any of the above failed, otherwise visualize API data: + // player name + game mode icon: + String gameModeIcon = activeProfile.getGameModeIcon(); + playerEntry.append(" ").append(gameModeIcon).append(gameModeIcon.isEmpty() ? "" : " ").append(EnumChatFormatting.DARK_GREEN).append(partyMemberName).append(EnumChatFormatting.LIGHT_PURPLE).append(" ➜ ").append(EnumChatFormatting.GRAY); + HySkyBlockStats.Profile.Member member = activeProfile.getMember(uuid); // active pet: HySkyBlockStats.Profile.Pet activePet = member.getActivePet(); // append player name + class and class level + armor + active pet - playerTooltip.append(EnumChatFormatting.WHITE).append(EnumChatFormatting.BOLD).append(partyMemberName).append(EnumChatFormatting.LIGHT_PURPLE).append(" ➜ ").append(EnumChatFormatting.GRAY).append(EnumChatFormatting.ITALIC).append("no class selected") + playerTooltip.append(gameModeIcon).append(gameModeIcon.isEmpty() ? "" : " ").append(EnumChatFormatting.WHITE).append(EnumChatFormatting.BOLD).append(partyMemberName).append(EnumChatFormatting.LIGHT_PURPLE).append(" ➜ ").append(EnumChatFormatting.GRAY).append(EnumChatFormatting.ITALIC).append("no class selected") .append("\n").append(String.join("\n", member.getArmor())) .append("\n\n").append(EnumChatFormatting.GRAY).append("Active pet: ").append(activePet != null ? activePet.toFancyString() : "" + EnumChatFormatting.DARK_GRAY + EnumChatFormatting.ITALIC + "none"); @@ -267,7 +269,17 @@ public class DungeonsPartyListener { playerTooltip.append(dungeons.getHighestFloorCompletions(3, false)); // found dungeon secrets: - playerTooltip.append("\n").append(EnumChatFormatting.GRAY).append("Found secrets: ").append(EnumChatFormatting.GOLD).append(partyMemberFoundDungeonSecrets.getOrDefault(partyMemberName, 0)); + int foundSecrets = partyMemberFoundDungeonSecrets.getOrDefault(partyMemberName, 0); + int totalDungeonCompletions = dungeons.getTotalDungeonCompletions(); + String averageSecretsPerCompletion = null; + if (foundSecrets > 0 && totalDungeonCompletions > 0) { + averageSecretsPerCompletion = Utils.formatDecimal(foundSecrets / (1d * totalDungeonCompletions)); + } + + playerTooltip.append("\n").append(EnumChatFormatting.GRAY).append("Found secrets: ").append(EnumChatFormatting.GOLD).append(foundSecrets); + if (averageSecretsPerCompletion != null) { + playerTooltip.append(EnumChatFormatting.GRAY).append(" (").append(EnumChatFormatting.YELLOW).append(averageSecretsPerCompletion).append(EnumChatFormatting.GRAY).append("/completion)"); + } } else { playerEntry.setLength(0); playerEntry.append(errorNamePrefix).append("API error").append(sbStats != null && sbStats.getCause() != null ? ": " + sbStats.getCause() : ""); -- cgit