aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormartimavocado <39881008+martimavocado@users.noreply.github.com>2024-10-26 19:14:57 +0100
committerGitHub <noreply@github.com>2024-10-26 20:14:57 +0200
commit6b4f3a330869360b55a9f55fc0f9dc554e195feb (patch)
tree7594ae1e879c8aeaec4492c637d013a91a46dfc1
parent257640fdd4708356cebf8898d43e8ec4d7bd7351 (diff)
downloadSkyHanni-6b4f3a330869360b55a9f55fc0f9dc554e195feb.tar.gz
SkyHanni-6b4f3a330869360b55a9f55fc0f9dc554e195feb.tar.bz2
SkyHanni-6b4f3a330869360b55a9f55fc0f9dc554e195feb.zip
Fix: Great Spook mob cooldown and timer (#2804)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/EventsJson.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/spook/TheGreatSpook.kt188
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt16
4 files changed, 178 insertions, 40 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java
index 56a17dfb9..9f92436cf 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/DebugConfig.java
@@ -162,6 +162,11 @@ public class DebugConfig {
@ConfigEditorBoolean
public boolean alwaysHoppitys = false;
+ @Expose
+ @ConfigOption(name = "Always Great Spook", desc = "Assumes the Great Spook is always active.")
+ @ConfigEditorBoolean
+ public Property<Boolean> forceGreatSpook = Property.of(false);
+
// Does not have a config element!
@Expose
public Position trackSoundPosition = new Position(0, 0);
diff --git a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/EventsJson.kt b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/EventsJson.kt
new file mode 100644
index 000000000..cab8ae7fe
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/EventsJson.kt
@@ -0,0 +1,9 @@
+package at.hannibal2.skyhanni.data.jsonobjects.repo
+
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import com.google.gson.annotations.Expose
+import com.google.gson.annotations.SerializedName
+
+data class EventsJson(
+ @Expose @SerializedName("great_spook") val greatSpook: Map<String, SimpleTimeMark>,
+)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/spook/TheGreatSpook.kt b/src/main/java/at/hannibal2/skyhanni/features/event/spook/TheGreatSpook.kt
index 4e88237e0..9125f25a2 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/spook/TheGreatSpook.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/spook/TheGreatSpook.kt
@@ -1,84 +1,167 @@
package at.hannibal2.skyhanni.features.event.spook
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.jsonobjects.repo.EventsJson
import at.hannibal2.skyhanni.data.model.SkyblockStat
+import at.hannibal2.skyhanni.events.ConfigLoadEvent
+import at.hannibal2.skyhanni.events.DebugDataCollectEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.IslandChangeEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.events.SecondPassedEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.ChatUtils
+import at.hannibal2.skyhanni.utils.ConditionalUtils.afterChange
import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.HypixelCommands
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NEUCalculator
import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.RegexUtils.matches
+import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderable
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.SoundUtils
import at.hannibal2.skyhanni.utils.StringUtils
-import at.hannibal2.skyhanni.utils.TabListData
+import at.hannibal2.skyhanni.utils.TimeUnit
+import at.hannibal2.skyhanni.utils.TimeUtils.format
+import at.hannibal2.skyhanni.utils.renderables.Renderable
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration.Companion.minutes
+import kotlin.time.Duration.Companion.seconds
@SkyHanniModule
object TheGreatSpook {
-
- // §r§cPrimal Fears§r§7: §r§6§lREADY!!
private val config get() = SkyHanniMod.feature.event.spook
- private var displayTimer = ""
- private var displayTimeLeft = ""
- private var notificationSeconds = 0
+
+ private var isGreatSpookActive = false
+ private var greatSpookTimeRange: ClosedRange<SimpleTimeMark>? = null
+ private var greatSpookEndTime = SimpleTimeMark.farPast()
+
+ private var displayMobCooldown: Renderable? = null
+ private var displayGreatSpookEnd: Renderable? = null
+
+ private var timeUntilNextMob = SimpleTimeMark.farPast()
+
+ private val patternGroup = RepoPattern.group("event.greatspook")
+
+ /**
+ * REGEX-TEST: §d§lQUICK MATHS! §r§7Solve: §r§e(10*2)+12*5
+ */
+ private val mathFearMessagePattern by patternGroup.pattern(
+ "chat.math",
+ "§d§lQUICK MATHS! §r§7Solve: §r§e(?<math>.*)",
+ )
+
+ /**
+ * REGEX-TEST: §4[FEAR] Public Speaking Demon§r§f: Speak PlasticEating!
+ */
+ private val speakingFearMessagePattern by patternGroup.pattern(
+ "chat.speaking",
+ "§4\\[FEAR] Public Speaking Demon§r§f: (Speak|Say something interesting) (?<name>.*)!",
+ )
+
+ /**
+ * REGEX-TEST: §5§lFEAR. §r§eA §r§dPrimal Fear §r§ehas been summoned!
+ */
+ private val primalFearSpawnPattern by patternGroup.pattern(
+ "mob.spawn",
+ "§5§lFEAR\\. §r§eA §r§dPrimal Fear §r§ehas been summoned!",
+ )
@SubscribeEvent
fun onSecondPassed(event: SecondPassedEvent) {
if (!LorenzUtils.inSkyBlock) return
+ if (!isGreatSpookActive) return
+
+ val fear = SkyblockStat.FEAR.lastKnownValue ?: 0.0
+ val mobCooldown = timeUntilNextMob.minus((3 * fear).seconds)
+ val mobCooldownString = if (mobCooldown.isInFuture()) {
+ "§5Next fear in: §b${
+ mobCooldown.timeUntil().format(
+ biggestUnit = TimeUnit.MINUTE,
+ showMilliSeconds = false,
+ showSmallerUnits = false,
+ )
+ }"
+ } else {
+ "§5§lPrimal Fear Ready!"
+ }
+ displayMobCooldown = Renderable.string(mobCooldownString)
- if (config.primalFearTimer || config.primalFearNotification) displayTimer = checkTabList(" §r§cPrimal Fears§r§7: ")
- if (config.greatSpookTimeLeft) displayTimeLeft = checkTabList(" §r§dEnds In§r§7: ")
- if (config.primalFearNotification) {
- if (displayTimer.endsWith("READY!!")) {
- if (notificationSeconds > 0) {
- SoundUtils.playBeepSound()
- notificationSeconds--
+ if (config.primalFearNotification && mobCooldown.isInFuture()) {
+ SoundUtils.playPlingSound()
+ }
+
+ val greatSpookEnd = greatSpookTimeRange?.endInclusive ?: return
+ val timeLeftString = if (greatSpookEnd.isInFuture()) {
+ "§5Great Spook time left: §b${
+ greatSpookEnd.timeUntil().format(
+ biggestUnit = TimeUnit.DAY,
+ maxUnits = 2,
+ )
+ }"
+ } else {
+ "§5§lThe Great Spook has ended!"
+ }
+ displayGreatSpookEnd = Renderable.string(timeLeftString)
+ }
+
+ @SubscribeEvent
+ fun onConfigLoad(event: ConfigLoadEvent) {
+ val config = SkyHanniMod.feature.dev.debug.forceGreatSpook
+ config.afterChange {
+ if (config.get()) {
+ isGreatSpookActive = true
+ greatSpookEndTime = SimpleTimeMark.farFuture()
+ } else {
+ val timeRange = greatSpookTimeRange
+ if (timeRange == null) {
+ isGreatSpookActive = false
+ greatSpookEndTime = SimpleTimeMark.farPast()
+ return@afterChange
}
- } else if (displayTimer.isNotEmpty()) {
- notificationSeconds = 5
+ isGreatSpookActive = SimpleTimeMark.now() in timeRange
+ greatSpookEndTime = timeRange.endInclusive
}
}
}
- private fun checkTabList(matchString: String): String {
- return (TabListData.getTabList().find { it.contains(matchString) }.orEmpty()).trim()
+ @SubscribeEvent
+ fun onWorldSwitch(event: IslandChangeEvent) {
+ val currentTime = SimpleTimeMark.now()
+ val timeRange = greatSpookTimeRange ?: run {
+ isGreatSpookActive = false
+ return
+ }
+
+ isGreatSpookActive = currentTime in timeRange
}
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!LorenzUtils.inSkyBlock) return
+ if (!isGreatSpookActive) return
- if (config.primalFearTimer) config.positionTimer.renderString(displayTimer, posLabel = "Primal Fear Timer")
+ if (config.primalFearTimer) {
+ displayMobCooldown.let {
+ config.positionTimer.renderRenderable(it, posLabel = "Primal Fear Timer")
+ }
+ }
if (config.fearStatDisplay) {
SkyblockStat.FEAR.displayValue?.let {
config.positionFear.renderString(it, posLabel = "Fear Stat Display")
}
}
- if (config.greatSpookTimeLeft) config.positionTimeLeft.renderString(displayTimeLeft, posLabel = "Time Left Display")
+ if (config.greatSpookTimeLeft) {
+ displayGreatSpookEnd.let {
+ config.positionTimeLeft.renderRenderable(it, posLabel = "Great Spook Time Left")
+ }
+ }
}
- /**
- * REGEX-TEST: §d§lQUICK MATHS! §r§7Solve: §r§e(10*2)+12*5
- */
- private val mathFearMessagePattern by RepoPattern.pattern(
- "chat.math",
- "§d§lQUICK MATHS! §r§7Solve: §r§e(?<math>.*)",
- )
-
- /**
- * REGEX-TEST: §4[FEAR] Public Speaking Demon§r§f: Speak PlasticEating!
- */
- private val speakingFearMessagePattern by RepoPattern.pattern(
- "chat.speaking",
- "§4\\[FEAR] Public Speaking Demon§r§f: (Speak|Say something interesting) (?<name>.*)!",
- )
-
private fun mathSolver(query: String?) {
val answer = query?.let { NEUCalculator.calculateOrNull(it)?.toInt() } ?: run {
ChatUtils.userError("Failed to solve $query!")
@@ -108,6 +191,18 @@ object TheGreatSpook {
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
if (!LorenzUtils.inSkyBlock) return
+ if (!isGreatSpookActive) return
+
+ if (primalFearSpawnPattern.matches(event.message)) {
+ timeUntilNextMob = SimpleTimeMark.now().plus(6.minutes)
+ if (SkyblockStat.FEAR.lastKnownValue == null && (config.primalFearNotification || config.primalFearTimer)) {
+ ChatUtils.userError(
+ "Fear stat not found! Please enable the Stats widget and enable the Fear stat for the best results.",
+ replaceSameMessage = true,
+ )
+ }
+ return
+ }
if (config.primalFearSolver.math) {
mathFearMessagePattern.matchMatcher(event.message) {
@@ -125,4 +220,27 @@ object TheGreatSpook {
}
}
}
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ val data = event.getConstant<EventsJson>("Events").greatSpook
+
+ val startTime = data["start_time"] ?: SimpleTimeMark.farPast()
+ val endTime = data["end_time"] ?: SimpleTimeMark.farPast()
+
+ greatSpookTimeRange = startTime..endTime
+ greatSpookEndTime = if (SkyHanniMod.feature.dev.debug.forceGreatSpook.get()) SimpleTimeMark.farFuture() else endTime
+ }
+
+ @SubscribeEvent
+ fun onDebug(event: DebugDataCollectEvent) {
+ event.title("Great Spook")
+
+ event.addIrrelevant {
+ add("isActive: $isGreatSpookActive")
+ add("activeTimeRange: $greatSpookTimeRange")
+ add("eventEndTime: $greatSpookEndTime")
+ add("timeUntilNextMob: $timeUntilNextMob")
+ }
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt
index 1547e39b5..d48c8d8a7 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ChatUtils.kt
@@ -44,8 +44,11 @@ object ChatUtils {
*
* @see DEBUG_PREFIX
*/
- fun debug(message: String) {
- if (LorenzUtils.debug && internalChat(DEBUG_PREFIX + message)) {
+ fun debug(
+ message: String,
+ replaceSameMessage: Boolean = false,
+ ) {
+ if (LorenzUtils.debug && internalChat(DEBUG_PREFIX + message, replaceSameMessage)) {
LorenzUtils.consoleLog("[Debug] $message")
}
}
@@ -58,8 +61,11 @@ object ChatUtils {
*
* @see USER_ERROR_PREFIX
*/
- fun userError(message: String) {
- internalChat(USER_ERROR_PREFIX + message)
+ fun userError(
+ message: String,
+ replaceSameMessage: Boolean = false,
+ ) {
+ internalChat(USER_ERROR_PREFIX + message, replaceSameMessage)
}
/**
@@ -87,7 +93,7 @@ object ChatUtils {
private fun internalChat(
message: String,
- replaceSameMessage: Boolean = false,
+ replaceSameMessage: Boolean,
): Boolean {
val text = ChatComponentText(message)