From cdd9441aa587ef7ecb2ac285350f59846b433ff9 Mon Sep 17 00:00:00 2001 From: Emirlol <81419447+Emirlol@users.noreply.github.com> Date: Sun, 7 Jan 2024 02:06:28 +0300 Subject: Add dungeon score calculation on client-side --- .../hysky/skyblocker/config/SkyblockerConfig.java | 14 + .../config/categories/DungeonsCategory.java | 30 ++- .../config/categories/MessageFilterCategory.java | 8 + .../skyblocker/skyblock/dungeon/DungeonScore.java | 290 ++++++++++++++++++--- .../skyblocker/skyblock/filters/MimicFilter.java | 26 ++ src/main/java/de/hysky/skyblocker/utils/Utils.java | 27 ++ .../skyblocker/utils/chat/ChatMessageListener.java | 7 +- 7 files changed, 356 insertions(+), 46 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index aa6e5d24..e07a7588 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -605,6 +605,9 @@ public class SkyblockerConfig { @SerialEntry public DungeonChestProfit dungeonChestProfit = new DungeonChestProfit(); + @SerialEntry + public MimicMessages mimicMessages = new MimicMessages(); + @SerialEntry public boolean croesusHelper = true; @@ -785,6 +788,14 @@ public class SkyblockerConfig { public Formatting incompleteColor = Formatting.BLUE; } + public static class MimicMessages { + @SerialEntry + public boolean sendMimicMessages = true; + + @SerialEntry + public String mimicMessage = "Mimic dead!"; + } + public static class LividColor { @SerialEntry public boolean enableLividColorGlow = true; @@ -969,6 +980,9 @@ public class SkyblockerConfig { @SerialEntry public ChatFilterResult hideToggleSkyMall = ChatFilterResult.PASS; + @SerialEntry + public ChatFilterResult hideMimicKill = ChatFilterResult.PASS; + @SerialEntry public boolean hideMana = false; } diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index 583bc166..06133afc 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -2,17 +2,12 @@ package de.hysky.skyblocker.config.categories; import de.hysky.skyblocker.config.ConfigUtils; import de.hysky.skyblocker.config.SkyblockerConfig; +import de.hysky.skyblocker.skyblock.dungeon.DungeonMapConfigScreen; import de.hysky.skyblocker.utils.waypoint.Waypoint.Type; -import dev.isxander.yacl3.api.ButtonOption; -import dev.isxander.yacl3.api.ConfigCategory; -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.OptionDescription; -import dev.isxander.yacl3.api.OptionFlag; -import dev.isxander.yacl3.api.OptionGroup; +import dev.isxander.yacl3.api.*; import dev.isxander.yacl3.api.controller.FloatFieldControllerBuilder; import dev.isxander.yacl3.api.controller.IntegerFieldControllerBuilder; import dev.isxander.yacl3.api.controller.StringControllerBuilder; -import de.hysky.skyblocker.skyblock.dungeon.DungeonMapConfigScreen; import net.minecraft.client.MinecraftClient; import net.minecraft.text.Text; import net.minecraft.util.Formatting; @@ -418,6 +413,27 @@ public class DungeonsCategory { newValue -> config.locations.dungeons.allowDroppingProtectedItems = newValue) .controller(ConfigUtils::createBooleanController) .build()) + //Mimic Messages + .group(OptionGroup.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages")) + .collapsed(true) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.sendMimicMessages")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.sendMimicMessages.@Tooltip"))) + .binding(defaults.locations.dungeons.mimicMessages.sendMimicMessages, + () -> config.locations.dungeons.mimicMessages.sendMimicMessages, + newValue -> config.locations.dungeons.mimicMessages.sendMimicMessages = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.mimicMessage")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.mimicMessage.@Tooltip"))) + .binding(defaults.locations.dungeons.mimicMessages.mimicMessage, + () -> config.locations.dungeons.mimicMessages.mimicMessage, + newValue -> config.locations.dungeons.mimicMessages.mimicMessage = newValue) + .controller(StringControllerBuilder::create) + .build()) + .build()) // Livid Color .group(OptionGroup.createBuilder() diff --git a/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java index 37f24d8c..3fe285de 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java @@ -102,6 +102,14 @@ public class MessageFilterCategory { newValue -> config.messages.hideMana = newValue) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.messages.hideMimicKill")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.messages.hideMimicKill.@Tooltip"))) + .binding(defaults.messages.hideMimicKill, + () -> config.messages.hideMimicKill, + newValue -> config.messages.hideMimicKill = newValue) + .controller(ConfigUtils::createEnumCyclingListController) + .build()) .build(); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index d67d6988..ebec99dc 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -1,28 +1,81 @@ package de.hysky.skyblocker.skyblock.dungeon; + import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; +import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.scheduler.MessageScheduler; import de.hysky.skyblocker.utils.scheduler.Scheduler; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; +import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.Entity; +import net.minecraft.entity.mob.ZombieEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; import net.minecraft.sound.SoundEvents; +import net.minecraft.util.collection.DefaultedList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DungeonScore { - private static final SkyblockerConfig.DungeonScore CONFIG = SkyblockerConfigManager.get().locations.dungeons.dungeonScore; - private static final Pattern DUNGEON_CLEARED_PATTERN = Pattern.compile("Cleared: (?\\d+)% \\((?\\d+)\\)"); + private static final SkyblockerConfig.DungeonScore SCORE_CONFIG = SkyblockerConfigManager.get().locations.dungeons.dungeonScore; + private static final SkyblockerConfig.MimicMessages MIMIC_MESSAGES_CONFIG = SkyblockerConfigManager.get().locations.dungeons.mimicMessages; + private static final Logger LOGGER = LoggerFactory.getLogger("Skyblocker Dungeon Score"); + private static final Pattern CLEARED_PATTERN = Pattern.compile("Cleared: (?\\d+)%.*"); + private static final Pattern SECRETS_PATTERN = Pattern.compile("Secrets Found: (?\\d+\\.?\\d*)%"); + private static final Pattern PUZZLES_PATTERN = Pattern.compile(".+?(?=:): \\[(?.)](?: \\(\\w+\\))?"); + private static final Pattern PUZZLE_COUNT_PATTERN = Pattern.compile("Puzzles: \\((?\\d+)\\)"); + private static final Pattern TIME_PATTERN = Pattern.compile("Time: (?:(?\\d+(?=h))?h? ?(?\\d+(?=m))?m? ?(?\\d+(?=s))s|Soon!)"); + private static final Pattern CRYPTS_PATTERN = Pattern.compile("Crypts: (?\\d+)"); + private static final Pattern COMPLETED_ROOMS_PATTERN = Pattern.compile(" *Completed Rooms: (?\\d+)"); + private static final Pattern DUNGEON_START_PATTERN = Pattern.compile("(?:Auto-closing|Starting) in: \\d:\\d+"); + private static final Pattern FLOOR_PATTERN = Pattern.compile(".*?(?=T)The Catacombs \\((?[EFM]\\D*\\d*)\\)"); + private static final Pattern DEATHS_PATTERN = Pattern.compile("Team Deaths: (?\\d+)"); + private static String currentFloor; private static boolean sent270; private static boolean sent300; + private static boolean isMimicKilled; + private static int puzzleCount; + //Caching the dungeon start state to prevent unnecessary scoreboard pattern matching after dungeon starts + private static boolean isDungeonStarted; + private static boolean isMayorPaul; + private static final HashMap floorRequirements = new HashMap<>(Map.ofEntries( + Map.entry("E", new FloorRequirement(30, 1200)), + Map.entry("F1", new FloorRequirement(30, 600)), + Map.entry("F2", new FloorRequirement(40, 600)), + Map.entry("F3", new FloorRequirement(50, 600)), + Map.entry("F4", new FloorRequirement(60, 720)), + Map.entry("F5", new FloorRequirement(70, 600)), + Map.entry("F6", new FloorRequirement(85, 720)), + Map.entry("F7", new FloorRequirement(100, 840)), + Map.entry("M1", new FloorRequirement(100, 480)), + Map.entry("M2", new FloorRequirement(100, 480)), + Map.entry("M3", new FloorRequirement(100, 480)), + Map.entry("M4", new FloorRequirement(100, 480)), + Map.entry("M5", new FloorRequirement(100, 480)), + Map.entry("M6", new FloorRequirement(100, 600)), + Map.entry("M7", new FloorRequirement(100, 840)) + )); public static void init() { Scheduler.INSTANCE.scheduleCyclic(DungeonScore::tick, 20); ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> reset()); + ServerLivingEntityEvents.AFTER_DEATH.register((entity, source) -> { + if (isEntityMimic(entity)) { + if (MIMIC_MESSAGES_CONFIG.sendMimicMessages) MessageScheduler.INSTANCE.sendMessageAfterCooldown(MIMIC_MESSAGES_CONFIG.mimicMessage); + setMimicKilled(true); + } + }); } public static void tick() { @@ -31,46 +84,211 @@ public class DungeonScore { reset(); return; } + if (!isDungeonStarted) { + if (checkIfDungeonStarted()) onDungeonStart(); + return; + } + int score = calculateScore(); + if (SCORE_CONFIG.enableDungeonScore270 && !sent270 && score >= 270 && score < 300) { + MessageScheduler.INSTANCE.sendMessageAfterCooldown("/pc " + Constants.PREFIX.get().getString() + SCORE_CONFIG.dungeonScore270Message.replaceAll("\\[score]", "270")); + client.player.playSound(SoundEvents.BLOCK_NOTE_BLOCK_PLING.value(), 1f, 0.1f); + sent270 = true; + } + if (SCORE_CONFIG.enableDungeonScore300 && !sent300 && score >= 300) { + MessageScheduler.INSTANCE.sendMessageAfterCooldown("/pc " + Constants.PREFIX.get().getString() + SCORE_CONFIG.dungeonScore300Message.replaceAll("\\[score]", "300")); + client.player.playSound(SoundEvents.BLOCK_NOTE_BLOCK_PLING.value(), 1f, 1f); + sent300 = true; + } + } + + public static boolean isEntityMimic(Entity entity) { + if (!(entity instanceof ZombieEntity zombie)) return false; + if (!zombie.isBaby()) return false; + try { + DefaultedList armor = (DefaultedList) zombie.getArmorItems(); + if (armor.isEmpty()) return false; + NbtCompound helmetNbt = armor.get(3).getNbt(); + if (helmetNbt == null) return false; + return helmetNbt.getCompound("SkullOwner") + .getCompound("Properties") + .getList("textures", NbtElement.COMPOUND_TYPE) + .getCompound(0).getString("Value") + .equals("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTE5YzEyNTQzYmM3NzkyNjA1ZWY2OGUxZjg3NDlhZThmMmEzODFkOTA4NWQ0ZDRiNzgwYmExMjgyZDM1OTdhMCJ9fX0K"); + } catch (NullPointerException e) { + return false; + } catch (ClassCastException f) { + f.printStackTrace(); + return false; + } + } + private static boolean checkIfDungeonStarted() { for (String sidebarLine : Utils.STRING_SCOREBOARD) { - Matcher dungeonClearedMatcher = DUNGEON_CLEARED_PATTERN.matcher(sidebarLine); - if (!dungeonClearedMatcher.matches()) { - continue; - } - int score = Integer.parseInt(dungeonClearedMatcher.group("score")); - if (!DungeonManager.isInBoss()) score += 28; - if (!sent270 && score >= 270 && score < 300) { - if (CONFIG.enableDungeonScore270Message) { - MessageScheduler.INSTANCE.sendMessageAfterCooldown(Constants.PREFIX.get().getString() + CONFIG.dungeonScore270Message.replaceAll("\\[score]", "270")); - } - if (CONFIG.enableDungeonScore270Title) { - client.inGameHud.setDefaultTitleFade(); - client.inGameHud.setTitle(Constants.PREFIX.get().append(CONFIG.dungeonScore270Message.replaceAll("\\[score]", "270"))); - } - if (CONFIG.enableDungeonScore270Sound) { - client.player.playSound(SoundEvents.BLOCK_NOTE_BLOCK_PLING.value(), 100f, 0.1f); - } - sent270 = true; - } - if (!sent300 && score >= 300) { - if (CONFIG.enableDungeonScore300Message) { - MessageScheduler.INSTANCE.sendMessageAfterCooldown(Constants.PREFIX.get().getString() + CONFIG.dungeonScore300Message.replaceAll("\\[score]", "300")); - } - if (CONFIG.enableDungeonScore300Title) { - client.inGameHud.setDefaultTitleFade(); - client.inGameHud.setTitle(Constants.PREFIX.get().append(CONFIG.dungeonScore300Message.replaceAll("\\[score]", "300"))); - } - if (CONFIG.enableDungeonScore300Sound) { - client.player.playSound(SoundEvents.BLOCK_NOTE_BLOCK_PLING.value(), 100f, 0.1f); - } - sent300 = true; - } - break; + Matcher matcher = DUNGEON_START_PATTERN.matcher(sidebarLine); + if (matcher.matches()) return false; } + return true; + } + + private static void onDungeonStart() { + setCurrentFloor(); + isDungeonStarted = true; + puzzleCount = getPuzzleCount(); + isMayorPaul = Utils.getMayor().equals("Paul"); + } + + private static int calculateScore() { + int timeScore = calculateTimeScore(); + int exploreScore = calculateExploreScore(); + int skillScore = calculateSkillScore(); + int paulScore = isMayorPaul ? 10 : 0; + int cryptsScore = Math.min(getCrypts(), 5); + int mimicScore = isMimicKilled ? 2 : 0; + int totalScore = timeScore + exploreScore + skillScore + paulScore + cryptsScore + mimicScore; + //Will be this way until ready for pr, so it's easy to debug. + LOGGER.info("Total Score: {} (Time: {}, Explore: {}, Skill: {}, Paul: {}, Crypts: {}, Mimic: {})", totalScore, timeScore, exploreScore, skillScore, paulScore, cryptsScore, mimicScore); + return totalScore; + } + + private static int calculateExploreScore() { + int completedRoomScore = (int) Math.floor(60.0 * getCompletedRooms() / getTotalRooms()); + int percentageRequirement = floorRequirements.get(currentFloor).percentage; + int secretsScore = (int) Math.floor(40 * Math.min(percentageRequirement, getSecretsPercentage()) / percentageRequirement); + return completedRoomScore + secretsScore; + } + + private static int calculateTimeScore() { + Matcher timeMatcher = PlayerListMgr.regexAt(45, TIME_PATTERN); + if (timeMatcher == null) { + LOGGER.error("Time pattern doesn't match"); + return 0; + } + int score = 100; + int hours = Optional.ofNullable(timeMatcher.group("hours")).map(Integer::parseInt).orElse(0); + int minutes = Optional.ofNullable(timeMatcher.group("minutes")).map(Integer::parseInt).orElse(0); + int seconds = Optional.ofNullable(timeMatcher.group("seconds")).map(Integer::parseInt).orElse(0); + int timeSpent = hours * 3600 + minutes * 60 + seconds; + int timeRequirement = floorRequirements.get(currentFloor).timeLimit; + if (timeSpent < timeRequirement) return score; + + double timePastRequirement = ((double) (timeSpent - timeRequirement) / timeRequirement) * 100; + if (timePastRequirement >= 0 && timePastRequirement < 20) { + score -= (int) timePastRequirement / 2; + } else if (timePastRequirement >= 20 && timePastRequirement < 40) { + score -= (int) (10 + (timePastRequirement - 20) / 4); + } else if (timePastRequirement >= 40 && timePastRequirement < 50) { + score -= (int) (15 + (timePastRequirement - 40) / 5); + } else if (timePastRequirement >= 50 && timePastRequirement < 60) { + score -= (int) (17 + (timePastRequirement - 50) / 6); + } else if (timePastRequirement >= 60) { + score -= (int) (18 + (2.0 / 3.0) + (timePastRequirement - 60) / 7); + } + return score; + } + + private static int calculateSkillScore() { + return 20 + (int) Math.floor(80.0 * getCompletedRooms() / getTotalRooms()) - (2 * getDeathCount()) - (10 * getFailedPuzzles()); } private static void reset() { sent270 = false; sent300 = false; + isDungeonStarted = false; + isMimicKilled = false; + isMayorPaul = false; + puzzleCount = 0; + currentFloor = ""; + } + + public static void setMimicKilled(boolean killed) { + isMimicKilled = killed; + } + + private static int getTotalRooms() { + return (int) Math.round((getCompletedRooms()) / getClearPercentage()); //Clear% rounds to the closest integer so it can be off by 0.5% at most, this should be accurate enough + } + + private static int getCompletedRooms() { + Matcher completedRoomsMatcher = PlayerListMgr.regexAt(43, COMPLETED_ROOMS_PATTERN); + if (completedRoomsMatcher == null) { + LOGGER.error("Completed rooms pattern doesn't match"); + return 0; + } + return Integer.parseInt(completedRoomsMatcher.group("rooms")); + } + + private static double getClearPercentage() { + for (String sidebarLine : Utils.STRING_SCOREBOARD) { + Matcher clearMatcher = CLEARED_PATTERN.matcher(sidebarLine); + if (!clearMatcher.matches()) continue; + return Double.parseDouble(clearMatcher.group("cleared")) / 100; + } + LOGGER.error("Clear pattern doesn't match"); + return 0; + } + + private static int getDeathCount() { + Matcher matcher = PlayerListMgr.regexAt(25, DEATHS_PATTERN); + if (matcher == null) { + LOGGER.error("Death count pattern doesn't match"); + return 0; + } + //TODO: Turn this into a map of players and their deathcounts, get party members' pets, check if they have spirit pet, if they have it reduce their death count by 0.5 + return Integer.parseInt(matcher.group("deaths")); + } + + private static int getPuzzleCount() { + Matcher matcher = PlayerListMgr.regexAt(47, PUZZLE_COUNT_PATTERN); + if (matcher == null) { + LOGGER.error("Puzzle count pattern doesn't match"); + return 0; + } + return Integer.parseInt(matcher.group("count")); + } + + //Might be replaced to look for puzzle fail messages on chat instead of playerlist + private static int getFailedPuzzles() { + int failedPuzzles = 0; + for (int index = 0; index < puzzleCount; index++) { + Matcher puzzleMatcher = PlayerListMgr.regexAt(48 + index, PUZZLES_PATTERN); + if (puzzleMatcher == null) { + LOGGER.error("Puzzle pattern doesn't match"); + return 0; + } + if (puzzleMatcher.group("state").equals("✖")) failedPuzzles++; + } + return failedPuzzles; + } + + private static double getSecretsPercentage() { + Matcher matcher = PlayerListMgr.regexAt(44, SECRETS_PATTERN); + if (matcher == null) { + LOGGER.error("Secrets pattern doesn't match"); + return 0; + } + return Double.parseDouble(matcher.group("secper")); + } + + private static int getCrypts() { + Matcher matcher = PlayerListMgr.regexAt(33, CRYPTS_PATTERN); + if (matcher == null) { + LOGGER.error("Crypts pattern doesn't match"); + return 0; + } + return Integer.parseInt(matcher.group("crypts")); + } + + public static void setCurrentFloor() { + for (String sidebarLine : Utils.STRING_SCOREBOARD) { + Matcher floorMatcher = FLOOR_PATTERN.matcher(sidebarLine); + if (!floorMatcher.matches()) continue; + currentFloor = floorMatcher.group("floor"); + return; + } + LOGGER.error("Floor pattern doesn't match"); + } + + record FloorRequirement(int percentage, int timeLimit) { } } + diff --git a/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java b/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java new file mode 100644 index 00000000..0fce5b2c --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java @@ -0,0 +1,26 @@ +package de.hysky.skyblocker.skyblock.filters; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; +import de.hysky.skyblocker.utils.chat.ChatFilterResult; +import de.hysky.skyblocker.utils.chat.ChatPatternListener; +import net.minecraft.text.Text; + +import java.util.regex.Matcher; + +public class MimicFilter extends ChatPatternListener { + public MimicFilter() { + super("(?:Mimic dead!|Mimic Killed!|\\$SKYTILS-DUNGEON-SCORE-MIMIC\\$|\\Q" + SkyblockerConfigManager.get().locations.dungeons.mimicMessages.mimicMessage + "\\E)$"); + } + + @Override + public ChatFilterResult state() { + return SkyblockerConfigManager.get().messages.hideMimicKill; + } + + @Override + protected boolean onMatch(Text message, Matcher matcher) { + DungeonScore.setMimicKilled(true); + return false; + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java index 45ace085..1fc718be 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Utils.java +++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java @@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.Collections; import java.util.List; @@ -64,6 +65,8 @@ public class Utils { private static boolean sentLocRaw = false; private static boolean canSendLocRaw = false; + private static String mayor = ""; + /** * @implNote The parent text will always be empty, the actual text content is inside the text's siblings. */ @@ -135,7 +138,16 @@ public class Utils { return map; } + /** + * @return the current mayor as cached on skyblock join. + */ + @NotNull + public static String getMayor() { + return mayor; + } + public static void init() { + SkyblockEvents.JOIN.register(Utils::initializeMayorCache); ClientPlayConnectionEvents.JOIN.register(Utils::onClientWorldJoin); ClientReceiveMessageEvents.ALLOW_GAME.register(Utils::onChatMessage); ClientReceiveMessageEvents.GAME_CANCELED.register(Utils::onChatMessage); // Somehow this works even though onChatMessage returns a boolean @@ -381,4 +393,19 @@ public class Utils { locationRaw = ""; map = ""; } + + private static void initializeMayorCache() { + if (!mayor.isEmpty()) return; + try { + JsonObject json = JsonParser.parseString(Http.sendGetRequest("https://api.hypixel.net/v2/resources/skyblock/election")).getAsJsonObject(); + if (json.get("success").getAsBoolean()) { + mayor = json.get("mayor").getAsJsonObject().get("name").getAsString(); + System.out.println(mayor); + } else { + throw new IOException("API call for mayor failed: " + json.get("cause").getAsString()); + } + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } } diff --git a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java index ebdb6f09..97398625 100644 --- a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java +++ b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java @@ -1,7 +1,5 @@ package de.hysky.skyblocker.utils.chat; -import de.hysky.skyblocker.skyblock.filters.*; -import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.skyblock.barn.HungryHiker; import de.hysky.skyblocker.skyblock.barn.TreasureHunter; import de.hysky.skyblocker.skyblock.dungeon.Reparty; @@ -9,6 +7,8 @@ import de.hysky.skyblocker.skyblock.dungeon.puzzle.ThreeWeirdos; import de.hysky.skyblocker.skyblock.dungeon.puzzle.Trivia; import de.hysky.skyblocker.skyblock.dwarven.Fetchur; import de.hysky.skyblocker.skyblock.dwarven.Puzzler; +import de.hysky.skyblocker.skyblock.filters.*; +import de.hysky.skyblocker.utils.Utils; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; @@ -54,7 +54,8 @@ public interface ChatMessageListener { new TeleportPadFilter(), new AutopetFilter(), new ShowOffFilter(), - new ToggleSkyMallFilter() + new ToggleSkyMallFilter(), + new MimicFilter() }; // Register all listeners to EVENT for (ChatMessageListener listener : listeners) { -- cgit From 2b1239950626b4480b0ac7120f4c8429dfaf8b68 Mon Sep 17 00:00:00 2001 From: Emirlol <81419447+Emirlol@users.noreply.github.com> Date: Sun, 7 Jan 2024 02:58:21 +0300 Subject: Improved time score calculation --- .../de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index ebec99dc..6016813c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -35,7 +35,6 @@ public class DungeonScore { private static final Pattern SECRETS_PATTERN = Pattern.compile("Secrets Found: (?\\d+\\.?\\d*)%"); private static final Pattern PUZZLES_PATTERN = Pattern.compile(".+?(?=:): \\[(?.)](?: \\(\\w+\\))?"); private static final Pattern PUZZLE_COUNT_PATTERN = Pattern.compile("Puzzles: \\((?\\d+)\\)"); - private static final Pattern TIME_PATTERN = Pattern.compile("Time: (?:(?\\d+(?=h))?h? ?(?\\d+(?=m))?m? ?(?\\d+(?=s))s|Soon!)"); private static final Pattern CRYPTS_PATTERN = Pattern.compile("Crypts: (?\\d+)"); private static final Pattern COMPLETED_ROOMS_PATTERN = Pattern.compile(" *Completed Rooms: (?\\d+)"); private static final Pattern DUNGEON_START_PATTERN = Pattern.compile("(?:Auto-closing|Starting) in: \\d:\\d+"); @@ -49,6 +48,7 @@ public class DungeonScore { //Caching the dungeon start state to prevent unnecessary scoreboard pattern matching after dungeon starts private static boolean isDungeonStarted; private static boolean isMayorPaul; + private static long startingTime; private static final HashMap floorRequirements = new HashMap<>(Map.ofEntries( Map.entry("E", new FloorRequirement(30, 1200)), Map.entry("F1", new FloorRequirement(30, 600)), @@ -135,6 +135,7 @@ public class DungeonScore { isDungeonStarted = true; puzzleCount = getPuzzleCount(); isMayorPaul = Utils.getMayor().equals("Paul"); + startingTime = System.currentTimeMillis(); } private static int calculateScore() { @@ -158,16 +159,8 @@ public class DungeonScore { } private static int calculateTimeScore() { - Matcher timeMatcher = PlayerListMgr.regexAt(45, TIME_PATTERN); - if (timeMatcher == null) { - LOGGER.error("Time pattern doesn't match"); - return 0; - } int score = 100; - int hours = Optional.ofNullable(timeMatcher.group("hours")).map(Integer::parseInt).orElse(0); - int minutes = Optional.ofNullable(timeMatcher.group("minutes")).map(Integer::parseInt).orElse(0); - int seconds = Optional.ofNullable(timeMatcher.group("seconds")).map(Integer::parseInt).orElse(0); - int timeSpent = hours * 3600 + minutes * 60 + seconds; + int timeSpent = (int) (System.currentTimeMillis() - startingTime) / 1000; int timeRequirement = floorRequirements.get(currentFloor).timeLimit; if (timeSpent < timeRequirement) return score; -- cgit From 6a350f931609432bd93362b2dbdc26e23450e2b8 Mon Sep 17 00:00:00 2001 From: Emirlol <81419447+Emirlol@users.noreply.github.com> Date: Sun, 14 Jan 2024 18:21:20 +0300 Subject: Fixed most things and cleaned up code --- .../mixin/ClientPlayNetworkHandlerMixin.java | 19 +- .../skyblocker/skyblock/dungeon/DungeonScore.java | 596 ++++++++++++--------- src/main/java/de/hysky/skyblocker/utils/Utils.java | 1 - 3 files changed, 353 insertions(+), 263 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java index 4015dfa5..b3fc871b 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java @@ -1,19 +1,25 @@ package de.hysky.skyblocker.mixin; import com.llamalad7.mixinextras.injector.WrapWithCondition; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; import de.hysky.skyblocker.skyblock.FishingHelper; +import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; import de.hysky.skyblocker.skyblock.waypoint.MythologicalRitual; import de.hysky.skyblocker.utils.Utils; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityStatuses; import net.minecraft.entity.ItemEntity; import net.minecraft.entity.LivingEntity; +import net.minecraft.network.packet.s2c.play.EntityStatusS2CPacket; import net.minecraft.network.packet.s2c.play.ParticleS2CPacket; import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket; import net.minecraft.util.Identifier; - +import net.minecraft.world.World; import org.slf4j.Logger; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -49,12 +55,12 @@ public abstract class ClientPlayNetworkHandlerMixin { private boolean skyblocker$cancelTeamWarning(Logger instance, String format, Object... arg) { return !Utils.isOnHypixel(); } - + @WrapWithCondition(method = { "onScoreboardScoreUpdate", "onScoreboardScoreReset" }, at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false)) private boolean skyblocker$cancelUnknownScoreboardObjectiveWarnings(Logger instance, String message, Object objectiveName) { return !Utils.isOnHypixel(); } - + @WrapWithCondition(method = "warnOnUnknownPayload", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false)) private boolean skyblocker$dropBadlionPacketWarnings(Logger instance, String message, Object identifier) { return !(Utils.isOnHypixel() && ((Identifier) identifier).getNamespace().equals("badlion")); @@ -64,4 +70,11 @@ public abstract class ClientPlayNetworkHandlerMixin { private void skyblocker$onParticle(ParticleS2CPacket packet, CallbackInfo ci) { MythologicalRitual.onParticle(packet); } + + @WrapOperation(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;")) + private Entity skyblocker$onEntityDeath(EntityStatusS2CPacket packet, World world, Operation original) { + Entity entity = original.call(packet, world); + if (packet.getStatus() == EntityStatuses.PLAY_DEATH_SOUND_OR_ADD_PROJECTILE_HIT_PARTICLES) DungeonScore.handleEntityDeath(entity); + return entity; + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index 6016813c..0334290d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -1,21 +1,26 @@ package de.hysky.skyblocker.skyblock.dungeon; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.events.SkyblockEvents; +import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; +import de.hysky.skyblocker.utils.ApiUtils; import de.hysky.skyblocker.utils.Constants; +import de.hysky.skyblocker.utils.Http; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.scheduler.MessageScheduler; import de.hysky.skyblocker.utils.scheduler.Scheduler; +import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; -import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; import net.minecraft.client.MinecraftClient; import net.minecraft.entity.Entity; import net.minecraft.entity.mob.ZombieEntity; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; import net.minecraft.sound.SoundEvents; import net.minecraft.util.collection.DefaultedList; import org.slf4j.Logger; @@ -23,265 +28,338 @@ import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; -import java.util.Optional; +import java.util.concurrent.CompletableFuture; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.StreamSupport; public class DungeonScore { - private static final SkyblockerConfig.DungeonScore SCORE_CONFIG = SkyblockerConfigManager.get().locations.dungeons.dungeonScore; - private static final SkyblockerConfig.MimicMessages MIMIC_MESSAGES_CONFIG = SkyblockerConfigManager.get().locations.dungeons.mimicMessages; - private static final Logger LOGGER = LoggerFactory.getLogger("Skyblocker Dungeon Score"); - private static final Pattern CLEARED_PATTERN = Pattern.compile("Cleared: (?\\d+)%.*"); - private static final Pattern SECRETS_PATTERN = Pattern.compile("Secrets Found: (?\\d+\\.?\\d*)%"); - private static final Pattern PUZZLES_PATTERN = Pattern.compile(".+?(?=:): \\[(?.)](?: \\(\\w+\\))?"); - private static final Pattern PUZZLE_COUNT_PATTERN = Pattern.compile("Puzzles: \\((?\\d+)\\)"); - private static final Pattern CRYPTS_PATTERN = Pattern.compile("Crypts: (?\\d+)"); - private static final Pattern COMPLETED_ROOMS_PATTERN = Pattern.compile(" *Completed Rooms: (?\\d+)"); - private static final Pattern DUNGEON_START_PATTERN = Pattern.compile("(?:Auto-closing|Starting) in: \\d:\\d+"); - private static final Pattern FLOOR_PATTERN = Pattern.compile(".*?(?=T)The Catacombs \\((?[EFM]\\D*\\d*)\\)"); - private static final Pattern DEATHS_PATTERN = Pattern.compile("Team Deaths: (?\\d+)"); - private static String currentFloor; - private static boolean sent270; - private static boolean sent300; - private static boolean isMimicKilled; - private static int puzzleCount; - //Caching the dungeon start state to prevent unnecessary scoreboard pattern matching after dungeon starts - private static boolean isDungeonStarted; - private static boolean isMayorPaul; - private static long startingTime; - private static final HashMap floorRequirements = new HashMap<>(Map.ofEntries( - Map.entry("E", new FloorRequirement(30, 1200)), - Map.entry("F1", new FloorRequirement(30, 600)), - Map.entry("F2", new FloorRequirement(40, 600)), - Map.entry("F3", new FloorRequirement(50, 600)), - Map.entry("F4", new FloorRequirement(60, 720)), - Map.entry("F5", new FloorRequirement(70, 600)), - Map.entry("F6", new FloorRequirement(85, 720)), - Map.entry("F7", new FloorRequirement(100, 840)), - Map.entry("M1", new FloorRequirement(100, 480)), - Map.entry("M2", new FloorRequirement(100, 480)), - Map.entry("M3", new FloorRequirement(100, 480)), - Map.entry("M4", new FloorRequirement(100, 480)), - Map.entry("M5", new FloorRequirement(100, 480)), - Map.entry("M6", new FloorRequirement(100, 600)), - Map.entry("M7", new FloorRequirement(100, 840)) - )); - - public static void init() { - Scheduler.INSTANCE.scheduleCyclic(DungeonScore::tick, 20); - ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> reset()); - ServerLivingEntityEvents.AFTER_DEATH.register((entity, source) -> { - if (isEntityMimic(entity)) { - if (MIMIC_MESSAGES_CONFIG.sendMimicMessages) MessageScheduler.INSTANCE.sendMessageAfterCooldown(MIMIC_MESSAGES_CONFIG.mimicMessage); - setMimicKilled(true); - } - }); - } - - public static void tick() { - MinecraftClient client = MinecraftClient.getInstance(); - if (!Utils.isInDungeons() || client.player == null) { - reset(); - return; - } - if (!isDungeonStarted) { - if (checkIfDungeonStarted()) onDungeonStart(); - return; - } - int score = calculateScore(); - if (SCORE_CONFIG.enableDungeonScore270 && !sent270 && score >= 270 && score < 300) { - MessageScheduler.INSTANCE.sendMessageAfterCooldown("/pc " + Constants.PREFIX.get().getString() + SCORE_CONFIG.dungeonScore270Message.replaceAll("\\[score]", "270")); - client.player.playSound(SoundEvents.BLOCK_NOTE_BLOCK_PLING.value(), 1f, 0.1f); - sent270 = true; - } - if (SCORE_CONFIG.enableDungeonScore300 && !sent300 && score >= 300) { - MessageScheduler.INSTANCE.sendMessageAfterCooldown("/pc " + Constants.PREFIX.get().getString() + SCORE_CONFIG.dungeonScore300Message.replaceAll("\\[score]", "300")); - client.player.playSound(SoundEvents.BLOCK_NOTE_BLOCK_PLING.value(), 1f, 1f); - sent300 = true; - } - } - - public static boolean isEntityMimic(Entity entity) { - if (!(entity instanceof ZombieEntity zombie)) return false; - if (!zombie.isBaby()) return false; - try { - DefaultedList armor = (DefaultedList) zombie.getArmorItems(); - if (armor.isEmpty()) return false; - NbtCompound helmetNbt = armor.get(3).getNbt(); - if (helmetNbt == null) return false; - return helmetNbt.getCompound("SkullOwner") - .getCompound("Properties") - .getList("textures", NbtElement.COMPOUND_TYPE) - .getCompound(0).getString("Value") - .equals("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTE5YzEyNTQzYmM3NzkyNjA1ZWY2OGUxZjg3NDlhZThmMmEzODFkOTA4NWQ0ZDRiNzgwYmExMjgyZDM1OTdhMCJ9fX0K"); - } catch (NullPointerException e) { - return false; - } catch (ClassCastException f) { - f.printStackTrace(); - return false; - } - } - - private static boolean checkIfDungeonStarted() { - for (String sidebarLine : Utils.STRING_SCOREBOARD) { - Matcher matcher = DUNGEON_START_PATTERN.matcher(sidebarLine); - if (matcher.matches()) return false; - } - return true; - } - - private static void onDungeonStart() { - setCurrentFloor(); - isDungeonStarted = true; - puzzleCount = getPuzzleCount(); - isMayorPaul = Utils.getMayor().equals("Paul"); - startingTime = System.currentTimeMillis(); - } - - private static int calculateScore() { - int timeScore = calculateTimeScore(); - int exploreScore = calculateExploreScore(); - int skillScore = calculateSkillScore(); - int paulScore = isMayorPaul ? 10 : 0; - int cryptsScore = Math.min(getCrypts(), 5); - int mimicScore = isMimicKilled ? 2 : 0; - int totalScore = timeScore + exploreScore + skillScore + paulScore + cryptsScore + mimicScore; - //Will be this way until ready for pr, so it's easy to debug. - LOGGER.info("Total Score: {} (Time: {}, Explore: {}, Skill: {}, Paul: {}, Crypts: {}, Mimic: {})", totalScore, timeScore, exploreScore, skillScore, paulScore, cryptsScore, mimicScore); - return totalScore; - } - - private static int calculateExploreScore() { - int completedRoomScore = (int) Math.floor(60.0 * getCompletedRooms() / getTotalRooms()); - int percentageRequirement = floorRequirements.get(currentFloor).percentage; - int secretsScore = (int) Math.floor(40 * Math.min(percentageRequirement, getSecretsPercentage()) / percentageRequirement); - return completedRoomScore + secretsScore; - } - - private static int calculateTimeScore() { - int score = 100; - int timeSpent = (int) (System.currentTimeMillis() - startingTime) / 1000; - int timeRequirement = floorRequirements.get(currentFloor).timeLimit; - if (timeSpent < timeRequirement) return score; - - double timePastRequirement = ((double) (timeSpent - timeRequirement) / timeRequirement) * 100; - if (timePastRequirement >= 0 && timePastRequirement < 20) { - score -= (int) timePastRequirement / 2; - } else if (timePastRequirement >= 20 && timePastRequirement < 40) { - score -= (int) (10 + (timePastRequirement - 20) / 4); - } else if (timePastRequirement >= 40 && timePastRequirement < 50) { - score -= (int) (15 + (timePastRequirement - 40) / 5); - } else if (timePastRequirement >= 50 && timePastRequirement < 60) { - score -= (int) (17 + (timePastRequirement - 50) / 6); - } else if (timePastRequirement >= 60) { - score -= (int) (18 + (2.0 / 3.0) + (timePastRequirement - 60) / 7); - } - return score; - } - - private static int calculateSkillScore() { - return 20 + (int) Math.floor(80.0 * getCompletedRooms() / getTotalRooms()) - (2 * getDeathCount()) - (10 * getFailedPuzzles()); - } - - private static void reset() { - sent270 = false; - sent300 = false; - isDungeonStarted = false; - isMimicKilled = false; - isMayorPaul = false; - puzzleCount = 0; - currentFloor = ""; - } - - public static void setMimicKilled(boolean killed) { - isMimicKilled = killed; - } - - private static int getTotalRooms() { - return (int) Math.round((getCompletedRooms()) / getClearPercentage()); //Clear% rounds to the closest integer so it can be off by 0.5% at most, this should be accurate enough - } - - private static int getCompletedRooms() { - Matcher completedRoomsMatcher = PlayerListMgr.regexAt(43, COMPLETED_ROOMS_PATTERN); - if (completedRoomsMatcher == null) { - LOGGER.error("Completed rooms pattern doesn't match"); - return 0; - } - return Integer.parseInt(completedRoomsMatcher.group("rooms")); - } - - private static double getClearPercentage() { - for (String sidebarLine : Utils.STRING_SCOREBOARD) { - Matcher clearMatcher = CLEARED_PATTERN.matcher(sidebarLine); - if (!clearMatcher.matches()) continue; - return Double.parseDouble(clearMatcher.group("cleared")) / 100; - } - LOGGER.error("Clear pattern doesn't match"); - return 0; - } - - private static int getDeathCount() { - Matcher matcher = PlayerListMgr.regexAt(25, DEATHS_PATTERN); - if (matcher == null) { - LOGGER.error("Death count pattern doesn't match"); - return 0; - } - //TODO: Turn this into a map of players and their deathcounts, get party members' pets, check if they have spirit pet, if they have it reduce their death count by 0.5 - return Integer.parseInt(matcher.group("deaths")); - } - - private static int getPuzzleCount() { - Matcher matcher = PlayerListMgr.regexAt(47, PUZZLE_COUNT_PATTERN); - if (matcher == null) { - LOGGER.error("Puzzle count pattern doesn't match"); - return 0; - } - return Integer.parseInt(matcher.group("count")); - } - - //Might be replaced to look for puzzle fail messages on chat instead of playerlist - private static int getFailedPuzzles() { - int failedPuzzles = 0; - for (int index = 0; index < puzzleCount; index++) { - Matcher puzzleMatcher = PlayerListMgr.regexAt(48 + index, PUZZLES_PATTERN); - if (puzzleMatcher == null) { - LOGGER.error("Puzzle pattern doesn't match"); - return 0; - } - if (puzzleMatcher.group("state").equals("✖")) failedPuzzles++; - } - return failedPuzzles; - } - - private static double getSecretsPercentage() { - Matcher matcher = PlayerListMgr.regexAt(44, SECRETS_PATTERN); - if (matcher == null) { - LOGGER.error("Secrets pattern doesn't match"); - return 0; - } - return Double.parseDouble(matcher.group("secper")); - } - - private static int getCrypts() { - Matcher matcher = PlayerListMgr.regexAt(33, CRYPTS_PATTERN); - if (matcher == null) { - LOGGER.error("Crypts pattern doesn't match"); - return 0; - } - return Integer.parseInt(matcher.group("crypts")); - } - - public static void setCurrentFloor() { - for (String sidebarLine : Utils.STRING_SCOREBOARD) { - Matcher floorMatcher = FLOOR_PATTERN.matcher(sidebarLine); - if (!floorMatcher.matches()) continue; - currentFloor = floorMatcher.group("floor"); - return; - } - LOGGER.error("Floor pattern doesn't match"); - } - - record FloorRequirement(int percentage, int timeLimit) { - } + private static final SkyblockerConfig.DungeonScore SCORE_CONFIG = SkyblockerConfigManager.get().locations.dungeons.dungeonScore; + private static final SkyblockerConfig.MimicMessages MIMIC_MESSAGES_CONFIG = SkyblockerConfigManager.get().locations.dungeons.mimicMessages; + private static final Logger LOGGER = LoggerFactory.getLogger("Skyblocker Dungeon Score"); + //Scoreboard patterns + private static final Pattern CLEARED_PATTERN = Pattern.compile("Cleared: (?\\d+)%.*"); + private static final Pattern DUNGEON_START_PATTERN = Pattern.compile("(?:Auto-closing|Starting) in: \\d:\\d+"); + private static final Pattern FLOOR_PATTERN = Pattern.compile(".*?(?=T)The Catacombs \\((?[EFM]\\D*\\d*)\\)"); + //Playerlist patterns + private static final Pattern SECRETS_PATTERN = Pattern.compile("Secrets Found: (?\\d+\\.?\\d*)%"); + private static final Pattern PUZZLES_PATTERN = Pattern.compile(".+?(?=:): \\[(?.)](?: \\(\\w+\\))?"); + private static final Pattern PUZZLE_COUNT_PATTERN = Pattern.compile("Puzzles: \\((?\\d+)\\)"); + private static final Pattern CRYPTS_PATTERN = Pattern.compile("Crypts: (?\\d+)"); + private static final Pattern COMPLETED_ROOMS_PATTERN = Pattern.compile(" *Completed Rooms: (?\\d+)"); + //Chat patterns + private static final Pattern DEATHS_PATTERN = Pattern.compile(".*?\u2620 (?\\S+) .*"); + //Other patterns + private static final Pattern MIMIC_FLOOR_FILTER_PATTERN = Pattern.compile("[EFM][12345]?"); + + private static String currentFloor; + private static boolean sent270; + private static boolean sent300; + private static boolean isMimicKilled; + private static int puzzleCount; + private static boolean isDungeonStarted; + private static boolean isMayorPaul; + private static long startingTime; + private static int deathCount; + private static boolean firstDeathHasSpiritPet; + private static boolean bloodRoomCompleted; + private static final Map SpiritPetCache = new HashMap<>(); + + public static void init() { + Scheduler.INSTANCE.scheduleCyclic(DungeonScore::tick, 20); + SkyblockEvents.LEAVE.register(SpiritPetCache::clear); + ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> reset()); + ClientReceiveMessageEvents.GAME.register((message, overlay) -> { + String str = message.getString(); + checkMessageForDeaths(str); + checkMessageForWatcher(str); + }); + } + + public static void tick() { + MinecraftClient client = MinecraftClient.getInstance(); + if (!Utils.isInDungeons() || client.player == null) { + reset(); + return; + } + if (!isDungeonStarted) { + if (checkIfDungeonStarted()) onDungeonStart(); + return; + } + int score = calculateScore(); + if (!sent270 && score >= 270 && score < 300) { + if (SCORE_CONFIG.enableDungeonScore270Message) { + MessageScheduler.INSTANCE.sendMessageAfterCooldown(SCORE_CONFIG.dungeonScore270Message.replaceAll("\\[score]", "270")); + } + if (SCORE_CONFIG.enableDungeonScore270Title) { + client.inGameHud.setDefaultTitleFade(); + client.inGameHud.setTitle(Constants.PREFIX.get().append(SCORE_CONFIG.dungeonScore270Message.replaceAll("\\[score]", "270"))); + } + if (SCORE_CONFIG.enableDungeonScore270Sound) { + client.player.playSound(SoundEvents.BLOCK_NOTE_BLOCK_PLING.value(), 100f, 0.1f); + } + sent270 = true; + } + if (!sent300 && score >= 300) { + if (SCORE_CONFIG.enableDungeonScore300Message) { + MessageScheduler.INSTANCE.sendMessageAfterCooldown(SCORE_CONFIG.dungeonScore300Message.replaceAll("\\[score]", "300")); + } + if (SCORE_CONFIG.enableDungeonScore300Title) { + client.inGameHud.setDefaultTitleFade(); + client.inGameHud.setTitle(Constants.PREFIX.get().append(SCORE_CONFIG.dungeonScore300Message.replaceAll("\\[score]", "300"))); + } + if (SCORE_CONFIG.enableDungeonScore300Sound) { + client.player.playSound(SoundEvents.BLOCK_NOTE_BLOCK_PLING.value(), 100f, 0.1f); + } + sent300 = true; + } + } + + private static void reset() { + sent270 = false; + sent300 = false; + isDungeonStarted = false; + isMimicKilled = false; + isMayorPaul = false; + firstDeathHasSpiritPet = false; + deathCount = 0; + currentFloor = ""; + } + + private static void onDungeonStart() { + setCurrentFloor(); + isDungeonStarted = true; + puzzleCount = getPuzzleCount(); + isMayorPaul = Utils.getMayor().equals("Paul"); + startingTime = System.currentTimeMillis(); + } + + private static int calculateScore() { + int timeScore = calculateTimeScore(); + int exploreScore = calculateExploreScore(); + int skillScore = calculateSkillScore(); + int bonusScore = calculateBonusScore(); + int totalScore = timeScore + exploreScore + skillScore + bonusScore; + if (currentFloor.equals("E")) totalScore = (int) (totalScore * 0.7); + //Will be this way until ready for pr, so it's easy to debug. + LOGGER.info("Total Score: {} (Time: {}, Explore: {}, Skill: {}, Bonus: {})", totalScore, timeScore, exploreScore, skillScore, bonusScore); + return totalScore; + } + + private static int calculateSkillScore() { + int extraCompletedRooms = 0; //This is needed for calculating the score before going in, so we have the result sooner + if (!DungeonManager.isInBoss()) extraCompletedRooms = bloodRoomCompleted ? 1 : 2; + return 20 + (int) Math.floor(80.0 * (getCompletedRooms() + extraCompletedRooms) / getTotalRooms()) - getPuzzlePenalty() - getDeathScorePenalty(); + } + + private static int calculateExploreScore() { + int extraCompletedRooms = 0; + if (!DungeonManager.isInBoss()) extraCompletedRooms = bloodRoomCompleted ? 1 : 2; + int completedRoomScore = (int) Math.floor(60.0 * (getCompletedRooms() + extraCompletedRooms) / getTotalRooms()); + int percentageRequirement = FloorRequirement.valueOf(currentFloor).percentage; + int secretsScore = (int) Math.floor(40 * Math.min(percentageRequirement, getSecretsPercentage()) / percentageRequirement); + return completedRoomScore + secretsScore; + } + + private static int calculateTimeScore() { + int score = 100; + int timeSpent = (int) (System.currentTimeMillis() - startingTime) / 1000; + int timeRequirement = FloorRequirement.valueOf(currentFloor).timeLimit; + if (timeSpent < timeRequirement) return score; + + double timePastRequirement = ((double) (timeSpent - timeRequirement) / timeRequirement) * 100; + if (timePastRequirement >= 0 && timePastRequirement < 20) { + score -= (int) timePastRequirement / 2; + } else if (timePastRequirement >= 20 && timePastRequirement < 40) { + score -= (int) (10 + (timePastRequirement - 20) / 4); + } else if (timePastRequirement >= 40 && timePastRequirement < 50) { + score -= (int) (15 + (timePastRequirement - 40) / 5); + } else if (timePastRequirement >= 50 && timePastRequirement < 60) { + score -= (int) (17 + (timePastRequirement - 50) / 6); + } else if (timePastRequirement >= 60) { + score -= (int) (18 + (2.0 / 3.0) + (timePastRequirement - 60) / 7); + } + return score; + } + + private static int calculateBonusScore() { + int paulScore = isMayorPaul ? 10 : 0; + int cryptsScore = Math.min(getCrypts(), 5); + int mimicScore = isMimicKilled ? 2 : 0; + if (getSecretsPercentage() >= 100 && !MIMIC_FLOOR_FILTER_PATTERN.matcher(currentFloor).matches()) mimicScore = 2; //If mimic kill is not announced but all secrets are found, mimic must've been killed + return paulScore + cryptsScore + mimicScore; + } + + private static boolean checkIfDungeonStarted() { + return Utils.STRING_SCOREBOARD.stream().anyMatch(s -> DUNGEON_START_PATTERN.matcher(s).matches()); + } + + public static boolean isEntityMimic(Entity entity) { + if (!Utils.isInDungeons()) return false; + if (MIMIC_FLOOR_FILTER_PATTERN.matcher(currentFloor).matches()) return false; + if (entity == null) return false; + if (!(entity instanceof ZombieEntity zombie)) return false; + if (!zombie.isBaby()) return false; + try { + DefaultedList armor = (DefaultedList) zombie.getArmorItems(); + return armor.stream().allMatch(ItemStack::isEmpty); + } catch (NullPointerException e) { + return false; + } catch (ClassCastException f) { + f.printStackTrace(); + return false; + } + } + + public static void handleEntityDeath(Entity entity) { + if (isMimicKilled) return; + if (!isEntityMimic(entity)) return; + isMimicKilled = true; + } + + public static void setMimicKilled(boolean state) { + isMimicKilled = state; + } + + private static int getTotalRooms() { + int completedRooms = getCompletedRooms(); + return (int) Math.round(completedRooms / getClearPercentage()); + } + + private static int getCompletedRooms() { + Matcher matcher = PlayerListMgr.regexAt(43, COMPLETED_ROOMS_PATTERN); + return matcher != null ? Integer.parseInt(matcher.group("rooms")) : 0; + } + + private static double getClearPercentage() { + for (String sidebarLine : Utils.STRING_SCOREBOARD) { + Matcher clearMatcher = CLEARED_PATTERN.matcher(sidebarLine); + if (!clearMatcher.matches()) continue; + return Double.parseDouble(clearMatcher.group("cleared")) / 100.0; + } + LOGGER.error("Clear pattern doesn't match"); + return 0; + } + + private static int getDeathScorePenalty() { + return deathCount * 2 - (firstDeathHasSpiritPet ? 1 : 0); + } + + private static int getPuzzleCount() { + Matcher matcher = PlayerListMgr.regexAt(47, PUZZLE_COUNT_PATTERN); + return matcher != null ? Integer.parseInt(matcher.group("count")) : 0; + } + + //Possible states: ✖, ✦, ✔ + private static int getPuzzlePenalty() { + int incompletePuzzles = 0; + for (int index = 0; index < puzzleCount; index++) { + Matcher puzzleMatcher = PlayerListMgr.regexAt(48 + index, PUZZLES_PATTERN); + if (puzzleMatcher == null) break; + if (puzzleMatcher.group("state").matches("[✖✦]")) incompletePuzzles++; + } + return incompletePuzzles * 10; + } + + private static double getSecretsPercentage() { + Matcher matcher = PlayerListMgr.regexAt(44, SECRETS_PATTERN); + return matcher != null ? Double.parseDouble(matcher.group("secper")) : 0; + } + + private static int getCrypts() { + Matcher matcher = PlayerListMgr.regexAt(33, CRYPTS_PATTERN); + if (matcher == null) matcher = PlayerListMgr.regexAt(32, CRYPTS_PATTERN); //If class milestone 9 is reached, crypts goes up by 1 + return matcher != null ? Integer.parseInt(matcher.group("crypts")) : 0; + } + + public static boolean hasSpiritPet(String name) { + return SpiritPetCache.computeIfAbsent(name, k -> { + String playeruuid = ApiUtils.name2Uuid(name); + try (Http.ApiResponse response = Http.sendHypixelRequest("skyblock/profiles", "?uuid=" + playeruuid)) { + if (!response.ok()) throw new IllegalStateException("Failed to get profile uuid for player " + name + "! Response: " + response.content()); + JsonObject responseJson = JsonParser.parseString(response.content()).getAsJsonObject(); + + JsonObject player = StreamSupport.stream(responseJson.getAsJsonArray("profiles").spliterator(), false) + .map(JsonElement::getAsJsonObject) + .filter(profile -> profile.getAsJsonPrimitive("selected").getAsBoolean()) + .findFirst() + .orElseThrow(() -> new IllegalStateException("No selected profile found!?")) + .getAsJsonObject("members").entrySet().stream() + .filter(entry -> entry.getKey().equals(playeruuid)) + .map(Map.Entry::getValue) + .map(JsonElement::getAsJsonObject) + .findFirst() + .orElseThrow(() -> new IllegalStateException("Player somehow not found inside their own profile!")); + + for (JsonElement element : player.getAsJsonObject("pets_data").getAsJsonArray("pets")) { + if (!element.getAsJsonObject().get("type").getAsString().equals("SPIRIT")) continue; + if (!element.getAsJsonObject().get("tier").getAsString().equals("LEGENDARY")) continue; + + return true; + } + } catch (Exception e) { + e.printStackTrace(); + LOGGER.error("[Skyblocker] Spirit pet lookup by name failed! Name: {} - Cause: {}", name, e.getMessage()); + } + return false; + }); + } + + private static void checkMessageForDeaths(String message) { + if (!Utils.isInDungeons()) return; + if (!message.startsWith("\u2620", 1)) return; + Matcher matcher = DEATHS_PATTERN.matcher(message); + if (!matcher.matches()) return; + deathCount++; + if (deathCount > 1) return; + final String whoDied = matcher.group("whodied").transform(s -> { + if (s.equals("You")) return MinecraftClient.getInstance().player.getName().getString(); //This will be wrong if the dead player is called 'You' but that's unlikely + else return s; + }); + CompletableFuture.supplyAsync(() -> hasSpiritPet(whoDied)) + .thenAccept(hasSpiritPet -> { + firstDeathHasSpiritPet = hasSpiritPet; + }); + } + + private static void checkMessageForWatcher(String message) { + if (message.equals("[BOSS] The Watcher: You have proven yourself. You may pass.")) bloodRoomCompleted = true; + } + + public static void setCurrentFloor() { + for (String sidebarLine : Utils.STRING_SCOREBOARD) { + Matcher floorMatcher = FLOOR_PATTERN.matcher(sidebarLine); + if (!floorMatcher.matches()) continue; + currentFloor = floorMatcher.group("floor"); + return; + } + LOGGER.error("Floor pattern doesn't match"); + } + + enum FloorRequirement { + E(30, 1200), + F1(30, 600), + F2(40, 600), + F3(50, 600), + F4(60, 720), + F5(70, 600), + F6(85, 720), + F7(100, 840), + M1(100, 480), + M2(100, 480), + M3(100, 480), + M4(100, 480), + M5(100, 480), + M6(100, 600), + M7(100, 840); + + private final int percentage; + private final int timeLimit; + + FloorRequirement(int percentage, int timeLimit) { + this.percentage = percentage; + this.timeLimit = timeLimit; + } + } } diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java index 1fc718be..3336a0a7 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Utils.java +++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java @@ -400,7 +400,6 @@ public class Utils { JsonObject json = JsonParser.parseString(Http.sendGetRequest("https://api.hypixel.net/v2/resources/skyblock/election")).getAsJsonObject(); if (json.get("success").getAsBoolean()) { mayor = json.get("mayor").getAsJsonObject().get("name").getAsString(); - System.out.println(mayor); } else { throw new IOException("API call for mayor failed: " + json.get("cause").getAsString()); } -- cgit From cbdaa7a2b69ed2b17e36548b707400f416154c4f Mon Sep 17 00:00:00 2001 From: Emirlol <81419447+Emirlol@users.noreply.github.com> Date: Mon, 15 Jan 2024 19:05:55 +0300 Subject: Added dungeon score to the hud and cleaned up code --- .../java/de/hysky/skyblocker/SkyblockerMod.java | 1 + .../skyblocker/skyblock/dungeon/DungeonScore.java | 73 ++++++++++++---------- .../skyblock/dungeon/DungeonScoreHUD.java | 38 +++++++++++ .../skyblocker/skyblock/filters/MimicFilter.java | 6 +- 4 files changed, 84 insertions(+), 34 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 83f41c0b..4a2ff497 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -110,6 +110,7 @@ public class SkyblockerMod implements ClientModInitializer { Waterboard.init(); DungeonScore.init(); PartyFinderScreen.initClass(); + DungeonScoreHUD.init(); ChestValue.init(); FireFreezeStaffTimer.init(); GuardianHealth.init(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index 0334290d..0a9aec50 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -56,13 +56,14 @@ public class DungeonScore { private static boolean sent270; private static boolean sent300; private static boolean isMimicKilled; - private static int puzzleCount; - private static boolean isDungeonStarted; + private static boolean dungeonStarted; private static boolean isMayorPaul; - private static long startingTime; - private static int deathCount; private static boolean firstDeathHasSpiritPet; private static boolean bloodRoomCompleted; + private static long startingTime; + private static int puzzleCount; + private static int deathCount; + private static int score; private static final Map SpiritPetCache = new HashMap<>(); public static void init() { @@ -70,6 +71,7 @@ public class DungeonScore { SkyblockEvents.LEAVE.register(SpiritPetCache::clear); ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> reset()); ClientReceiveMessageEvents.GAME.register((message, overlay) -> { + if (!Utils.isInDungeons() || !dungeonStarted) return; String str = message.getString(); checkMessageForDeaths(str); checkMessageForWatcher(str); @@ -82,11 +84,11 @@ public class DungeonScore { reset(); return; } - if (!isDungeonStarted) { + if (!dungeonStarted) { if (checkIfDungeonStarted()) onDungeonStart(); return; } - int score = calculateScore(); + score = calculateScore(); if (!sent270 && score >= 270 && score < 300) { if (SCORE_CONFIG.enableDungeonScore270Message) { MessageScheduler.INSTANCE.sendMessageAfterCooldown(SCORE_CONFIG.dungeonScore270Message.replaceAll("\\[score]", "270")); @@ -116,19 +118,23 @@ public class DungeonScore { } private static void reset() { + currentFloor = ""; sent270 = false; sent300 = false; - isDungeonStarted = false; isMimicKilled = false; + dungeonStarted = false; isMayorPaul = false; firstDeathHasSpiritPet = false; + bloodRoomCompleted = false; + startingTime = 0L; + puzzleCount = 0; deathCount = 0; - currentFloor = ""; + score = 0; } private static void onDungeonStart() { setCurrentFloor(); - isDungeonStarted = true; + dungeonStarted = true; puzzleCount = getPuzzleCount(); isMayorPaul = Utils.getMayor().equals("Paul"); startingTime = System.currentTimeMillis(); @@ -147,15 +153,11 @@ public class DungeonScore { } private static int calculateSkillScore() { - int extraCompletedRooms = 0; //This is needed for calculating the score before going in, so we have the result sooner - if (!DungeonManager.isInBoss()) extraCompletedRooms = bloodRoomCompleted ? 1 : 2; - return 20 + (int) Math.floor(80.0 * (getCompletedRooms() + extraCompletedRooms) / getTotalRooms()) - getPuzzlePenalty() - getDeathScorePenalty(); + return 20 + (int) Math.floor(80.0 * (getCompletedRooms() + getExtraCompletedRooms()) / getTotalRooms()) - getPuzzlePenalty() - getDeathScorePenalty(); } private static int calculateExploreScore() { - int extraCompletedRooms = 0; - if (!DungeonManager.isInBoss()) extraCompletedRooms = bloodRoomCompleted ? 1 : 2; - int completedRoomScore = (int) Math.floor(60.0 * (getCompletedRooms() + extraCompletedRooms) / getTotalRooms()); + int completedRoomScore = (int) Math.floor(60.0 * (getCompletedRooms() + getExtraCompletedRooms()) / getTotalRooms()); int percentageRequirement = FloorRequirement.valueOf(currentFloor).percentage; int secretsScore = (int) Math.floor(40 * Math.min(percentageRequirement, getSecretsPercentage()) / percentageRequirement); return completedRoomScore + secretsScore; @@ -168,18 +170,11 @@ public class DungeonScore { if (timeSpent < timeRequirement) return score; double timePastRequirement = ((double) (timeSpent - timeRequirement) / timeRequirement) * 100; - if (timePastRequirement >= 0 && timePastRequirement < 20) { - score -= (int) timePastRequirement / 2; - } else if (timePastRequirement >= 20 && timePastRequirement < 40) { - score -= (int) (10 + (timePastRequirement - 20) / 4); - } else if (timePastRequirement >= 40 && timePastRequirement < 50) { - score -= (int) (15 + (timePastRequirement - 40) / 5); - } else if (timePastRequirement >= 50 && timePastRequirement < 60) { - score -= (int) (17 + (timePastRequirement - 50) / 6); - } else if (timePastRequirement >= 60) { - score -= (int) (18 + (2.0 / 3.0) + (timePastRequirement - 60) / 7); - } - return score; + if (timePastRequirement < 20) return score - (int) timePastRequirement / 2; + if (timePastRequirement < 40) return score - (int) (10 + (timePastRequirement - 20) / 4); + if (timePastRequirement < 50) return score - (int) (15 + (timePastRequirement - 40) / 5); + if (timePastRequirement < 60) return score - (int) (17 + (timePastRequirement - 50) / 6); + return score - (int) (18 + (2.0 / 3.0) + (timePastRequirement - 60) / 7); } private static int calculateBonusScore() { @@ -191,7 +186,7 @@ public class DungeonScore { } private static boolean checkIfDungeonStarted() { - return Utils.STRING_SCOREBOARD.stream().anyMatch(s -> DUNGEON_START_PATTERN.matcher(s).matches()); + return Utils.STRING_SCOREBOARD.stream().noneMatch(s -> DUNGEON_START_PATTERN.matcher(s).matches()); } public static boolean isEntityMimic(Entity entity) { @@ -214,6 +209,7 @@ public class DungeonScore { public static void handleEntityDeath(Entity entity) { if (isMimicKilled) return; if (!isEntityMimic(entity)) return; + if (MIMIC_MESSAGES_CONFIG.sendMimicMessages) MessageScheduler.INSTANCE.sendMessageAfterCooldown(MIMIC_MESSAGES_CONFIG.mimicMessage); isMimicKilled = true; } @@ -221,6 +217,8 @@ public class DungeonScore { isMimicKilled = state; } + //This is not very accurate at the beginning of the dungeon since clear percentage is rounded to the closest integer, so at lower percentages its effect on the result is quite high. + //For example: If clear percentage is 7% with a single room completed, it can be rounded from 6.5 or 7.49. In that range, the actual total room count can be either 14 or 15 while our result is 14. private static int getTotalRooms() { int completedRooms = getCompletedRooms(); return (int) Math.round(completedRooms / getClearPercentage()); @@ -231,6 +229,12 @@ public class DungeonScore { return matcher != null ? Integer.parseInt(matcher.group("rooms")) : 0; } + private static int getExtraCompletedRooms() { //This is needed for calculating the score before going in the boss room & completing the blood room, so we have the result sooner + if (!bloodRoomCompleted) return 2; + if (!DungeonManager.isInBoss()) return 1; + return 0; + } + private static double getClearPercentage() { for (String sidebarLine : Utils.STRING_SCOREBOARD) { Matcher clearMatcher = CLEARED_PATTERN.matcher(sidebarLine); @@ -306,7 +310,6 @@ public class DungeonScore { } private static void checkMessageForDeaths(String message) { - if (!Utils.isInDungeons()) return; if (!message.startsWith("\u2620", 1)) return; Matcher matcher = DEATHS_PATTERN.matcher(message); if (!matcher.matches()) return; @@ -317,9 +320,7 @@ public class DungeonScore { else return s; }); CompletableFuture.supplyAsync(() -> hasSpiritPet(whoDied)) - .thenAccept(hasSpiritPet -> { - firstDeathHasSpiritPet = hasSpiritPet; - }); + .thenAccept(hasSpiritPet -> firstDeathHasSpiritPet = hasSpiritPet); } private static void checkMessageForWatcher(String message) { @@ -336,6 +337,14 @@ public class DungeonScore { LOGGER.error("Floor pattern doesn't match"); } + public static int getScore() { + return score; + } + + public static boolean isDungeonStarted() { + return dungeonStarted; + } + enum FloorRequirement { E(30, 1200), F1(30, 600), diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java new file mode 100644 index 00000000..9da12426 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java @@ -0,0 +1,38 @@ +package de.hysky.skyblocker.skyblock.dungeon; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.Utils; +import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class DungeonScoreHUD { + + public static void init() { + HudRenderCallback.EVENT.register(DungeonScoreHUD::onHudRender); + } + + private static void onHudRender(DrawContext context, float tickDelta) { + if (!Utils.isInDungeons() || !DungeonScore.isDungeonStarted()) return; + + int x = SkyblockerConfigManager.get().locations.dungeons.mapX; + int y = SkyblockerConfigManager.get().locations.dungeons.mapY; + int size = (int) (128 * SkyblockerConfigManager.get().locations.dungeons.mapScaling); + context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, + Text.literal("Score: ").append(formatScore(DungeonScore.getScore())), + x + (size >> 1), + y + size + 5, + 0x00FFFFFF); + } + + private static Text formatScore(int score) { + if (score < 100) return Text.literal(String.valueOf(score)).withColor(0xDC1A1A).append(Text.literal(" (D)").formatted(Formatting.GRAY)); + if (score < 160) return Text.literal(String.valueOf(score)).withColor(0x4141FF).append(Text.literal(" (C)").formatted(Formatting.GRAY)); + if (score < 230) return Text.literal(String.valueOf(score)).withColor(0x7FCC19).append(Text.literal(" (B)").formatted(Formatting.GRAY)); + if (score < 270) return Text.literal(String.valueOf(score)).withColor(0x7F3FB2).append(Text.literal(" (A)").formatted(Formatting.GRAY)); + if (score < 300) return Text.literal(String.valueOf(score)).withColor(0xF1E252).append(Text.literal(" (S)").formatted(Formatting.GRAY)); + return Text.literal(String.valueOf(score)).withColor(0xF1E252).formatted(Formatting.BOLD).append(Text.literal(" (S+)").formatted(Formatting.GRAY)); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java b/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java index 0fce5b2c..51482794 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java @@ -2,6 +2,7 @@ package de.hysky.skyblocker.skyblock.filters; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; +import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.chat.ChatFilterResult; import de.hysky.skyblocker.utils.chat.ChatPatternListener; import net.minecraft.text.Text; @@ -10,7 +11,7 @@ import java.util.regex.Matcher; public class MimicFilter extends ChatPatternListener { public MimicFilter() { - super("(?:Mimic dead!|Mimic Killed!|\\$SKYTILS-DUNGEON-SCORE-MIMIC\\$|\\Q" + SkyblockerConfigManager.get().locations.dungeons.mimicMessages.mimicMessage + "\\E)$"); + super("(?:Mimic dead!?|Mimic Killed!|\\$SKYTILS-DUNGEON-SCORE-MIMIC\\$|\\Q" + SkyblockerConfigManager.get().locations.dungeons.mimicMessages.mimicMessage + "\\E)$"); } @Override @@ -20,7 +21,8 @@ public class MimicFilter extends ChatPatternListener { @Override protected boolean onMatch(Text message, Matcher matcher) { + if (!Utils.isInDungeons()) return false; DungeonScore.setMimicKilled(true); - return false; + return true; } } -- cgit From 52eb325a71664cd48b527dde13ba1df64a3b4777 Mon Sep 17 00:00:00 2001 From: Emirlol <81419447+Emirlol@users.noreply.github.com> Date: Tue, 16 Jan 2024 10:12:39 +0300 Subject: Made the score hud element's location and size configurable --- .../hysky/skyblocker/config/SkyblockerConfig.java | 12 ++++++ .../config/categories/DungeonsCategory.java | 18 ++++++++ .../de/hysky/skyblocker/mixin/InGameHudMixin.java | 10 +++-- .../skyblocker/skyblock/dungeon/DungeonMap.java | 12 +----- .../skyblock/dungeon/DungeonMapConfigScreen.java | 48 ++++++++++++++++------ .../skyblock/dungeon/DungeonScoreHUD.java | 41 +++++++++--------- .../resources/assets/skyblocker/lang/en_us.json | 4 +- 7 files changed, 97 insertions(+), 48 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index e07a7588..ffd6aa4d 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -623,6 +623,18 @@ public class SkyblockerConfig { @SerialEntry public int mapY = 2; + @SerialEntry + public boolean enableScore = true; + + @SerialEntry + public int scoreX = 29; + + @SerialEntry + public int scoreY = 134; + + @SerialEntry + public float scoreScaling = 1f; + @SerialEntry public boolean playerSecretsTracker = false; diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index 06133afc..8cd697e5 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -315,6 +315,13 @@ public class DungeonsCategory { newValue -> config.locations.dungeons.enableMap = newValue) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.enableScore")) + .binding(defaults.locations.dungeons.enableScore, + () -> config.locations.dungeons.enableScore, + newValue -> config.locations.dungeons.enableScore = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) .option(ButtonOption.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mapScreen")) .text(Text.translatable("text.skyblocker.open")) @@ -327,6 +334,17 @@ public class DungeonsCategory { newValue -> config.locations.dungeons.mapScaling = newValue) .controller(FloatFieldControllerBuilder::create) .build()) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.scoreScaling")) + .binding(defaults.locations.dungeons.scoreScaling, + () -> config.locations.dungeons.scoreScaling, + newValue -> { + config.locations.dungeons.scoreX = config.locations.dungeons.scoreX + (int) ((config.locations.dungeons.scoreScaling - newValue) * 38.0); + config.locations.dungeons.scoreY = config.locations.dungeons.scoreY + (int) ((config.locations.dungeons.scoreScaling - newValue) * MinecraftClient.getInstance().textRenderer.fontHeight / 2.0); + config.locations.dungeons.scoreScaling = newValue; + }) + .controller(FloatFieldControllerBuilder::create) + .build()) .option(Option.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker")) .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker.@Tooltip"))) diff --git a/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java b/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java index 0ee7b528..396bf893 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java @@ -5,9 +5,11 @@ import com.llamalad7.mixinextras.sugar.Local; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.FancyStatusBars; +import de.hysky.skyblocker.skyblock.dungeon.DungeonMap; +import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; +import de.hysky.skyblocker.skyblock.dungeon.DungeonScoreHUD; import de.hysky.skyblocker.skyblock.item.HotbarSlotLock; import de.hysky.skyblocker.skyblock.item.ItemCooldowns; -import de.hysky.skyblocker.skyblock.dungeon.DungeonMap; import de.hysky.skyblocker.skyblock.item.ItemRarityBackgrounds; import de.hysky.skyblocker.utils.Utils; import net.fabricmc.api.EnvType; @@ -64,8 +66,10 @@ public abstract class InGameHudMixin { if (statusBars.render(context, scaledWidth, scaledHeight)) ci.cancel(); - if (Utils.isInDungeons() && SkyblockerConfigManager.get().locations.dungeons.enableMap) - DungeonMap.render(context.getMatrices()); + if (Utils.isInDungeons() && DungeonScore.isDungeonStarted()) { + if (SkyblockerConfigManager.get().locations.dungeons.enableMap) DungeonMap.render(context.getMatrices()); + if (SkyblockerConfigManager.get().locations.dungeons.enableScore) DungeonScoreHUD.render(context); + } } @Inject(method = "renderMountHealth", at = @At("HEAD"), cancellable = true) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMap.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMap.java index e1af85ea..293d301f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMap.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMap.java @@ -5,7 +5,6 @@ import de.hysky.skyblocker.utils.scheduler.Scheduler; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; import net.minecraft.client.render.MapRenderer; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.util.math.MatrixStack; @@ -13,12 +12,9 @@ import net.minecraft.item.FilledMapItem; import net.minecraft.item.ItemStack; import net.minecraft.item.map.MapState; import net.minecraft.nbt.NbtCompound; -import net.minecraft.util.Identifier; import org.apache.commons.lang3.StringUtils; public class DungeonMap { - private static final Identifier MAP_BACKGROUND = new Identifier("textures/map/map_background.png"); - public static void render(MatrixStack matrices) { MinecraftClient client = MinecraftClient.getInstance(); if (client.player == null || client.world == null) return; @@ -46,13 +42,7 @@ public class DungeonMap { } } - public static void renderHUDMap(DrawContext context, int x, int y) { - float scaling = SkyblockerConfigManager.get().locations.dungeons.mapScaling; - int size = (int) (128 * scaling); - context.drawTexture(MAP_BACKGROUND, x, y, 0, 0, size, size, size, size); - } - - public static void init() { + public static void init() { //Todo: consider renaming the command to a more general name since it'll also have dungeon score and maybe other stuff in the future ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker") .then(ClientCommandManager.literal("hud") .then(ClientCommandManager.literal("dungeonmap") diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java index 02b08254..00a956e1 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java @@ -5,13 +5,17 @@ import de.hysky.skyblocker.utils.render.RenderHelper; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.text.Text; +import net.minecraft.util.Identifier; import java.awt.*; public class DungeonMapConfigScreen extends Screen { - private int hudX = SkyblockerConfigManager.get().locations.dungeons.mapX; - private int hudY = SkyblockerConfigManager.get().locations.dungeons.mapY; + private int mapX = SkyblockerConfigManager.get().locations.dungeons.mapX; + private int mapY = SkyblockerConfigManager.get().locations.dungeons.mapY; + private int scoreX = SkyblockerConfigManager.get().locations.dungeons.scoreX; + private int scoreY = SkyblockerConfigManager.get().locations.dungeons.scoreY; + private static final Identifier MAP_BACKGROUND = new Identifier("textures/map/map_background.png"); private final Screen parent; protected DungeonMapConfigScreen() { @@ -27,17 +31,23 @@ public class DungeonMapConfigScreen extends Screen { public void render(DrawContext context, int mouseX, int mouseY, float delta) { super.render(context, mouseX, mouseY, delta); renderBackground(context, mouseX, mouseY, delta); - DungeonMap.renderHUDMap(context, hudX, hudY); + renderHUDMap(context, mapX, mapY); + renderHUDScore(context, scoreX, scoreY); context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width >> 1, height >> 1, Color.GRAY.getRGB()); } @Override public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { - float scaling = SkyblockerConfigManager.get().locations.dungeons.mapScaling; - int size = (int) (128 * scaling); - if (RenderHelper.pointIsInArea(mouseX, mouseY, hudX, hudY, hudX + size, hudY + size) && button == 0) { - hudX = (int) Math.max(Math.min(mouseX - (size >> 1), this.width - size), 0); - hudY = (int) Math.max(Math.min(mouseY - (size >> 1), this.height - size), 0); + int mapSize = (int) (128 * SkyblockerConfigManager.get().locations.dungeons.mapScaling); + float scoreScaling = SkyblockerConfigManager.get().locations.dungeons.scoreScaling; + int scoreWidth = (int) (textRenderer.getWidth("Score: 300 (S+)") * scoreScaling); + int scoreHeight = (int) (textRenderer.fontHeight * scoreScaling); + if (RenderHelper.pointIsInArea(mouseX, mouseY, mapX, mapY, mapX + mapSize, mapY + mapSize) && button == 0) { + mapX = (int) Math.max(Math.min(mouseX - (mapSize >> 1), this.width - mapSize), 0); + mapY = (int) Math.max(Math.min(mouseY - (mapSize >> 1), this.height - mapSize), 0); + } else if (RenderHelper.pointIsInArea(mouseX, mouseY, scoreX, scoreY, scoreX + scoreWidth, scoreY + scoreHeight) && button == 0) { + scoreX = (int) Math.max(Math.min(mouseX - (scoreWidth >> 1), this.width - scoreWidth), 0); + scoreY = (int) Math.max(Math.min(mouseY - (scoreHeight >> 1), this.height - scoreHeight), 0); } return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); } @@ -45,8 +55,10 @@ public class DungeonMapConfigScreen extends Screen { @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { if (button == 1) { - hudX = 2; - hudY = 2; + mapX = 2; + mapY = 2; + scoreX = Math.max((int) ((mapX + (64 * SkyblockerConfigManager.get().locations.dungeons.mapScaling)) - textRenderer.getWidth("Score: 300 (S+)") * SkyblockerConfigManager.get().locations.dungeons.scoreScaling / 2), 0); + scoreY = (int) (mapY + (128 * SkyblockerConfigManager.get().locations.dungeons.mapScaling) + 4); } return super.mouseClicked(mouseX, mouseY, button); @@ -54,10 +66,22 @@ public class DungeonMapConfigScreen extends Screen { @Override public void close() { - SkyblockerConfigManager.get().locations.dungeons.mapX = hudX; - SkyblockerConfigManager.get().locations.dungeons.mapY = hudY; + SkyblockerConfigManager.get().locations.dungeons.mapX = mapX; + SkyblockerConfigManager.get().locations.dungeons.mapY = mapY; + SkyblockerConfigManager.get().locations.dungeons.scoreX = scoreX; + SkyblockerConfigManager.get().locations.dungeons.scoreY = scoreY; SkyblockerConfigManager.save(); this.client.setScreen(parent); } + + public void renderHUDMap(DrawContext context, int x, int y) { + float scaling = SkyblockerConfigManager.get().locations.dungeons.mapScaling; + int size = (int) (128 * scaling); + context.drawTexture(MAP_BACKGROUND, x, y, 0, 0, size, size, size, size); + } + + public void renderHUDScore(DrawContext context, int x, int y) { + DungeonScoreHUD.render(context, x, y); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java index 9da12426..18038ccd 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java @@ -1,38 +1,37 @@ package de.hysky.skyblocker.skyblock.dungeon; import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.utils.Utils; -import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; import net.minecraft.util.Formatting; public class DungeonScoreHUD { - - public static void init() { - HudRenderCallback.EVENT.register(DungeonScoreHUD::onHudRender); + private DungeonScoreHUD() { } - private static void onHudRender(DrawContext context, float tickDelta) { - if (!Utils.isInDungeons() || !DungeonScore.isDungeonStarted()) return; + public static void render(DrawContext context) { + int x = SkyblockerConfigManager.get().locations.dungeons.scoreX; + int y = SkyblockerConfigManager.get().locations.dungeons.scoreY; + render(context, x, y); + } - int x = SkyblockerConfigManager.get().locations.dungeons.mapX; - int y = SkyblockerConfigManager.get().locations.dungeons.mapY; - int size = (int) (128 * SkyblockerConfigManager.get().locations.dungeons.mapScaling); - context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, - Text.literal("Score: ").append(formatScore(DungeonScore.getScore())), - x + (size >> 1), - y + size + 5, - 0x00FFFFFF); + public static void render(DrawContext context, int x, int y) { + float scale = SkyblockerConfigManager.get().locations.dungeons.scoreScaling; + MatrixStack matrixStack = context.getMatrices(); + matrixStack.push(); + matrixStack.scale(scale, scale, 0); + context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, Text.literal("Score: ").append(formatScore(DungeonScore.getScore())), (int) (x / scale), (int) (y / scale), 0xFFFFFFFF); + matrixStack.pop(); } private static Text formatScore(int score) { - if (score < 100) return Text.literal(String.valueOf(score)).withColor(0xDC1A1A).append(Text.literal(" (D)").formatted(Formatting.GRAY)); - if (score < 160) return Text.literal(String.valueOf(score)).withColor(0x4141FF).append(Text.literal(" (C)").formatted(Formatting.GRAY)); - if (score < 230) return Text.literal(String.valueOf(score)).withColor(0x7FCC19).append(Text.literal(" (B)").formatted(Formatting.GRAY)); - if (score < 270) return Text.literal(String.valueOf(score)).withColor(0x7F3FB2).append(Text.literal(" (A)").formatted(Formatting.GRAY)); - if (score < 300) return Text.literal(String.valueOf(score)).withColor(0xF1E252).append(Text.literal(" (S)").formatted(Formatting.GRAY)); - return Text.literal(String.valueOf(score)).withColor(0xF1E252).formatted(Formatting.BOLD).append(Text.literal(" (S+)").formatted(Formatting.GRAY)); + if (score < 100) return Text.literal(String.format("%03d", score)).withColor(0xDC1A1A).append(Text.literal(" (D) ").formatted(Formatting.GRAY)); + if (score < 160) return Text.literal(String.format("%03d", score)).withColor(0x4141FF).append(Text.literal(" (C) ").formatted(Formatting.GRAY)); + if (score < 230) return Text.literal(String.format("%03d", score)).withColor(0x7FCC19).append(Text.literal(" (B) ").formatted(Formatting.GRAY)); + if (score < 270) return Text.literal(String.format("%03d", score)).withColor(0x7F3FB2).append(Text.literal(" (A) ").formatted(Formatting.GRAY)); + if (score < 300) return Text.literal(String.format("%03d", score)).withColor(0xF1E252).append(Text.literal(" (S) ").formatted(Formatting.GRAY)); + return Text.literal(String.format("%03d", score)).withColor(0xF1E252).formatted(Formatting.BOLD).append(Text.literal(" (S+)").formatted(Formatting.GRAY)); } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index cd1d9673..e66fbfcd 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -215,8 +215,10 @@ "text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper": "Croesus Helper", "text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper.@Tooltip": "Gray out chests that have already been opened.", "text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Enable Map", - "text.autoconfig.skyblocker.option.locations.dungeons.mapScreen": "Dungeon Map Placement Config...", + "text.autoconfig.skyblocker.option.locations.dungeons.enableScore": "Enable Score HUD", + "text.autoconfig.skyblocker.option.locations.dungeons.mapScreen": "Dungeon Map & Score Placement Config...", "text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Map Scaling", + "text.autoconfig.skyblocker.option.locations.dungeons.scoreScaling": "Score Scaling", "text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker": "Player Secrets Tracker", "text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker.@Tooltip": "Tracks the amount of secrets people in your dungeon run are doing.", "text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow": "Starred Mob Glow", -- cgit From 1382f6ce7f4dc9aade35f7d877e6b9ba6832ce4a Mon Sep 17 00:00:00 2001 From: Emirlol <81419447+Emirlol@users.noreply.github.com> Date: Tue, 16 Jan 2024 10:52:31 +0300 Subject: Cleaned up some sections and added comments on some critical points --- .../skyblocker/skyblock/dungeon/DungeonScore.java | 35 ++++++++++------------ 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index 0a9aec50..44c19ff5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -50,7 +50,7 @@ public class DungeonScore { //Chat patterns private static final Pattern DEATHS_PATTERN = Pattern.compile(".*?\u2620 (?\\S+) .*"); //Other patterns - private static final Pattern MIMIC_FLOOR_FILTER_PATTERN = Pattern.compile("[EFM][12345]?"); + private static final Pattern MIMICLESS_FLOORS_PATTERN = Pattern.compile("[EFM][12345]?"); private static String currentFloor; private static boolean sent270; @@ -91,7 +91,7 @@ public class DungeonScore { score = calculateScore(); if (!sent270 && score >= 270 && score < 300) { if (SCORE_CONFIG.enableDungeonScore270Message) { - MessageScheduler.INSTANCE.sendMessageAfterCooldown(SCORE_CONFIG.dungeonScore270Message.replaceAll("\\[score]", "270")); + MessageScheduler.INSTANCE.sendMessageAfterCooldown("/pc " + Constants.PREFIX.get().getString() + SCORE_CONFIG.dungeonScore270Message.replaceAll("\\[score]", "270")); } if (SCORE_CONFIG.enableDungeonScore270Title) { client.inGameHud.setDefaultTitleFade(); @@ -104,7 +104,7 @@ public class DungeonScore { } if (!sent300 && score >= 300) { if (SCORE_CONFIG.enableDungeonScore300Message) { - MessageScheduler.INSTANCE.sendMessageAfterCooldown(SCORE_CONFIG.dungeonScore300Message.replaceAll("\\[score]", "300")); + MessageScheduler.INSTANCE.sendMessageAfterCooldown("/pc " + Constants.PREFIX.get().getString() + SCORE_CONFIG.dungeonScore300Message.replaceAll("\\[score]", "300")); } if (SCORE_CONFIG.enableDungeonScore300Title) { client.inGameHud.setDefaultTitleFade(); @@ -141,14 +141,8 @@ public class DungeonScore { } private static int calculateScore() { - int timeScore = calculateTimeScore(); - int exploreScore = calculateExploreScore(); - int skillScore = calculateSkillScore(); - int bonusScore = calculateBonusScore(); - int totalScore = timeScore + exploreScore + skillScore + bonusScore; - if (currentFloor.equals("E")) totalScore = (int) (totalScore * 0.7); - //Will be this way until ready for pr, so it's easy to debug. - LOGGER.info("Total Score: {} (Time: {}, Explore: {}, Skill: {}, Bonus: {})", totalScore, timeScore, exploreScore, skillScore, bonusScore); + int totalScore = calculateTimeScore() + calculateExploreScore() + calculateSkillScore() + calculateBonusScore(); + if (currentFloor.equals("E")) return (int) (totalScore * 0.7); return totalScore; } @@ -181,7 +175,7 @@ public class DungeonScore { int paulScore = isMayorPaul ? 10 : 0; int cryptsScore = Math.min(getCrypts(), 5); int mimicScore = isMimicKilled ? 2 : 0; - if (getSecretsPercentage() >= 100 && !MIMIC_FLOOR_FILTER_PATTERN.matcher(currentFloor).matches()) mimicScore = 2; //If mimic kill is not announced but all secrets are found, mimic must've been killed + if (getSecretsPercentage() >= 100 && !MIMICLESS_FLOORS_PATTERN.matcher(currentFloor).matches()) mimicScore = 2; //If mimic kill is not announced but all secrets are found, mimic must've been killed return paulScore + cryptsScore + mimicScore; } @@ -191,7 +185,7 @@ public class DungeonScore { public static boolean isEntityMimic(Entity entity) { if (!Utils.isInDungeons()) return false; - if (MIMIC_FLOOR_FILTER_PATTERN.matcher(currentFloor).matches()) return false; + if (MIMICLESS_FLOORS_PATTERN.matcher(currentFloor).matches()) return false; if (entity == null) return false; if (!(entity instanceof ZombieEntity zombie)) return false; if (!zombie.isBaby()) return false; @@ -219,9 +213,9 @@ public class DungeonScore { //This is not very accurate at the beginning of the dungeon since clear percentage is rounded to the closest integer, so at lower percentages its effect on the result is quite high. //For example: If clear percentage is 7% with a single room completed, it can be rounded from 6.5 or 7.49. In that range, the actual total room count can be either 14 or 15 while our result is 14. + //Score might fluctuate at first if the total room amount calculated changes as it gets more accurate with each room completed. private static int getTotalRooms() { - int completedRooms = getCompletedRooms(); - return (int) Math.round(completedRooms / getClearPercentage()); + return (int) Math.round(getCompletedRooms() / getClearPercentage()); } private static int getCompletedRooms() { @@ -229,7 +223,9 @@ public class DungeonScore { return matcher != null ? Integer.parseInt(matcher.group("rooms")) : 0; } - private static int getExtraCompletedRooms() { //This is needed for calculating the score before going in the boss room & completing the blood room, so we have the result sooner + //This is needed for calculating the score before going in the boss room & completing the blood room, so we have the result sooner + //It might cause score to fluctuate when completing the blood room or entering the boss room as there's a slight delay between the room being completed (boolean set to true) and the scoreboard updating + private static int getExtraCompletedRooms() { if (!bloodRoomCompleted) return 2; if (!DungeonManager.isInBoss()) return 1; return 0; @@ -241,10 +237,11 @@ public class DungeonScore { if (!clearMatcher.matches()) continue; return Double.parseDouble(clearMatcher.group("cleared")) / 100.0; } - LOGGER.error("Clear pattern doesn't match"); + LOGGER.error("[Skyblocker] Clear pattern doesn't match!"); return 0; } + //Score might fluctuate when the first death has spirit pet as the boolean will be set to true after getting a response from the api, which might take a while private static int getDeathScorePenalty() { return deathCount * 2 - (firstDeathHasSpiritPet ? 1 : 0); } @@ -254,7 +251,6 @@ public class DungeonScore { return matcher != null ? Integer.parseInt(matcher.group("count")) : 0; } - //Possible states: ✖, ✦, ✔ private static int getPuzzlePenalty() { int incompletePuzzles = 0; for (int index = 0; index < puzzleCount; index++) { @@ -302,7 +298,6 @@ public class DungeonScore { return true; } } catch (Exception e) { - e.printStackTrace(); LOGGER.error("[Skyblocker] Spirit pet lookup by name failed! Name: {} - Cause: {}", name, e.getMessage()); } return false; @@ -334,7 +329,7 @@ public class DungeonScore { currentFloor = floorMatcher.group("floor"); return; } - LOGGER.error("Floor pattern doesn't match"); + LOGGER.error("[Skyblocker] Floor pattern doesn't match!"); } public static int getScore() { -- cgit From 8feae9fc42e894431bc16474c4476ee0f7e58fa4 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 18 Jan 2024 08:23:05 +0300 Subject: Wrapped initializeMayorCache in a CompletableFuture --- src/main/java/de/hysky/skyblocker/utils/Utils.java | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java index 3336a0a7..31157bfc 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Utils.java +++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java @@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Collections; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * Utility variables and methods for retrieving Skyblock related information. @@ -396,15 +397,18 @@ public class Utils { private static void initializeMayorCache() { if (!mayor.isEmpty()) return; - try { - JsonObject json = JsonParser.parseString(Http.sendGetRequest("https://api.hypixel.net/v2/resources/skyblock/election")).getAsJsonObject(); - if (json.get("success").getAsBoolean()) { - mayor = json.get("mayor").getAsJsonObject().get("name").getAsString(); - } else { - throw new IOException("API call for mayor failed: " + json.get("cause").getAsString()); + CompletableFuture.supplyAsync(() -> { + try { + JsonObject json = JsonParser.parseString(Http.sendGetRequest("https://api.hypixel.net/v2/resources/skyblock/election")).getAsJsonObject(); + if (json.get("success").getAsBoolean()) return json.get("mayor").getAsJsonObject().get("name").getAsString(); + throw new IOException("API call for mayor status failed: " + json.get("cause").getAsString()); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); } - } catch (IOException | InterruptedException e) { - e.printStackTrace(); - } + return ""; + }).thenAccept(s -> { + if (!s.isEmpty()) mayor = s; + }); + } } -- cgit From 9a86e3fa1ff130285a998f089939da24c3b5b7b9 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 18 Jan 2024 08:39:14 +0300 Subject: Refactored score hud configs from Dungeons to DungeonScore --- .../hysky/skyblocker/config/SkyblockerConfig.java | 24 +++++++++++----------- .../config/categories/DungeonsCategory.java | 16 +++++++-------- .../de/hysky/skyblocker/mixin/InGameHudMixin.java | 2 +- .../skyblock/dungeon/DungeonMapConfigScreen.java | 12 +++++------ .../skyblock/dungeon/DungeonScoreHUD.java | 6 +++--- 5 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index ffd6aa4d..e47b008d 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -623,18 +623,6 @@ public class SkyblockerConfig { @SerialEntry public int mapY = 2; - @SerialEntry - public boolean enableScore = true; - - @SerialEntry - public int scoreX = 29; - - @SerialEntry - public int scoreY = 134; - - @SerialEntry - public float scoreScaling = 1f; - @SerialEntry public boolean playerSecretsTracker = false; @@ -772,6 +760,18 @@ public class SkyblockerConfig { @SerialEntry public String dungeonScore300Message = "300 Score Reached!"; + + @SerialEntry + public boolean enableScoreHUD = true; + + @SerialEntry + public int scoreX = 29; + + @SerialEntry + public int scoreY = 134; + + @SerialEntry + public float scoreScaling = 1f; } public static class DungeonChestProfit { diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index 8cd697e5..8546382f 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -317,9 +317,9 @@ public class DungeonsCategory { .build()) .option(Option.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.enableScore")) - .binding(defaults.locations.dungeons.enableScore, - () -> config.locations.dungeons.enableScore, - newValue -> config.locations.dungeons.enableScore = newValue) + .binding(defaults.locations.dungeons.dungeonScore.enableScoreHUD, + () -> config.locations.dungeons.dungeonScore.enableScoreHUD, + newValue -> config.locations.dungeons.dungeonScore.enableScoreHUD = newValue) .controller(ConfigUtils::createBooleanController) .build()) .option(ButtonOption.createBuilder() @@ -336,12 +336,12 @@ public class DungeonsCategory { .build()) .option(Option.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.scoreScaling")) - .binding(defaults.locations.dungeons.scoreScaling, - () -> config.locations.dungeons.scoreScaling, + .binding(defaults.locations.dungeons.dungeonScore.scoreScaling, + () -> config.locations.dungeons.dungeonScore.scoreScaling, newValue -> { - config.locations.dungeons.scoreX = config.locations.dungeons.scoreX + (int) ((config.locations.dungeons.scoreScaling - newValue) * 38.0); - config.locations.dungeons.scoreY = config.locations.dungeons.scoreY + (int) ((config.locations.dungeons.scoreScaling - newValue) * MinecraftClient.getInstance().textRenderer.fontHeight / 2.0); - config.locations.dungeons.scoreScaling = newValue; + config.locations.dungeons.dungeonScore.scoreX = config.locations.dungeons.dungeonScore.scoreX + (int) ((config.locations.dungeons.dungeonScore.scoreScaling - newValue) * 38.0); + config.locations.dungeons.dungeonScore.scoreY = config.locations.dungeons.dungeonScore.scoreY + (int) ((config.locations.dungeons.dungeonScore.scoreScaling - newValue) * MinecraftClient.getInstance().textRenderer.fontHeight / 2.0); + config.locations.dungeons.dungeonScore.scoreScaling = newValue; }) .controller(FloatFieldControllerBuilder::create) .build()) diff --git a/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java b/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java index 396bf893..df7cbdea 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java @@ -68,7 +68,7 @@ public abstract class InGameHudMixin { if (Utils.isInDungeons() && DungeonScore.isDungeonStarted()) { if (SkyblockerConfigManager.get().locations.dungeons.enableMap) DungeonMap.render(context.getMatrices()); - if (SkyblockerConfigManager.get().locations.dungeons.enableScore) DungeonScoreHUD.render(context); + if (SkyblockerConfigManager.get().locations.dungeons.dungeonScore.enableScoreHUD) DungeonScoreHUD.render(context); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java index 00a956e1..b832f12d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java @@ -13,8 +13,8 @@ public class DungeonMapConfigScreen extends Screen { private int mapX = SkyblockerConfigManager.get().locations.dungeons.mapX; private int mapY = SkyblockerConfigManager.get().locations.dungeons.mapY; - private int scoreX = SkyblockerConfigManager.get().locations.dungeons.scoreX; - private int scoreY = SkyblockerConfigManager.get().locations.dungeons.scoreY; + private int scoreX = SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreX; + private int scoreY = SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreY; private static final Identifier MAP_BACKGROUND = new Identifier("textures/map/map_background.png"); private final Screen parent; @@ -39,7 +39,7 @@ public class DungeonMapConfigScreen extends Screen { @Override public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { int mapSize = (int) (128 * SkyblockerConfigManager.get().locations.dungeons.mapScaling); - float scoreScaling = SkyblockerConfigManager.get().locations.dungeons.scoreScaling; + float scoreScaling = SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreScaling; int scoreWidth = (int) (textRenderer.getWidth("Score: 300 (S+)") * scoreScaling); int scoreHeight = (int) (textRenderer.fontHeight * scoreScaling); if (RenderHelper.pointIsInArea(mouseX, mouseY, mapX, mapY, mapX + mapSize, mapY + mapSize) && button == 0) { @@ -57,7 +57,7 @@ public class DungeonMapConfigScreen extends Screen { if (button == 1) { mapX = 2; mapY = 2; - scoreX = Math.max((int) ((mapX + (64 * SkyblockerConfigManager.get().locations.dungeons.mapScaling)) - textRenderer.getWidth("Score: 300 (S+)") * SkyblockerConfigManager.get().locations.dungeons.scoreScaling / 2), 0); + scoreX = Math.max((int) ((mapX + (64 * SkyblockerConfigManager.get().locations.dungeons.mapScaling)) - textRenderer.getWidth("Score: 300 (S+)") * SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreScaling / 2), 0); scoreY = (int) (mapY + (128 * SkyblockerConfigManager.get().locations.dungeons.mapScaling) + 4); } @@ -68,8 +68,8 @@ public class DungeonMapConfigScreen extends Screen { public void close() { SkyblockerConfigManager.get().locations.dungeons.mapX = mapX; SkyblockerConfigManager.get().locations.dungeons.mapY = mapY; - SkyblockerConfigManager.get().locations.dungeons.scoreX = scoreX; - SkyblockerConfigManager.get().locations.dungeons.scoreY = scoreY; + SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreX = scoreX; + SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreY = scoreY; SkyblockerConfigManager.save(); this.client.setScreen(parent); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java index 18038ccd..eedbf020 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java @@ -12,13 +12,13 @@ public class DungeonScoreHUD { } public static void render(DrawContext context) { - int x = SkyblockerConfigManager.get().locations.dungeons.scoreX; - int y = SkyblockerConfigManager.get().locations.dungeons.scoreY; + int x = SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreX; + int y = SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreY; render(context, x, y); } public static void render(DrawContext context, int x, int y) { - float scale = SkyblockerConfigManager.get().locations.dungeons.scoreScaling; + float scale = SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreScaling; MatrixStack matrixStack = context.getMatrices(); matrixStack.push(); matrixStack.scale(scale, scale, 0); -- cgit From b52f1e67c417266599d23dff22c7c2febfad95ed Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 18 Jan 2024 10:07:00 +0300 Subject: Prevent sending 270 message if 300 message is already sent This can happen if the player leaves the dungeon and rejoins while score is above 300, then fall below 300 from player deaths etc. --- src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index 44c19ff5..20942935 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -89,7 +89,7 @@ public class DungeonScore { return; } score = calculateScore(); - if (!sent270 && score >= 270 && score < 300) { + if (!sent270 && !sent300 && score >= 270 && score < 300) { if (SCORE_CONFIG.enableDungeonScore270Message) { MessageScheduler.INSTANCE.sendMessageAfterCooldown("/pc " + Constants.PREFIX.get().getString() + SCORE_CONFIG.dungeonScore270Message.replaceAll("\\[score]", "270")); } -- cgit From d9c69b47127c6aae71333831654402f1924924c8 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:24:56 +0300 Subject: Reduce mimic floor pattern matching to once per run and refactor isMimicKilled boolean --- .../skyblocker/skyblock/dungeon/DungeonScore.java | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index 20942935..b27ca660 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -50,12 +50,13 @@ public class DungeonScore { //Chat patterns private static final Pattern DEATHS_PATTERN = Pattern.compile(".*?\u2620 (?\\S+) .*"); //Other patterns - private static final Pattern MIMICLESS_FLOORS_PATTERN = Pattern.compile("[EFM][12345]?"); + private static final Pattern MIMIC_FLOORS_PATTERN = Pattern.compile("[FM][67]]"); private static String currentFloor; + private static boolean floorHasMimics; private static boolean sent270; private static boolean sent300; - private static boolean isMimicKilled; + private static boolean mimicKilled; private static boolean dungeonStarted; private static boolean isMayorPaul; private static boolean firstDeathHasSpiritPet; @@ -119,9 +120,10 @@ public class DungeonScore { private static void reset() { currentFloor = ""; + floorHasMimics = false; sent270 = false; sent300 = false; - isMimicKilled = false; + mimicKilled = false; dungeonStarted = false; isMayorPaul = false; firstDeathHasSpiritPet = false; @@ -138,6 +140,7 @@ public class DungeonScore { puzzleCount = getPuzzleCount(); isMayorPaul = Utils.getMayor().equals("Paul"); startingTime = System.currentTimeMillis(); + floorHasMimics = MIMIC_FLOORS_PATTERN.matcher(currentFloor).matches(); } private static int calculateScore() { @@ -174,8 +177,8 @@ public class DungeonScore { private static int calculateBonusScore() { int paulScore = isMayorPaul ? 10 : 0; int cryptsScore = Math.min(getCrypts(), 5); - int mimicScore = isMimicKilled ? 2 : 0; - if (getSecretsPercentage() >= 100 && !MIMICLESS_FLOORS_PATTERN.matcher(currentFloor).matches()) mimicScore = 2; //If mimic kill is not announced but all secrets are found, mimic must've been killed + int mimicScore = mimicKilled ? 2 : 0; + if (getSecretsPercentage() >= 100 && floorHasMimics) mimicScore = 2; //If mimic kill is not announced but all secrets are found, mimic must've been killed return paulScore + cryptsScore + mimicScore; } @@ -185,7 +188,7 @@ public class DungeonScore { public static boolean isEntityMimic(Entity entity) { if (!Utils.isInDungeons()) return false; - if (MIMICLESS_FLOORS_PATTERN.matcher(currentFloor).matches()) return false; + if (!floorHasMimics) return false; if (entity == null) return false; if (!(entity instanceof ZombieEntity zombie)) return false; if (!zombie.isBaby()) return false; @@ -201,14 +204,14 @@ public class DungeonScore { } public static void handleEntityDeath(Entity entity) { - if (isMimicKilled) return; + if (mimicKilled) return; if (!isEntityMimic(entity)) return; if (MIMIC_MESSAGES_CONFIG.sendMimicMessages) MessageScheduler.INSTANCE.sendMessageAfterCooldown(MIMIC_MESSAGES_CONFIG.mimicMessage); - isMimicKilled = true; + mimicKilled = true; } public static void setMimicKilled(boolean state) { - isMimicKilled = state; + mimicKilled = state; } //This is not very accurate at the beginning of the dungeon since clear percentage is rounded to the closest integer, so at lower percentages its effect on the result is quite high. -- cgit From 2bfe8c5d5d9c39f270984e1f2d511c67cdc917f9 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:28:04 +0300 Subject: Check chat messages for dungeon start instead of scoreboard --- .../skyblocker/skyblock/dungeon/DungeonScore.java | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index b27ca660..98d3d79b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -39,7 +39,6 @@ public class DungeonScore { private static final Logger LOGGER = LoggerFactory.getLogger("Skyblocker Dungeon Score"); //Scoreboard patterns private static final Pattern CLEARED_PATTERN = Pattern.compile("Cleared: (?\\d+)%.*"); - private static final Pattern DUNGEON_START_PATTERN = Pattern.compile("(?:Auto-closing|Starting) in: \\d:\\d+"); private static final Pattern FLOOR_PATTERN = Pattern.compile(".*?(?=T)The Catacombs \\((?[EFM]\\D*\\d*)\\)"); //Playerlist patterns private static final Pattern SECRETS_PATTERN = Pattern.compile("Secrets Found: (?\\d+\\.?\\d*)%"); @@ -72,10 +71,14 @@ public class DungeonScore { SkyblockEvents.LEAVE.register(SpiritPetCache::clear); ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> reset()); ClientReceiveMessageEvents.GAME.register((message, overlay) -> { - if (!Utils.isInDungeons() || !dungeonStarted) return; + if (overlay || !Utils.isInDungeons()) return; String str = message.getString(); - checkMessageForDeaths(str); - checkMessageForWatcher(str); + if (!dungeonStarted) { + checkMessageForMort(str); + } else { + checkMessageForDeaths(str); + checkMessageForWatcher(str); + } }); } @@ -85,10 +88,8 @@ public class DungeonScore { reset(); return; } - if (!dungeonStarted) { - if (checkIfDungeonStarted()) onDungeonStart(); - return; - } + if (!dungeonStarted) return; + score = calculateScore(); if (!sent270 && !sent300 && score >= 270 && score < 300) { if (SCORE_CONFIG.enableDungeonScore270Message) { @@ -182,10 +183,6 @@ public class DungeonScore { return paulScore + cryptsScore + mimicScore; } - private static boolean checkIfDungeonStarted() { - return Utils.STRING_SCOREBOARD.stream().noneMatch(s -> DUNGEON_START_PATTERN.matcher(s).matches()); - } - public static boolean isEntityMimic(Entity entity) { if (!Utils.isInDungeons()) return false; if (!floorHasMimics) return false; @@ -325,6 +322,11 @@ public class DungeonScore { if (message.equals("[BOSS] The Watcher: You have proven yourself. You may pass.")) bloodRoomCompleted = true; } + private static void checkMessageForMort(String message) { + if (!message.equals("§e[NPC] §bMort§f: You should find it useful if you get lost.")) return; + onDungeonStart(); + } + public static void setCurrentFloor() { for (String sidebarLine : Utils.STRING_SCOREBOARD) { Matcher floorMatcher = FLOOR_PATTERN.matcher(sidebarLine); -- cgit From a074292c9ce56daa060c02f8abaf78857998fffd Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:31:25 +0300 Subject: Reduce Enum#valueOf calls and prevent infinite or negative score and division by 0 --- .../skyblocker/skyblock/dungeon/DungeonScore.java | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index 98d3d79b..6059f9d5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -51,6 +51,7 @@ public class DungeonScore { //Other patterns private static final Pattern MIMIC_FLOORS_PATTERN = Pattern.compile("[FM][67]]"); + private static FloorRequirement floorRequirement; private static String currentFloor; private static boolean floorHasMimics; private static boolean sent270; @@ -120,6 +121,7 @@ public class DungeonScore { } private static void reset() { + floorRequirement = null; currentFloor = ""; floorHasMimics = false; sent270 = false; @@ -141,6 +143,7 @@ public class DungeonScore { puzzleCount = getPuzzleCount(); isMayorPaul = Utils.getMayor().equals("Paul"); startingTime = System.currentTimeMillis(); + floorRequirement = FloorRequirement.valueOf(currentFloor); floorHasMimics = MIMIC_FLOORS_PATTERN.matcher(currentFloor).matches(); } @@ -151,28 +154,28 @@ public class DungeonScore { } private static int calculateSkillScore() { - return 20 + (int) Math.floor(80.0 * (getCompletedRooms() + getExtraCompletedRooms()) / getTotalRooms()) - getPuzzlePenalty() - getDeathScorePenalty(); + int totalRooms = getTotalRooms(); //This is necessary to avoid division by 0 at the start of dungeons, which results in infinite score + return 20 + Math.max((totalRooms != 0 ? (int) (80.0 * (getCompletedRooms() + getExtraCompletedRooms()) / totalRooms) : 0) - getPuzzlePenalty() - getDeathScorePenalty(), 0); //Can't go below 20 skill score } private static int calculateExploreScore() { - int completedRoomScore = (int) Math.floor(60.0 * (getCompletedRooms() + getExtraCompletedRooms()) / getTotalRooms()); - int percentageRequirement = FloorRequirement.valueOf(currentFloor).percentage; - int secretsScore = (int) Math.floor(40 * Math.min(percentageRequirement, getSecretsPercentage()) / percentageRequirement); - return completedRoomScore + secretsScore; + int totalRooms = getTotalRooms(); //This is necessary to avoid division by 0 at the start of dungeons, which results in infinite score + int completedRoomScore = totalRooms != 0 ? (int) (60.0 * (getCompletedRooms() + getExtraCompletedRooms()) / totalRooms) : 0; + int secretsScore = (int) (40 * Math.min(floorRequirement.percentage, getSecretsPercentage()) / floorRequirement.percentage); + return Math.max(completedRoomScore + secretsScore, 0); } private static int calculateTimeScore() { int score = 100; int timeSpent = (int) (System.currentTimeMillis() - startingTime) / 1000; - int timeRequirement = FloorRequirement.valueOf(currentFloor).timeLimit; - if (timeSpent < timeRequirement) return score; + if (timeSpent < floorRequirement.timeLimit) return score; - double timePastRequirement = ((double) (timeSpent - timeRequirement) / timeRequirement) * 100; + double timePastRequirement = ((double) (timeSpent - floorRequirement.timeLimit) / floorRequirement.timeLimit) * 100; if (timePastRequirement < 20) return score - (int) timePastRequirement / 2; if (timePastRequirement < 40) return score - (int) (10 + (timePastRequirement - 20) / 4); if (timePastRequirement < 50) return score - (int) (15 + (timePastRequirement - 40) / 5); if (timePastRequirement < 60) return score - (int) (17 + (timePastRequirement - 50) / 6); - return score - (int) (18 + (2.0 / 3.0) + (timePastRequirement - 60) / 7); + return Math.max(score - (int) (18 + (2.0 / 3.0) + (timePastRequirement - 60) / 7), 0); //This can theoretically go down to -20 if the time limit is one of the lower ones like 480, but individual score categories can't go below 0 } private static int calculateBonusScore() { -- cgit From b765b3f2fe69c1e10a3eafec75c6bd17201b9196 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:32:21 +0300 Subject: Fix entrance floor score calculation --- .../de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index 6059f9d5..fde255d7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -53,6 +53,7 @@ public class DungeonScore { private static FloorRequirement floorRequirement; private static String currentFloor; + private static boolean isCurrentFloorEntrance; private static boolean floorHasMimics; private static boolean sent270; private static boolean sent300; @@ -123,6 +124,7 @@ public class DungeonScore { private static void reset() { floorRequirement = null; currentFloor = ""; + isCurrentFloorEntrance = false; floorHasMimics = false; sent270 = false; sent300 = false; @@ -145,12 +147,12 @@ public class DungeonScore { startingTime = System.currentTimeMillis(); floorRequirement = FloorRequirement.valueOf(currentFloor); floorHasMimics = MIMIC_FLOORS_PATTERN.matcher(currentFloor).matches(); + if (currentFloor.equals("E")) isCurrentFloorEntrance = true; } private static int calculateScore() { - int totalScore = calculateTimeScore() + calculateExploreScore() + calculateSkillScore() + calculateBonusScore(); - if (currentFloor.equals("E")) return (int) (totalScore * 0.7); - return totalScore; + if (isCurrentFloorEntrance) return Math.round(calculateTimeScore() * 0.7f) + Math.round(calculateExploreScore() * 0.7f) + Math.round(calculateSkillScore() * 0.7f) + Math.round(calculateBonusScore() * 0.7f); + return calculateTimeScore() + calculateExploreScore() + calculateSkillScore() + calculateBonusScore(); } private static int calculateSkillScore() { @@ -229,8 +231,8 @@ public class DungeonScore { //This is needed for calculating the score before going in the boss room & completing the blood room, so we have the result sooner //It might cause score to fluctuate when completing the blood room or entering the boss room as there's a slight delay between the room being completed (boolean set to true) and the scoreboard updating private static int getExtraCompletedRooms() { - if (!bloodRoomCompleted) return 2; - if (!DungeonManager.isInBoss()) return 1; + if (!bloodRoomCompleted) return isCurrentFloorEntrance ? 1 : 2; + if (!DungeonManager.isInBoss() && !isCurrentFloorEntrance) return 1; return 0; } -- cgit From 4afcb477f933dc496827b4936f18685b2360c776 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Fri, 19 Jan 2024 08:58:19 +0300 Subject: Changed exception handling to use a logger in Utils and DungeonScore --- .../java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java | 6 ++---- src/main/java/de/hysky/skyblocker/utils/Utils.java | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index fde255d7..48a87c36 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -197,10 +197,8 @@ public class DungeonScore { try { DefaultedList armor = (DefaultedList) zombie.getArmorItems(); return armor.stream().allMatch(ItemStack::isEmpty); - } catch (NullPointerException e) { - return false; - } catch (ClassCastException f) { - f.printStackTrace(); + } catch (Exception f) { + LOGGER.error("[Skyblocker] Failed to check if entity is a mimic! Cause: {}", f.getMessage()); return false; } } diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java index 31157bfc..eaa07ff2 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Utils.java +++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java @@ -401,9 +401,9 @@ public class Utils { try { JsonObject json = JsonParser.parseString(Http.sendGetRequest("https://api.hypixel.net/v2/resources/skyblock/election")).getAsJsonObject(); if (json.get("success").getAsBoolean()) return json.get("mayor").getAsJsonObject().get("name").getAsString(); - throw new IOException("API call for mayor status failed: " + json.get("cause").getAsString()); - } catch (IOException | InterruptedException e) { - e.printStackTrace(); + throw new IOException(json.get("cause").getAsString()); + } catch (Exception e) { + LOGGER.error("[Skyblocker] Failed to get mayor status! Cause: {}", e.getMessage()); } return ""; }).thenAccept(s -> { -- cgit From adce676848e3fb15cacfaeb8426f7f86bc5efaa4 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:04:28 +0300 Subject: Match translation key to the path in the config --- .../java/de/hysky/skyblocker/config/categories/DungeonsCategory.java | 4 ++-- src/main/resources/assets/skyblocker/lang/en_us.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index 8546382f..d939a4f0 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -316,7 +316,7 @@ public class DungeonsCategory { .controller(ConfigUtils::createBooleanController) .build()) .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.enableScore")) + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD")) .binding(defaults.locations.dungeons.dungeonScore.enableScoreHUD, () -> config.locations.dungeons.dungeonScore.enableScoreHUD, newValue -> config.locations.dungeons.dungeonScore.enableScoreHUD = newValue) @@ -335,7 +335,7 @@ public class DungeonsCategory { .controller(FloatFieldControllerBuilder::create) .build()) .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.scoreScaling")) + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.scoreScaling")) .binding(defaults.locations.dungeons.dungeonScore.scoreScaling, () -> config.locations.dungeons.dungeonScore.scoreScaling, newValue -> { diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index e66fbfcd..c151c77b 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -200,6 +200,8 @@ "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableDungeonScoreSound.@Tooltip": "Plays a sound when reaching %d score in dungeons.", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.dungeonScoreMessage": "Dungeon Score %d Message", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.dungeonScoreMessage.@Tooltip": "Message which will be sent in the chat when reaching %d score in dungeons. The string \"[score]\" will be replaced with the dungeon score (%d).", + "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD": "Enable Score HUD", + "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.scoreScaling": "Score Scaling", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit": "Dungeon Chest Profit Calculator", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit.enableProfitCalculator": "Enable Profit Calculator", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit.enableProfitCalculator.@Tooltip": "Displays the profit of a dungeon chest in the chest screen's title.\nGreen if there's profit.\nRed if there isn't profit.\nGray if you don't gain or lose anything.\nBlue if calculations were based on incomplete data.", @@ -215,10 +217,8 @@ "text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper": "Croesus Helper", "text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper.@Tooltip": "Gray out chests that have already been opened.", "text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Enable Map", - "text.autoconfig.skyblocker.option.locations.dungeons.enableScore": "Enable Score HUD", "text.autoconfig.skyblocker.option.locations.dungeons.mapScreen": "Dungeon Map & Score Placement Config...", "text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Map Scaling", - "text.autoconfig.skyblocker.option.locations.dungeons.scoreScaling": "Score Scaling", "text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker": "Player Secrets Tracker", "text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker.@Tooltip": "Tracks the amount of secrets people in your dungeon run are doing.", "text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow": "Starred Mob Glow", -- cgit From 05518642cfdff4defe45a09c3fd52381c7b23c11 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:04:28 +0300 Subject: Change onEntityStatus mixin to use ModifyExpressionValue --- .../de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java index b3fc871b..e1eb6a2d 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java @@ -1,8 +1,7 @@ package de.hysky.skyblocker.mixin; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.WrapWithCondition; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; import de.hysky.skyblocker.skyblock.FishingHelper; import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; @@ -19,7 +18,6 @@ import net.minecraft.network.packet.s2c.play.EntityStatusS2CPacket; import net.minecraft.network.packet.s2c.play.ParticleS2CPacket; import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket; import net.minecraft.util.Identifier; -import net.minecraft.world.World; import org.slf4j.Logger; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -71,9 +69,8 @@ public abstract class ClientPlayNetworkHandlerMixin { MythologicalRitual.onParticle(packet); } - @WrapOperation(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;")) - private Entity skyblocker$onEntityDeath(EntityStatusS2CPacket packet, World world, Operation original) { - Entity entity = original.call(packet, world); + @ModifyExpressionValue(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;")) + private Entity skyblocker$onEntityDeath(Entity entity, @Local EntityStatusS2CPacket packet) { if (packet.getStatus() == EntityStatuses.PLAY_DEATH_SOUND_OR_ADD_PROJECTILE_HIT_PARTICLES) DungeonScore.handleEntityDeath(entity); return entity; } -- cgit From c0358d05116de2a90eee72ea64177a336a2cfbf3 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:45:35 +0300 Subject: Changed Score text into a translatable and fixed score going off screen borders Cleaned up the formatScore method to make sure all scores and letter rankings are equally wide, thereby making the text not move as score changes or go off screen borders when the location is set on a narrower score and a wider score is to be displayed. --- .../skyblock/dungeon/DungeonMapConfigScreen.java | 4 ++-- .../skyblock/dungeon/DungeonScoreHUD.java | 21 ++++++++++++++------- .../resources/assets/skyblocker/lang/en_us.json | 1 + 3 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java index b832f12d..0f42c495 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java @@ -40,7 +40,7 @@ public class DungeonMapConfigScreen extends Screen { public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { int mapSize = (int) (128 * SkyblockerConfigManager.get().locations.dungeons.mapScaling); float scoreScaling = SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreScaling; - int scoreWidth = (int) (textRenderer.getWidth("Score: 300 (S+)") * scoreScaling); + int scoreWidth = (int) (textRenderer.getWidth(DungeonScoreHUD.getFormattedScoreText()) * scoreScaling); int scoreHeight = (int) (textRenderer.fontHeight * scoreScaling); if (RenderHelper.pointIsInArea(mouseX, mouseY, mapX, mapY, mapX + mapSize, mapY + mapSize) && button == 0) { mapX = (int) Math.max(Math.min(mouseX - (mapSize >> 1), this.width - mapSize), 0); @@ -57,7 +57,7 @@ public class DungeonMapConfigScreen extends Screen { if (button == 1) { mapX = 2; mapY = 2; - scoreX = Math.max((int) ((mapX + (64 * SkyblockerConfigManager.get().locations.dungeons.mapScaling)) - textRenderer.getWidth("Score: 300 (S+)") * SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreScaling / 2), 0); + scoreX = Math.max((int) ((mapX + (64 * SkyblockerConfigManager.get().locations.dungeons.mapScaling)) - textRenderer.getWidth(DungeonScoreHUD.getFormattedScoreText()) * SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreScaling / 2), 0); scoreY = (int) (mapY + (128 * SkyblockerConfigManager.get().locations.dungeons.mapScaling) + 4); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java index eedbf020..1dfb1b95 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScoreHUD.java @@ -11,6 +11,9 @@ public class DungeonScoreHUD { private DungeonScoreHUD() { } + //This is 4+5 wide, needed to offset the extra width from bold numbers (3×1 wide) in S+ and the "+" (6 wide) so that it doesn't go off the screen if the score is S+ and the hud element is at the right edge of the screen + private static final Text extraSpace = Text.literal(" ").append(Text.literal(" ").formatted(Formatting.BOLD)); + public static void render(DrawContext context) { int x = SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreX; int y = SkyblockerConfigManager.get().locations.dungeons.dungeonScore.scoreY; @@ -22,16 +25,20 @@ public class DungeonScoreHUD { MatrixStack matrixStack = context.getMatrices(); matrixStack.push(); matrixStack.scale(scale, scale, 0); - context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, Text.literal("Score: ").append(formatScore(DungeonScore.getScore())), (int) (x / scale), (int) (y / scale), 0xFFFFFFFF); + context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, getFormattedScoreText(), (int) (x / scale), (int) (y / scale), 0xFFFFFFFF); matrixStack.pop(); } + public static Text getFormattedScoreText() { + return Text.translatable("skyblocker.dungeons.dungeonScore.scoreText", formatScore(DungeonScore.getScore())); + } + private static Text formatScore(int score) { - if (score < 100) return Text.literal(String.format("%03d", score)).withColor(0xDC1A1A).append(Text.literal(" (D) ").formatted(Formatting.GRAY)); - if (score < 160) return Text.literal(String.format("%03d", score)).withColor(0x4141FF).append(Text.literal(" (C) ").formatted(Formatting.GRAY)); - if (score < 230) return Text.literal(String.format("%03d", score)).withColor(0x7FCC19).append(Text.literal(" (B) ").formatted(Formatting.GRAY)); - if (score < 270) return Text.literal(String.format("%03d", score)).withColor(0x7F3FB2).append(Text.literal(" (A) ").formatted(Formatting.GRAY)); - if (score < 300) return Text.literal(String.format("%03d", score)).withColor(0xF1E252).append(Text.literal(" (S) ").formatted(Formatting.GRAY)); - return Text.literal(String.format("%03d", score)).withColor(0xF1E252).formatted(Formatting.BOLD).append(Text.literal(" (S+)").formatted(Formatting.GRAY)); + if (score < 100) return Text.literal(String.format("%03d", score)).withColor(0xDC1A1A).append(Text.literal(" (D)").formatted(Formatting.GRAY)).append(extraSpace); + if (score < 160) return Text.literal(String.format("%03d", score)).withColor(0x4141FF).append(Text.literal(" (C)").formatted(Formatting.GRAY)).append(extraSpace); + if (score < 230) return Text.literal(String.format("%03d", score)).withColor(0x7FCC19).append(Text.literal(" (B)").formatted(Formatting.GRAY)).append(extraSpace); + if (score < 270) return Text.literal(String.format("%03d", score)).withColor(0x7F3FB2).append(Text.literal(" (A)").formatted(Formatting.GRAY)).append(extraSpace); + if (score < 300) return Text.literal(String.format("%03d", score)).withColor(0xF1E252).append(Text.literal(" (S)").formatted(Formatting.GRAY)).append(extraSpace); + return Text.literal("").append(Text.literal(String.format("%03d", score)).withColor(0xF1E252).formatted(Formatting.BOLD)).append(Text.literal(" (S+)").formatted(Formatting.GRAY)); } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index c151c77b..38b14170 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -340,6 +340,7 @@ "skyblocker.dungeons.secrets.customWaypointAdded": "§rAdded a custom waypoint at X: %d, Y: %d, Z: %d for room %s secret #%d of category %s with name '%s'.", "skyblocker.dungeons.secrets.customWaypointRemoved": "§rRemoved custom waypoint at X: %d, Y: %d, Z: %d for room %s secret #%d of category %s with name '%s'.", "skyblocker.dungeons.secrets.customWaypointNotFound": "§cNo custom waypoint found at X: %d, Y: %d, Z: %d for room %s.", + "skyblocker.dungeons.dungeonScore.scoreText": "Score: %s", "skyblocker.dungeons.secretsTracker.feedback": "%s§f found %s§f secrets. %s", "skyblocker.dungeons.secretsTracker.failFeedback": "§cUnable to calculate the amount of secrets everybody did this run!", -- cgit From de4c4e1de62ec95cf4563f597a58c0ce02629042 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Fri, 19 Jan 2024 17:57:00 +0300 Subject: Fix mimic floors pattern regex There was a lingering ] that broke the whole mimic thing, and I spent 2 hours trying to figure out why... --- src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index 48a87c36..187ef43b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -49,7 +49,7 @@ public class DungeonScore { //Chat patterns private static final Pattern DEATHS_PATTERN = Pattern.compile(".*?\u2620 (?\\S+) .*"); //Other patterns - private static final Pattern MIMIC_FLOORS_PATTERN = Pattern.compile("[FM][67]]"); + private static final Pattern MIMIC_FLOORS_PATTERN = Pattern.compile("[FM][67]"); private static FloorRequirement floorRequirement; private static String currentFloor; -- cgit From cf55639859eda114efce3e91f762a534d0076b17 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Fri, 19 Jan 2024 18:16:38 +0300 Subject: Improve mimic filter regex and refactor some code --- .../de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java | 11 ++++++----- .../de/hysky/skyblocker/skyblock/filters/MimicFilter.java | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index 187ef43b..4dfbf62a 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -189,11 +189,7 @@ public class DungeonScore { } public static boolean isEntityMimic(Entity entity) { - if (!Utils.isInDungeons()) return false; - if (!floorHasMimics) return false; - if (entity == null) return false; - if (!(entity instanceof ZombieEntity zombie)) return false; - if (!zombie.isBaby()) return false; + if (!Utils.isInDungeons() || !floorHasMimics || !(entity instanceof ZombieEntity zombie) || !zombie.isBaby()) return false; try { DefaultedList armor = (DefaultedList) zombie.getArmorItems(); return armor.stream().allMatch(ItemStack::isEmpty); @@ -348,6 +344,11 @@ public class DungeonScore { return dungeonStarted; } + //Feel free to refactor this if you can think of a better name. + public static boolean isMimicOnCurrentFloor() { + return floorHasMimics; + } + enum FloorRequirement { E(30, 1200), F1(30, 600), diff --git a/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java b/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java index 51482794..31f83187 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java @@ -11,7 +11,7 @@ import java.util.regex.Matcher; public class MimicFilter extends ChatPatternListener { public MimicFilter() { - super("(?:Mimic dead!?|Mimic Killed!|\\$SKYTILS-DUNGEON-SCORE-MIMIC\\$|\\Q" + SkyblockerConfigManager.get().locations.dungeons.mimicMessages.mimicMessage + "\\E)$"); + super(".*?(?:Mimic dead!?|Mimic Killed!|\\$SKYTILS-DUNGEON-SCORE-MIMIC\\$|\\Q" + SkyblockerConfigManager.get().locations.dungeons.mimicMessages.mimicMessage + "\\E)$"); } @Override @@ -21,7 +21,7 @@ public class MimicFilter extends ChatPatternListener { @Override protected boolean onMatch(Text message, Matcher matcher) { - if (!Utils.isInDungeons()) return false; + if (!Utils.isInDungeons() || !DungeonScore.isDungeonStarted() || !DungeonScore.isMimicOnCurrentFloor()) return false; DungeonScore.setMimicKilled(true); return true; } -- cgit From 044f700a3c5c1a54eb39b2210f5dfdf18f528d7b Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Fri, 19 Jan 2024 19:03:20 +0300 Subject: Add a description for score config --- .../java/de/hysky/skyblocker/config/categories/DungeonsCategory.java | 1 + src/main/resources/assets/skyblocker/lang/en_us.json | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index d939a4f0..9c311471 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -317,6 +317,7 @@ public class DungeonsCategory { .build()) .option(Option.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.@Tooltip"), Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.deathMessagesNote"))) .binding(defaults.locations.dungeons.dungeonScore.enableScoreHUD, () -> config.locations.dungeons.dungeonScore.enableScoreHUD, newValue -> config.locations.dungeons.dungeonScore.enableScoreHUD = newValue) diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 38b14170..c38cc7ff 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -201,6 +201,8 @@ "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.dungeonScoreMessage": "Dungeon Score %d Message", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.dungeonScoreMessage.@Tooltip": "Message which will be sent in the chat when reaching %d score in dungeons. The string \"[score]\" will be replaced with the dungeon score (%d).", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD": "Enable Score HUD", + "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.@Tooltip": "Displays the dungeon score in the HUD.", + "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.deathMessagesNote": "\n\n\nNote: This only works correctly if death messages are enabled in your skyblock settings.", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.scoreScaling": "Score Scaling", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit": "Dungeon Chest Profit Calculator", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit.enableProfitCalculator": "Enable Profit Calculator", -- cgit From f7f8e5f0b8f9d638566e8528e1a64219b8bf40ad Mon Sep 17 00:00:00 2001 From: Aaron <51387595+AzureAaron@users.noreply.github.com> Date: Fri, 19 Jan 2024 23:31:31 -0500 Subject: Small changes --- .../de/hysky/skyblocker/config/categories/DungeonsCategory.java | 2 +- .../de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java | 2 +- .../java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java | 6 +++--- src/main/java/de/hysky/skyblocker/utils/Utils.java | 2 +- src/main/resources/assets/skyblocker/lang/en_us.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index 9c311471..1d8a7e8c 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -317,7 +317,7 @@ public class DungeonsCategory { .build()) .option(Option.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD")) - .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.@Tooltip"), Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.deathMessagesNote"))) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.@Tooltip"), Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.deathMessagesNote"))) .binding(defaults.locations.dungeons.dungeonScore.enableScoreHUD, () -> config.locations.dungeons.dungeonScore.enableScoreHUD, newValue -> config.locations.dungeons.dungeonScore.enableScoreHUD = newValue) diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java index e1eb6a2d..a8537088 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java @@ -70,7 +70,7 @@ public abstract class ClientPlayNetworkHandlerMixin { } @ModifyExpressionValue(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;")) - private Entity skyblocker$onEntityDeath(Entity entity, @Local EntityStatusS2CPacket packet) { + private Entity skyblocker$onEntityDeath(Entity entity, @Local(argsOnly = true) EntityStatusS2CPacket packet) { if (packet.getStatus() == EntityStatuses.PLAY_DEATH_SOUND_OR_ADD_PROJECTILE_HIT_PARTICLES) DungeonScore.handleEntityDeath(entity); return entity; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index 4dfbf62a..c6dbf8dc 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -193,8 +193,8 @@ public class DungeonScore { try { DefaultedList armor = (DefaultedList) zombie.getArmorItems(); return armor.stream().allMatch(ItemStack::isEmpty); - } catch (Exception f) { - LOGGER.error("[Skyblocker] Failed to check if entity is a mimic! Cause: {}", f.getMessage()); + } catch (Exception e) { + LOGGER.error("[Skyblocker] Failed to check if entity is a mimic!", e); return false; } } @@ -297,7 +297,7 @@ public class DungeonScore { return true; } } catch (Exception e) { - LOGGER.error("[Skyblocker] Spirit pet lookup by name failed! Name: {} - Cause: {}", name, e.getMessage()); + LOGGER.error("[Skyblocker] Spirit pet lookup by name failed! Name: {}", name, e); } return false; }); diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java index eaa07ff2..53c0ff4a 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Utils.java +++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java @@ -403,7 +403,7 @@ public class Utils { if (json.get("success").getAsBoolean()) return json.get("mayor").getAsJsonObject().get("name").getAsString(); throw new IOException(json.get("cause").getAsString()); } catch (Exception e) { - LOGGER.error("[Skyblocker] Failed to get mayor status! Cause: {}", e.getMessage()); + LOGGER.error("[Skyblocker] Failed to get mayor status!", e); } return ""; }).thenAccept(s -> { diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index c38cc7ff..3381e67a 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -202,7 +202,7 @@ "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.dungeonScoreMessage.@Tooltip": "Message which will be sent in the chat when reaching %d score in dungeons. The string \"[score]\" will be replaced with the dungeon score (%d).", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD": "Enable Score HUD", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.@Tooltip": "Displays the dungeon score in the HUD.", - "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.deathMessagesNote": "\n\n\nNote: This only works correctly if death messages are enabled in your skyblock settings.", + "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.deathMessagesNote": "\n\n\nNote: This only works correctly if death messages are enabled in your skyblock settings.", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.scoreScaling": "Score Scaling", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit": "Dungeon Chest Profit Calculator", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit.enableProfitCalculator": "Enable Profit Calculator", -- cgit From b1bfa5e0009b2a969c913e701a56b812517a0700 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sat, 20 Jan 2024 13:25:04 +0300 Subject: Add death message filter and improve death regex --- .../hysky/skyblocker/config/SkyblockerConfig.java | 3 +++ .../config/categories/MessageFilterCategory.java | 8 +++++++ .../skyblocker/skyblock/dungeon/DungeonScore.java | 6 +++++- .../skyblocker/skyblock/filters/DeathFilter.java | 25 ++++++++++++++++++++++ .../skyblocker/utils/chat/ChatMessageListener.java | 3 ++- .../resources/assets/skyblocker/lang/en_us.json | 4 +++- 6 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/filters/DeathFilter.java (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index e47b008d..4e7f9802 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -995,6 +995,9 @@ public class SkyblockerConfig { @SerialEntry public ChatFilterResult hideMimicKill = ChatFilterResult.PASS; + @SerialEntry + public ChatFilterResult hideDeath = ChatFilterResult.PASS; + @SerialEntry public boolean hideMana = false; } diff --git a/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java index 3fe285de..ce349049 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java @@ -110,6 +110,14 @@ public class MessageFilterCategory { newValue -> config.messages.hideMimicKill = newValue) .controller(ConfigUtils::createEnumCyclingListController) .build()) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.messages.hideDeath")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.messages.hideDeath.@Tooltip"))) + .binding(defaults.messages.hideDeath, + () -> config.messages.hideDeath, + newValue -> config.messages.hideDeath = newValue) + .controller(ConfigUtils::createEnumCyclingListController) + .build()) .build(); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index c6dbf8dc..a59d5615 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -47,7 +47,7 @@ public class DungeonScore { private static final Pattern CRYPTS_PATTERN = Pattern.compile("Crypts: (?\\d+)"); private static final Pattern COMPLETED_ROOMS_PATTERN = Pattern.compile(" *Completed Rooms: (?\\d+)"); //Chat patterns - private static final Pattern DEATHS_PATTERN = Pattern.compile(".*?\u2620 (?\\S+) .*"); + private static final Pattern DEATHS_PATTERN = Pattern.compile(" \\u2620 (?\\S+) .*"); //Other patterns private static final Pattern MIMIC_FLOORS_PATTERN = Pattern.compile("[FM][67]"); @@ -82,6 +82,10 @@ public class DungeonScore { checkMessageForWatcher(str); } }); + ClientReceiveMessageEvents.GAME_CANCELED.register((message, overlay) -> { + if (overlay || !Utils.isInDungeons() || !dungeonStarted) return; + checkMessageForDeaths(message.getString()); + }); } public static void tick() { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/filters/DeathFilter.java b/src/main/java/de/hysky/skyblocker/skyblock/filters/DeathFilter.java new file mode 100644 index 00000000..f2b9e7c5 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/filters/DeathFilter.java @@ -0,0 +1,25 @@ +package de.hysky.skyblocker.skyblock.filters; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.chat.ChatFilterResult; +import de.hysky.skyblocker.utils.chat.ChatPatternListener; +import net.minecraft.text.Text; + +import java.util.regex.Matcher; + +public class DeathFilter extends ChatPatternListener { + + public DeathFilter() { + super(" \\u2620 .*"); + } + + @Override + protected ChatFilterResult state() { + return SkyblockerConfigManager.get().messages.hideDeath; + } + + @Override + protected boolean onMatch(Text message, Matcher matcher) { + return true; + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java index 97398625..ee43bc4c 100644 --- a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java +++ b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java @@ -55,7 +55,8 @@ public interface ChatMessageListener { new AutopetFilter(), new ShowOffFilter(), new ToggleSkyMallFilter(), - new MimicFilter() + new MimicFilter(), + new DeathFilter() }; // Register all listeners to EVENT for (ChatMessageListener listener : listeners) { diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 3381e67a..91354ae7 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -202,7 +202,7 @@ "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.dungeonScoreMessage.@Tooltip": "Message which will be sent in the chat when reaching %d score in dungeons. The string \"[score]\" will be replaced with the dungeon score (%d).", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD": "Enable Score HUD", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.@Tooltip": "Displays the dungeon score in the HUD.", - "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.deathMessagesNote": "\n\n\nNote: This only works correctly if death messages are enabled in your skyblock settings.", + "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.deathMessagesNote": "\n\n\nNote: This only works correctly if death messages are enabled in your skyblock settings. If you want to hide death messages, use this mod's Hide Player Death Messages setting instead to allow further processing of death messages.", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.scoreScaling": "Score Scaling", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit": "Dungeon Chest Profit Calculator", "text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit.enableProfitCalculator": "Enable Profit Calculator", @@ -305,6 +305,8 @@ "text.autoconfig.skyblocker.option.messages.hideToggleSkyMall.@Tooltip": "Hides those pesky messages telling you to disable the Sky Mall HOTM perk when you want it enabled!", "text.autoconfig.skyblocker.option.messages.hideMimicKill": "Hide Mimic Kill Messages", "text.autoconfig.skyblocker.option.messages.hideMimicKill.@Tooltip": "Filters the \"Mimic dead!\" and \"Mimic killed!\" messages from chat.", + "text.autoconfig.skyblocker.option.messages.hideDeath": "Hide Player Death Messages", + "text.autoconfig.skyblocker.option.messages.hideDeath.@Tooltip": "Filters the player death messages from chat.", "text.autoconfig.skyblocker.category.slayer": "Slayers", "text.autoconfig.skyblocker.option.slayer.vampireSlayer": "Vampire Slayer", "text.autoconfig.skyblocker.option.slayer.vampireSlayer.enableEffigyWaypoints": "Enable Effigy Waypoints", -- cgit From ac6ac5096bf60c39ddf52bad41a6123afa51b097 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sat, 20 Jan 2024 18:31:06 +0300 Subject: Singularize MimicMessages --- .../hysky/skyblocker/config/SkyblockerConfig.java | 6 +++--- .../config/categories/DungeonsCategory.java | 22 +++++++++++----------- .../skyblocker/skyblock/dungeon/DungeonScore.java | 4 ++-- .../skyblocker/skyblock/filters/MimicFilter.java | 2 +- .../resources/assets/skyblocker/lang/en_us.json | 10 +++++----- 5 files changed, 22 insertions(+), 22 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 4e7f9802..9477fbed 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -606,7 +606,7 @@ public class SkyblockerConfig { public DungeonChestProfit dungeonChestProfit = new DungeonChestProfit(); @SerialEntry - public MimicMessages mimicMessages = new MimicMessages(); + public MimicMessage mimicMessage = new MimicMessage(); @SerialEntry public boolean croesusHelper = true; @@ -800,9 +800,9 @@ public class SkyblockerConfig { public Formatting incompleteColor = Formatting.BLUE; } - public static class MimicMessages { + public static class MimicMessage { @SerialEntry - public boolean sendMimicMessages = true; + public boolean sendMimicMessage = true; @SerialEntry public String mimicMessage = "Mimic dead!"; diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index 1d8a7e8c..c39eb05c 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -434,22 +434,22 @@ public class DungeonsCategory { .build()) //Mimic Messages .group(OptionGroup.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages")) + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage")) .collapsed(true) .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.sendMimicMessages")) - .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.sendMimicMessages.@Tooltip"))) - .binding(defaults.locations.dungeons.mimicMessages.sendMimicMessages, - () -> config.locations.dungeons.mimicMessages.sendMimicMessages, - newValue -> config.locations.dungeons.mimicMessages.sendMimicMessages = newValue) + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage.sendMimicMessage")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage.sendMimicMessage.@Tooltip"))) + .binding(defaults.locations.dungeons.mimicMessage.sendMimicMessage, + () -> config.locations.dungeons.mimicMessage.sendMimicMessage, + newValue -> config.locations.dungeons.mimicMessage.sendMimicMessage = newValue) .controller(ConfigUtils::createBooleanController) .build()) .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.mimicMessage")) - .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.mimicMessage.@Tooltip"))) - .binding(defaults.locations.dungeons.mimicMessages.mimicMessage, - () -> config.locations.dungeons.mimicMessages.mimicMessage, - newValue -> config.locations.dungeons.mimicMessages.mimicMessage = newValue) + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage.mimicMessage")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage.mimicMessage.@Tooltip"))) + .binding(defaults.locations.dungeons.mimicMessage.mimicMessage, + () -> config.locations.dungeons.mimicMessage.mimicMessage, + newValue -> config.locations.dungeons.mimicMessage.mimicMessage = newValue) .controller(StringControllerBuilder::create) .build()) .build()) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index a59d5615..cb834e7f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -35,7 +35,7 @@ import java.util.stream.StreamSupport; public class DungeonScore { private static final SkyblockerConfig.DungeonScore SCORE_CONFIG = SkyblockerConfigManager.get().locations.dungeons.dungeonScore; - private static final SkyblockerConfig.MimicMessages MIMIC_MESSAGES_CONFIG = SkyblockerConfigManager.get().locations.dungeons.mimicMessages; + private static final SkyblockerConfig.MimicMessage MIMIC_MESSAGE_CONFIG = SkyblockerConfigManager.get().locations.dungeons.mimicMessage; private static final Logger LOGGER = LoggerFactory.getLogger("Skyblocker Dungeon Score"); //Scoreboard patterns private static final Pattern CLEARED_PATTERN = Pattern.compile("Cleared: (?\\d+)%.*"); @@ -206,7 +206,7 @@ public class DungeonScore { public static void handleEntityDeath(Entity entity) { if (mimicKilled) return; if (!isEntityMimic(entity)) return; - if (MIMIC_MESSAGES_CONFIG.sendMimicMessages) MessageScheduler.INSTANCE.sendMessageAfterCooldown(MIMIC_MESSAGES_CONFIG.mimicMessage); + if (MIMIC_MESSAGE_CONFIG.sendMimicMessage) MessageScheduler.INSTANCE.sendMessageAfterCooldown(MIMIC_MESSAGE_CONFIG.mimicMessage); mimicKilled = true; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java b/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java index 31f83187..367e393c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java @@ -11,7 +11,7 @@ import java.util.regex.Matcher; public class MimicFilter extends ChatPatternListener { public MimicFilter() { - super(".*?(?:Mimic dead!?|Mimic Killed!|\\$SKYTILS-DUNGEON-SCORE-MIMIC\\$|\\Q" + SkyblockerConfigManager.get().locations.dungeons.mimicMessages.mimicMessage + "\\E)$"); + super(".*?(?:Mimic dead!?|Mimic Killed!|\\$SKYTILS-DUNGEON-SCORE-MIMIC\\$|\\Q" + SkyblockerConfigManager.get().locations.dungeons.mimicMessage.mimicMessage + "\\E)$"); } @Override diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 91354ae7..1360f5f1 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -235,11 +235,11 @@ "text.autoconfig.skyblocker.option.locations.dungeons.solveTicTacToe.@Tooltip": "Puts a red box around the next best move for you to make!", "text.autoconfig.skyblocker.option.locations.dungeons.solveWaterboard": "Solve Waterboard Puzzle", "text.autoconfig.skyblocker.option.locations.dungeons.solveWaterboard.@Tooltip": "Click the levers with green boxes to solve the puzzle.", - "text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages": "Mimic Messages", - "text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.sendMimicMessages": "Enable Mimic Messages", - "text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.sendMimicMessages.@Tooltip": "Sends a message in chat when a mimic is killed for score calculation mods.", - "text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.mimicMessage": "Mimic Message", - "text.autoconfig.skyblocker.option.locations.dungeons.mimicMessages.mimicMessage.@Tooltip": "Message which will be sent in the chat when a mimic is killed. Recommended to keep as \"Mimic dead!\"", + "text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage": "Mimic Message", + "text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage.sendMimicMessage": "Enable Mimic Message", + "text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage.sendMimicMessage.@Tooltip": "Sends a message in chat upon killing a mimic for other players' score calculation mods.", + "text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage.mimicMessage": "Mimic Message", + "text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage.mimicMessage.@Tooltip": "Message which will be sent in the chat upon killing a mimic. Recommended to retain the default value.", "text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Livid Color", "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow": "Enable Livid Color Glow", "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow.@Tooltip": "Applies the glowing effect to the correct Livid in F5/M5.", -- cgit From 4fd8d4f727ce611eb28218e6a47080894a78b7b1 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sat, 20 Jan 2024 18:57:08 +0300 Subject: Fix mimic messages not increasing score when mimic filter is disabled --- .../de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java | 11 +++++++++-- .../de/hysky/skyblocker/skyblock/filters/MimicFilter.java | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index cb834e7f..10605d8b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -48,6 +48,7 @@ public class DungeonScore { private static final Pattern COMPLETED_ROOMS_PATTERN = Pattern.compile(" *Completed Rooms: (?\\d+)"); //Chat patterns private static final Pattern DEATHS_PATTERN = Pattern.compile(" \\u2620 (?\\S+) .*"); + private static final Pattern MIMIC_PATTERN = Pattern.compile(".*?(?:Mimic dead!?|Mimic Killed!|\\$SKYTILS-DUNGEON-SCORE-MIMIC\\$|\\Q" + MIMIC_MESSAGE_CONFIG.mimicMessage + "\\E)$"); //Other patterns private static final Pattern MIMIC_FLOORS_PATTERN = Pattern.compile("[FM][67]"); @@ -80,6 +81,7 @@ public class DungeonScore { } else { checkMessageForDeaths(str); checkMessageForWatcher(str); + if (floorHasMimics) checkMessageForMimic(str); //Only called when the message is not cancelled & isn't on the action bar, complementing MimicFilter } }); ClientReceiveMessageEvents.GAME_CANCELED.register((message, overlay) -> { @@ -210,8 +212,8 @@ public class DungeonScore { mimicKilled = true; } - public static void setMimicKilled(boolean state) { - mimicKilled = state; + public static void onMimicKill() { + mimicKilled = true; } //This is not very accurate at the beginning of the dungeon since clear percentage is rounded to the closest integer, so at lower percentages its effect on the result is quite high. @@ -330,6 +332,11 @@ public class DungeonScore { onDungeonStart(); } + private static void checkMessageForMimic(String message) { + if (!MIMIC_PATTERN.matcher(message).matches()) return; + onMimicKill(); + } + public static void setCurrentFloor() { for (String sidebarLine : Utils.STRING_SCOREBOARD) { Matcher floorMatcher = FLOOR_PATTERN.matcher(sidebarLine); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java b/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java index 367e393c..cb845254 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/filters/MimicFilter.java @@ -22,7 +22,7 @@ public class MimicFilter extends ChatPatternListener { @Override protected boolean onMatch(Text message, Matcher matcher) { if (!Utils.isInDungeons() || !DungeonScore.isDungeonStarted() || !DungeonScore.isMimicOnCurrentFloor()) return false; - DungeonScore.setMimicKilled(true); + DungeonScore.onMimicKill(); //Only called when the message is cancelled | sent to action bar, complementing DungeonScore#checkMessageForMimic return true; } } -- cgit From 6120f55ac3161ebf4c0858ab674a5cbffa7879a9 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sat, 20 Jan 2024 19:09:17 +0300 Subject: Refactor score hud settings --- .../config/categories/DungeonsCategory.java | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index c39eb05c..6ec06e7a 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -230,6 +230,25 @@ public class DungeonsCategory { newValue -> config.locations.dungeons.dungeonScore.dungeonScore300Message = newValue) .controller(StringControllerBuilder::create) .build()) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.@Tooltip"), Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.deathMessagesNote"))) + .binding(defaults.locations.dungeons.dungeonScore.enableScoreHUD, + () -> config.locations.dungeons.dungeonScore.enableScoreHUD, + newValue -> config.locations.dungeons.dungeonScore.enableScoreHUD = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.scoreScaling")) + .binding(defaults.locations.dungeons.dungeonScore.scoreScaling, + () -> config.locations.dungeons.dungeonScore.scoreScaling, + newValue -> { + config.locations.dungeons.dungeonScore.scoreX = config.locations.dungeons.dungeonScore.scoreX + (int) ((config.locations.dungeons.dungeonScore.scoreScaling - newValue) * 38.0); + config.locations.dungeons.dungeonScore.scoreY = config.locations.dungeons.dungeonScore.scoreY + (int) ((config.locations.dungeons.dungeonScore.scoreScaling - newValue) * MinecraftClient.getInstance().textRenderer.fontHeight / 2.0); + config.locations.dungeons.dungeonScore.scoreScaling = newValue; + }) + .controller(FloatFieldControllerBuilder::create) + .build()) .build()) //Dungeon Chest Profit @@ -315,14 +334,6 @@ public class DungeonsCategory { newValue -> config.locations.dungeons.enableMap = newValue) .controller(ConfigUtils::createBooleanController) .build()) - .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD")) - .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.@Tooltip"), Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.enableScoreHUD.deathMessagesNote"))) - .binding(defaults.locations.dungeons.dungeonScore.enableScoreHUD, - () -> config.locations.dungeons.dungeonScore.enableScoreHUD, - newValue -> config.locations.dungeons.dungeonScore.enableScoreHUD = newValue) - .controller(ConfigUtils::createBooleanController) - .build()) .option(ButtonOption.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mapScreen")) .text(Text.translatable("text.skyblocker.open")) @@ -335,17 +346,6 @@ public class DungeonsCategory { newValue -> config.locations.dungeons.mapScaling = newValue) .controller(FloatFieldControllerBuilder::create) .build()) - .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonScore.scoreScaling")) - .binding(defaults.locations.dungeons.dungeonScore.scoreScaling, - () -> config.locations.dungeons.dungeonScore.scoreScaling, - newValue -> { - config.locations.dungeons.dungeonScore.scoreX = config.locations.dungeons.dungeonScore.scoreX + (int) ((config.locations.dungeons.dungeonScore.scoreScaling - newValue) * 38.0); - config.locations.dungeons.dungeonScore.scoreY = config.locations.dungeons.dungeonScore.scoreY + (int) ((config.locations.dungeons.dungeonScore.scoreScaling - newValue) * MinecraftClient.getInstance().textRenderer.fontHeight / 2.0); - config.locations.dungeons.dungeonScore.scoreScaling = newValue; - }) - .controller(FloatFieldControllerBuilder::create) - .build()) .option(Option.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker")) .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker.@Tooltip"))) -- cgit From 9bc2efcb66a3dbf0c0ab882ef05fdae551ab5912 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sun, 21 Jan 2024 09:45:02 +0300 Subject: Fix incorrect merge leftovers --- src/main/java/de/hysky/skyblocker/SkyblockerMod.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 4a2ff497..83f41c0b 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -110,7 +110,6 @@ public class SkyblockerMod implements ClientModInitializer { Waterboard.init(); DungeonScore.init(); PartyFinderScreen.initClass(); - DungeonScoreHUD.init(); ChestValue.init(); FireFreezeStaffTimer.init(); GuardianHealth.init(); -- cgit From cbf7f80faf78764f7787122be194e8d26e8b1f9e Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 21 Jan 2024 12:25:38 -0500 Subject: Fix DungeonsCategory --- .../java/de/hysky/skyblocker/config/categories/DungeonsCategory.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker') diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index 6ec06e7a..3b685f9a 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -432,7 +432,8 @@ public class DungeonsCategory { newValue -> config.locations.dungeons.allowDroppingProtectedItems = newValue) .controller(ConfigUtils::createBooleanController) .build()) - //Mimic Messages + + //Mimic Message .group(OptionGroup.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.mimicMessage")) .collapsed(true) @@ -454,7 +455,7 @@ public class DungeonsCategory { .build()) .build()) - // Livid Color + //Livid Color .group(OptionGroup.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor")) .collapsed(true) -- cgit