Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: mark duplicate egg locations #1929

Merged
merged 10 commits into from
May 30, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -41,6 +42,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ProfileSpecificStorage {

Expand Down Expand Up @@ -128,6 +130,9 @@ public static class PositionChange {
@Expose
public Map<String, Integer> rabbitCounts = new HashMap();

@Expose
public Map<IslandType, Set<LorenzVec>> collectedEggLocations = new HashMap();

@Expose
public Integer hoppityShopYearOpened = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ 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
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
Expand Down Expand Up @@ -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)
}
Expand All @@ -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()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down
appable0 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -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<IslandType, MutableSet<LorenzVec>>?
get() = ChocolateFactoryAPI.profileStorage?.collectedEggLocations

private fun getCurrentIslandCollectedEggs(): MutableSet<LorenzVec>? =
collectedEggLocations?.getOrPut(LorenzUtils.skyBlockIsland) { mutableSetOf<LorenzVec>() }

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

}
Loading