From 47b1fdce5577204bfef7a34dfe25af7374909ef6 Mon Sep 17 00:00:00 2001 From: appable Date: Wed, 29 May 2024 23:56:36 -0700 Subject: Feature: mark duplicate egg locations (#1929) Co-authored-by: Cal Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> --- .../config/features/event/HoppityEggsConfig.java | 18 +++++++ .../config/storage/ProfileSpecificStorage.java | 5 ++ .../features/event/hoppity/HoppityEggLocator.kt | 57 ++++++++++++++-------- .../features/event/hoppity/HoppityEggsManager.kt | 18 +++++++ .../event/hoppity/HoppityUniqueEggLocations.kt | 40 +++++++++++++++ 5 files changed, 118 insertions(+), 20 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityUniqueEggLocations.kt (limited to 'src/main/java/at/hannibal2') diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/HoppityEggsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/HoppityEggsConfig.java index 345b3fb83..5361991e1 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/event/HoppityEggsConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/HoppityEggsConfig.java @@ -38,12 +38,30 @@ public class HoppityEggsConfig { @ConfigEditorBoolean public boolean showAllWaypoints = false; + @Expose + @ConfigOption(name = "Mark Duplicate Locations", desc = "Marks egg location waypoints which you have already found in red.") + @ConfigEditorBoolean + @FeatureToggle + public boolean highlightDuplicateEggLocations = false; + + @Expose + @ConfigOption(name = "Mark Nearby Duplicates", desc = "Always show duplicate egg locations when nearby.") + @ConfigEditorBoolean + @FeatureToggle + public boolean showNearbyDuplicateEggLocations = false; + @Expose @ConfigOption(name = "Show Unclaimed Eggs", desc = "Displays which eggs haven't been found in the last SkyBlock day.") @ConfigEditorBoolean @FeatureToggle public boolean showClaimedEggs = false; + @Expose + @ConfigOption(name = "Show Collected Locations", desc = "Shows the number of found egg locations on this island. §eThis is not retroactive and may not be fully synced with Hypixel's count.") + @ConfigEditorBoolean + @FeatureToggle + public boolean showCollectedLocationCount = false; + @Expose @ConfigOption(name = "Warn When Unclaimed", desc = "Warn when all three eggs are ready to be found.") @ConfigEditorBoolean diff --git a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java index e25d725ec..747d5c116 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.config.storage; import at.hannibal2.skyhanni.api.SkillAPI; +import at.hannibal2.skyhanni.data.IslandType; import at.hannibal2.skyhanni.data.MaxwellAPI; import at.hannibal2.skyhanni.data.model.ComposterUpgrade; import at.hannibal2.skyhanni.features.combat.endernodetracker.EnderNodeTracker; @@ -41,6 +42,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; public class ProfileSpecificStorage { @@ -128,6 +130,9 @@ public class ProfileSpecificStorage { @Expose public Map rabbitCounts = new HashMap(); + @Expose + public Map> collectedEggLocations = new HashMap(); + @Expose public Integer hoppityShopYearOpened = null; } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggLocator.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggLocator.kt index 012532f3b..6b1f60507 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggLocator.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggLocator.kt @@ -14,6 +14,7 @@ import at.hannibal2.skyhanni.features.inventory.chocolatefactory.ChocolateFactor import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.round @@ -21,6 +22,7 @@ import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName import at.hannibal2.skyhanni.utils.RecalculatingValue import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine +import at.hannibal2.skyhanni.utils.RenderUtils.drawColor import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText import at.hannibal2.skyhanni.utils.RenderUtils.exactPlayerEyeLocation import at.hannibal2.skyhanni.utils.SimpleTimeMark @@ -99,15 +101,10 @@ object HoppityEggLocator { } } } + if (drawLocations) { for ((index, eggLocation) in possibleEggLocations.withIndex()) { - val eggLabel = "§aGuess #${index + 1}" - event.drawWaypointFilled( - eggLocation, - LorenzColor.GREEN.toColor(), - seeThroughBlocks = true, - ) - event.drawDynamicText(eggLocation.add(y = 1), eggLabel, 1.5) + drawEggWaypoint(event, eggLocation, "§aGuess #${index + 1}") if (config.showLine) { event.draw3DLine(eyeLocation, eggLocation.add(0.5, 0.5, 0.5), LorenzColor.GREEN.toColor(), 2, false) } @@ -117,27 +114,47 @@ object HoppityEggLocator { sharedEggLocation?.let { if (config.sharedWaypoints) { - event.drawWaypointFilled(it, LorenzColor.GREEN.toColor(), seeThroughBlocks = true,) - event.drawDynamicText(it.add(y = 1), "§aShared Egg", 1.5) + drawEggWaypoint(event, it, "§aShared Egg") return } } - if (!config.showAllWaypoints) return - if (hasLocatorInHotbar()) return - if (!HoppityEggType.eggsRemaining()) return - val islandEggsLocations = getCurrentIslandEggLocations() ?: return - for (eggLocation in islandEggsLocations) { - event.drawWaypointFilled( - eggLocation, - LorenzColor.GREEN.toColor(), - seeThroughBlocks = true, - ) - event.drawDynamicText(eggLocation.add(y = 1), "§aEgg", 1.5) + + if (shouldShowAllEggs()) { + for (eggLocation in islandEggsLocations) { + drawEggWaypoint(event, eggLocation, "§aEgg") + } + return } + + if (config.highlightDuplicateEggLocations && config.showNearbyDuplicateEggLocations) { + for (eggLocation in islandEggsLocations) { + val dist = eggLocation.distanceToPlayer() + if (dist < 10 && HoppityUniqueEggLocations.hasCollectedEgg(eggLocation)) { + val alpha = ((10 - dist) / 10).coerceAtMost(0.5).toFloat() + event.drawColor(eggLocation, LorenzColor.RED, false, alpha) + event.drawDynamicText(eggLocation.add(y = 1), "§cDuplicate Location!", 1.5) + } + } + } + } + + private fun drawEggWaypoint(event: LorenzRenderWorldEvent, location: LorenzVec, label: String) { + val shouldMarkDuplicate = config.highlightDuplicateEggLocations + && HoppityUniqueEggLocations.hasCollectedEgg(location) + val possibleDuplicateLabel = if (shouldMarkDuplicate) "$label §c(Duplicate Location)" else label + if (!shouldMarkDuplicate) { + event.drawWaypointFilled(location, LorenzColor.GREEN.toColor(), seeThroughBlocks = true) + } else { + event.drawColor(location, LorenzColor.RED.toColor(), false, 0.5f) + } + event.drawDynamicText(location.add(y = 1), possibleDuplicateLabel, 1.5) } + private fun shouldShowAllEggs() = + config.showAllWaypoints && !hasLocatorInHotbar() && HoppityEggType.eggsRemaining() + fun eggFound() { resetData() } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt index c085fcf16..0660268db 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt @@ -108,6 +108,7 @@ object HoppityEggsManager { HoppityEggsCompactChat.handleChat(event) eggFoundPattern.matchMatcher(event.message) { + HoppityUniqueEggLocations.saveNearestEgg() HoppityEggLocator.eggFound() val meal = getEggType(event) val note = group("note").removeColor() @@ -188,11 +189,28 @@ object HoppityEggsManager { .map { "§7 - ${it.formattedName} ${it.timeUntil().format()}" } .toMutableList() displayList.add(0, "§bUnclaimed Eggs:") + + if (config.showCollectedLocationCount) { + val totalEggs = HoppityEggLocator.getCurrentIslandEggLocations()?.size + if (totalEggs != null) { + val collectedEggs = HoppityUniqueEggLocations.collectedEggsThisIsland() + val collectedFormat = formatEggsCollected(collectedEggs) + displayList.add("§7Locations: $collectedFormat$collectedEggs§7/§a$totalEggs") + } + } if (displayList.size == 1) return config.position.renderStrings(displayList, posLabel = "Hoppity Eggs") } + private fun formatEggsCollected(collectedEggs: Int): String = + when (collectedEggs) { + in 0 until 5 -> "§c" + in 5 until 10 -> "§6" + in 10 until 15 -> "§e" + else -> "§a" + } + @SubscribeEvent fun onSecondPassed(event: SecondPassedEvent) { if (!isActive()) return diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityUniqueEggLocations.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityUniqueEggLocations.kt new file mode 100644 index 000000000..161cff80e --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityUniqueEggLocations.kt @@ -0,0 +1,40 @@ +package at.hannibal2.skyhanni.features.event.hoppity + +import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.features.inventory.chocolatefactory.ChocolateFactoryAPI +import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.LocationUtils +import at.hannibal2.skyhanni.utils.LocationUtils.distanceSqToPlayer +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzVec + +object HoppityUniqueEggLocations { + + private val collectedEggLocations: MutableMap>? + get() = ChocolateFactoryAPI.profileStorage?.collectedEggLocations + + private fun getCurrentIslandCollectedEggs(): MutableSet? = + collectedEggLocations?.getOrPut(LorenzUtils.skyBlockIsland) { mutableSetOf() } + + fun saveNearestEgg() { + val location = HoppityEggLocator.getCurrentIslandEggLocations() + ?.minByOrNull { it.distanceSqToPlayer() } ?: return + if (location.distanceSqToPlayer() > 100) { + ErrorManager.skyHanniError( + "Player far from any known egg location!", + "island" to LorenzUtils.skyBlockIsland, + "distanceSqToPlayer" to location.distanceSqToPlayer(), + "playerLocation" to LocationUtils.playerLocation(), + "closestKnownEgg" to location, + ) + } + + getCurrentIslandCollectedEggs()?.add(location) + } + + fun collectedEggsThisIsland() = getCurrentIslandCollectedEggs()?.size ?: 0 + + fun hasCollectedEgg(location: LorenzVec) = + getCurrentIslandCollectedEggs()?.contains(location) ?: false + +} -- cgit