diff --git a/detekt/detekt.yml b/detekt/detekt.yml index d69e828d..bdaea0ad 100644 --- a/detekt/detekt.yml +++ b/detekt/detekt.yml @@ -16,7 +16,7 @@ style: - 'HandleEvent' - 'Mod.EventHandler' MaxLineLength: - active: true + active: false maxLineLength: 140 excludeCommentStatements: true LoopWithTooManyJumpStatements: diff --git a/src/main/kotlin/at/raven/ravenAddons/config/ravenAddonsConfig.kt b/src/main/kotlin/at/raven/ravenAddons/config/ravenAddonsConfig.kt index 07c7a82c..4d4458f3 100644 --- a/src/main/kotlin/at/raven/ravenAddons/config/ravenAddonsConfig.kt +++ b/src/main/kotlin/at/raven/ravenAddons/config/ravenAddonsConfig.kt @@ -194,6 +194,16 @@ object ravenAddonsConfig : Vigilant( ) var blazetekkHamRadioMessageHider = false + @Property( + type = PropertyType.SWITCH, + name = "Invincibility Timer", + description = "Display a timer for Bonzo Mask, Phoenix Pet and Spirit Mask.\n" + + "§cNote: The mod assumes that your Phoenix Pet is level 100.", + category = "SkyBlock", + subcategory = "Invincibility" + ) + var invincibilityTimer = false + @Property( type = PropertyType.SWITCH, name = "Mining Ability Notification", diff --git a/src/main/kotlin/at/raven/ravenAddons/features/skyblock/InvincibilityTimer.kt b/src/main/kotlin/at/raven/ravenAddons/features/skyblock/InvincibilityTimer.kt new file mode 100644 index 00000000..881ae6e8 --- /dev/null +++ b/src/main/kotlin/at/raven/ravenAddons/features/skyblock/InvincibilityTimer.kt @@ -0,0 +1,82 @@ + +import at.raven.ravenAddons.config.ravenAddonsConfig +import at.raven.ravenAddons.data.HypixelGame +import at.raven.ravenAddons.event.WorldChangeEvent +import at.raven.ravenAddons.event.chat.ChatReceivedEvent +import at.raven.ravenAddons.loadmodule.LoadModule +import at.raven.ravenAddons.ravenAddons +import at.raven.ravenAddons.utils.ChatUtils +import at.raven.ravenAddons.utils.RegexUtils.matches +import at.raven.ravenAddons.utils.ServerTimeMark +import at.raven.ravenAddons.utils.TitleManager +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.util.regex.Pattern +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds + +@LoadModule +object InvincibilityTimer { + private var invincibilityJob: Job? = null + + enum class Invincibility( + val pattern: Pattern, + val cooldown: Duration, + ) { + BONZO("^Your (?:. )?Bonzo's Mask saved your life!".toPattern(), 3.seconds), + PHOENIX("^Your Phoenix Pet saved you from certain death!".toPattern(), 4.seconds), + SPIRIT("^Second Wind Activated! Your Spirit Mask saved your life!".toPattern(), 3.seconds), + ; + + companion object { + fun match(message: String): Invincibility? = entries.find { it.pattern.matches(message) } + } + } + + @SubscribeEvent + fun onChat(event: ChatReceivedEvent) { + if (!HypixelGame.inSkyBlock || !ravenAddonsConfig.invincibilityTimer) return + + val invincibility = Invincibility.match(event.cleanMessage) ?: return + invincibilityJob?.cancel() + invincibilityJob = + ravenAddons.launchCoroutine { + try { + val timer = ServerTimeMark.now() + invincibility.cooldown + while (timer.isInFuture()) { + val timeUntil = timer.timeUntil() + val formattedTime = timeUntil.inWholeMilliseconds / 1000f + val color = + when { + timeUntil > 2.seconds -> "§a" + timeUntil > 1.seconds -> "§e" + else -> "§c" + } + TitleManager.setTitle( + "$color%.3f".format(formattedTime), + "", + 1.seconds, + 0.seconds, + 0.seconds, + ) + delay(50) + } + } catch (e: CancellationException) { + ChatUtils.debug("Invincibility Timer: Invincibility Job cancelled: ${e.message}") + } + } + } + + @SubscribeEvent + fun onWorldLoad(event: WorldChangeEvent) { + if (!HypixelGame.inSkyBlock || !ravenAddonsConfig.invincibilityTimer) return + invincibilityJob?.let { + if (it.isActive) { + it.cancel() + } + invincibilityJob = null + } + } +}