diff options
author | MTOnline69 <97001154+MTOnline69@users.noreply.github.com> | 2024-09-12 09:21:53 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-12 10:21:53 +0200 |
commit | 4e23db746f35965b84f8dd5be19b9883c67d8add (patch) | |
tree | 3df56c12f7e3766c33c64eb309136367e3009a42 /src/main/java/at/hannibal2/skyhanni/features | |
parent | 996b70464766ca017de65b85b0574b0ed6eccab4 (diff) | |
download | skyhanni-4e23db746f35965b84f8dd5be19b9883c67d8add.tar.gz skyhanni-4e23db746f35965b84f8dd5be19b9883c67d8add.tar.bz2 skyhanni-4e23db746f35965b84f8dd5be19b9883c67d8add.zip |
Feature: Broodmother alerts/messages and damage indicator support (#2325)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features')
5 files changed, 203 insertions, 5 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/BroodmotherFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/BroodmotherFeatures.kt new file mode 100644 index 000000000..e087fdd19 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/BroodmotherFeatures.kt @@ -0,0 +1,183 @@ +package at.hannibal2.skyhanni.features.combat + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.data.model.TabWidget +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent +import at.hannibal2.skyhanni.events.SecondPassedEvent +import at.hannibal2.skyhanni.events.WidgetUpdateEvent +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.ChatUtils +import at.hannibal2.skyhanni.utils.HypixelCommands +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland +import at.hannibal2.skyhanni.utils.RenderUtils.renderString +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.SoundUtils +import at.hannibal2.skyhanni.utils.SoundUtils.playSound +import at.hannibal2.skyhanni.utils.StringUtils +import at.hannibal2.skyhanni.utils.TimeUtils.format +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.reflect.KMutableProperty0 +import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds +import kotlin.time.DurationUnit + +@SkyHanniModule +object BroodmotherFeatures { + + enum class StageEntry(private val str: String, val minutes: Int) { + SLAIN("§eSlain", 10), + DORMANT("§eDormant", 9), + SOON("§6Soon", 6), + AWAKENING("§6Awakening", 3), + IMMINENT("§4Imminent", 1), + ALIVE("§4Alive!", 0); + + override fun toString() = str + } + + private val config get() = SkyHanniMod.feature.combat.broodmother + private val spawnAlertConfig get() = config.spawnAlert + + private var lastStage: StageEntry? = null + private var currentStage: StageEntry? = null + private var broodmotherSpawnTime = SimpleTimeMark.farPast() + private var display = "" + + @SubscribeEvent + fun onTabListUpdate(event: WidgetUpdateEvent) { + if (!event.isWidget(TabWidget.BROODMOTHER)) return + val newStage = event.widget.matchMatcherFirstLine { group("stage") } ?: "" + if (newStage.isNotEmpty()) { + lastStage = currentStage + currentStage = StageEntry.valueOf(newStage.replace("!", "").uppercase()) + onStageUpdate() + } + } + + private fun onStageUpdate() { + ChatUtils.debug("New Broodmother stage: $currentStage") + + if (lastStage == null) { + if (onServerJoin()) return + } + + // ignore Hypixel bug where the stage may temporarily revert to Imminent after the Broodmother's death + if (currentStage == StageEntry.IMMINENT && lastStage == StageEntry.ALIVE) return + + if (currentStage == StageEntry.ALIVE) { + onBroodmotherSpawn() + return + } + + val timeUntilSpawn = currentStage?.minutes?.minutes + broodmotherSpawnTime = SimpleTimeMark.now() + timeUntilSpawn!! + + if (currentStage == StageEntry.IMMINENT && config.imminentWarning) { + playImminentWarning() + return + } + + if (config.stages.contains(currentStage) && lastStage != null) { + if (currentStage == StageEntry.SLAIN) { + onBroodmotherSlain() + } else { + val pluralize = StringUtils.pluralize(timeUntilSpawn.toInt(DurationUnit.MINUTES), "minute") + ChatUtils.chat( + "Broodmother: $lastStage §e-> $currentStage§e. §b${timeUntilSpawn.inWholeMinutes} $pluralize §euntil it spawns!" + ) + } + } + } + + private fun onServerJoin(): Boolean { + // don't send if user has config enabled for either of the alive messages + // this is so that two messages aren't immediately sent upon joining a server + if (config.stageOnJoin && !(currentStage == StageEntry.ALIVE && isAliveMessageEnabled())) { + val pluralize = StringUtils.pluralize(currentStage?.minutes ?: 0, "minute") + var message = "The Broodmother's current stage in this server is ${currentStage.toString().replace("!", "")}§e." + if (currentStage?.minutes != 0) { + message += " It will spawn within §b${currentStage?.minutes} $pluralize§e." + } + ChatUtils.chat(message) + return true + } else { + return false + } + } + + private fun onBroodmotherSpawn() { + broodmotherSpawnTime = SimpleTimeMark.farPast() + if (!isAliveMessageEnabled()) return + val feature: KMutableProperty0<*> + if (config.alertOnSpawn) { + feature = config::alertOnSpawn + val alertSound = SoundUtils.createSound(spawnAlertConfig.alertSound, spawnAlertConfig.pitch) + SoundUtils.repeatSound(100, spawnAlertConfig.repeatSound, alertSound) + LorenzUtils.sendTitle(spawnAlertConfig.text.replace("&", "§"), 3.seconds) + } else { + feature = config::stages + } + ChatUtils.clickToActionOrDisable( + "The Broodmother has spawned!", + feature, + actionName = "warp to the Top of the Nest", + action = { HypixelCommands.warp("nest") }, + ) + } + + private fun playImminentWarning() { + SoundUtils.repeatSound(100, 2, SoundUtils.createSound("note.pling", 0.5f)) + ChatUtils.chat("The Broodmother is §4Imminent§e! It will spawn in §b60 seconds§e!") + } + + private fun onBroodmotherSlain() { + broodmotherSpawnTime = SimpleTimeMark.now() + 10.minutes + if (!(config.hideSlainWhenNearby && SpidersDenAPI.isAtTopOfNest())) { + ChatUtils.chat("The Broodmother was killed!") + } + } + + @SubscribeEvent + fun onWorldChange(event: LorenzWorldChangeEvent) { + broodmotherSpawnTime = SimpleTimeMark.farPast() + lastStage = null + currentStage = null + display = "" + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { + if (!isCountdownEnabled()) return + if (display.isEmpty()) return + + config.countdownPosition.renderString(display, posLabel = "Broodmother Countdown") + } + + @SubscribeEvent + fun onSecondPassed(event: SecondPassedEvent) { + if (!isCountdownEnabled()) return + + if (broodmotherSpawnTime.isFarPast()) { + if (lastStage != null) { + display = "§4Broodmother spawned!" + } + } else { + val countdown = broodmotherSpawnTime.timeUntil().format() + display = "§4Broodmother spawning in §b$countdown" + } + } + + @JvmStatic + fun playTestSound() { + with(spawnAlertConfig) { + SoundUtils.createSound(alertSound, pitch).playSound() + } + } + + private fun inSpidersDen() = IslandType.SPIDER_DEN.isInIsland() + private fun isCountdownEnabled() = inSpidersDen() && config.countdown + private fun isAliveMessageEnabled() = config.alertOnSpawn || config.stages.contains(StageEntry.ALIVE) +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/SpidersDenAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/SpidersDenAPI.kt new file mode 100644 index 000000000..7986c55e9 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/SpidersDenAPI.kt @@ -0,0 +1,12 @@ +package at.hannibal2.skyhanni.features.combat + +import at.hannibal2.skyhanni.features.gui.customscoreboard.CustomScoreboard +import at.hannibal2.skyhanni.features.gui.customscoreboard.ScoreboardPattern +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.RegexUtils.matches + +@SkyHanniModule +object SpidersDenAPI { + private fun getSbLines(): List<String> = CustomScoreboard.activeLines + fun isAtTopOfNest(): Boolean = getSbLines().any { ScoreboardPattern.broodmotherPattern.matches(it) } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt index 3bc12fa4c..3d46d3edc 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/BossType.kt @@ -101,6 +101,7 @@ enum class BossType( DUMMY("Dummy", Type.DUMMY), ARACHNE_SMALL("§cSmall Arachne", Type.ARACHNE), ARACHNE_BIG("§4Big Arachne", Type.ARACHNE), + BROODMOTHER("§cBroodmother", Type.BROODMOTHER), // The Rift LEECH_SUPREME("§cLeech Supreme", Type.THE_RIFT_BOSSES), @@ -119,8 +120,6 @@ enum class BossType( GARDEN_PEST_SLUG("§cSlug", Type.GARDEN_PESTS), GARDEN_PEST_EARTHWORM("§cEarthworm", Type.GARDEN_PESTS), - // TODO arachne - // TODO Corleone // TODO bal diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt index e9b2f879b..975e3b4f8 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/MobFinder.kt @@ -429,6 +429,11 @@ class MobFinder { entity.hasMaxHealth(2_400_000, true) -> return EntityResult(bossType = BossType.SLAYER_SPIDER_4) } } + if (entity.hasNameTagWith(1, "[§7Lv12§8] §4Broodmother")) { + if (entity.hasMaxHealth(6000)) { + return EntityResult(bossType = BossType.BROODMOTHER) + } + } checkArachne(entity as EntitySpider)?.let { return it } return null } diff --git a/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardEvent.kt b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardEvent.kt index efe7c953d..9f3c009e5 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardEvent.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.gui.customscoreboard import at.hannibal2.skyhanni.data.HypixelData import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.features.combat.SpidersDenAPI.isAtTopOfNest import at.hannibal2.skyhanni.features.dungeon.DungeonAPI import at.hannibal2.skyhanni.features.gui.customscoreboard.CustomScoreboard.eventsConfig import at.hannibal2.skyhanni.features.gui.customscoreboard.ScoreboardEvent.VOTING @@ -121,7 +122,7 @@ enum class ScoreboardEvent( ), BROODMOTHER( ::getBroodmotherLines, - ::getBroodmotherShowWhen, + ::isAtTopOfNest, "§4Broodmother§7: §eDormant", ), MINING_EVENTS( @@ -441,8 +442,6 @@ private fun getSoonEventShowWhen(): Boolean = private fun getBroodmotherLines(): List<String> = listOf(getSbLines().first { SbPattern.broodmotherPattern.matches(it) }) -private fun getBroodmotherShowWhen(): Boolean = getSbLines().any { SbPattern.broodmotherPattern.matches(it) } - private fun getMiningEventsLines() = buildList { // Wind if (getSbLines().any { SbPattern.windCompassPattern.matches(it) } |