From 6d4f9a049cf530930fe502a3a716b8ba5cb59827 Mon Sep 17 00:00:00 2001 From: Appability Date: Tue, 15 Aug 2023 10:31:16 -0700 Subject: fix formatDuration and refactor with Timer class --- .../features/misc/NonGodPotEffectDisplay.kt | 78 ++++++++++++---------- src/main/java/at/hannibal2/skyhanni/utils/Timer.kt | 43 ++++++++++++ 2 files changed, 84 insertions(+), 37 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/Timer.kt (limited to 'src/main/java/at/hannibal2/skyhanni') diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt index 1a37cb8ee..c0c5e08bc 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt @@ -12,14 +12,20 @@ import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.TimeUnit import at.hannibal2.skyhanni.utils.TimeUtils +import at.hannibal2.skyhanni.utils.Timer import net.minecraft.network.play.server.S47PacketPlayerListHeaderFooter import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds class NonGodPotEffectDisplay { private val config get() = SkyHanniMod.feature.misc private var checkFooter = false - private val effectDuration = mutableMapOf() + private val effectDuration = mutableMapOf() private var display = emptyList() enum class NonGodPotEffect(val apiName: String, val displayName: String, val isMixin: Boolean = false) { @@ -52,26 +58,26 @@ class NonGodPotEffectDisplay { if (event.message == "§aYou ate a §r§aRe-heated Gummy Polar Bear§r§a!") { checkFooter = true - effectDuration[NonGodPotEffect.SMOLDERING] = System.currentTimeMillis() + 1000 * 60 * 60 + effectDuration[NonGodPotEffect.SMOLDERING] = Timer(1.hours) update() } if (event.message == "§a§lBUFF! §fYou have gained §r§2Mushed Glowy Tonic I§r§f! Press TAB or type /effects to view your active effects!") { checkFooter = true - effectDuration[NonGodPotEffect.GLOWY] = System.currentTimeMillis() + 1000 * 60 * 60 + effectDuration[NonGodPotEffect.GLOWY] = Timer(1.hours) update() } if (event.message == "§a§lBUFF! §fYou splashed yourself with §r§bWisp's Ice-Flavored Water I§r§f! Press TAB or type /effects to view your active effects!") { checkFooter = true - effectDuration[NonGodPotEffect.WISP] = System.currentTimeMillis() + 1000 * 60 * 5 + effectDuration[NonGodPotEffect.WISP] = Timer(5.minutes) update() } if (event.message == "§e[NPC] §6King Yolkar§f: §rThese eggs will help me stomach my pain.") { checkFooter = true - effectDuration[NonGodPotEffect.GOBLIN] = System.currentTimeMillis() + 1000 * 60 * 20 + effectDuration[NonGodPotEffect.GOBLIN] = Timer(20.minutes) update() } if (event.message == "§cThe Goblin King's §r§afoul stench §r§chas dissipated!") { @@ -83,7 +89,7 @@ class NonGodPotEffectDisplay { private fun update() { val now = System.currentTimeMillis() - if (effectDuration.values.removeIf { now > it }) { + if (effectDuration.values.removeIf { it.ended }) { //to fetch the real amount of active pots totalEffectsCount = 0 checkFooter = true @@ -95,13 +101,14 @@ class NonGodPotEffectDisplay { private fun drawDisplay(now: Long): MutableList { val newDisplay = mutableListOf() for ((effect, time) in effectDuration.sorted()) { + if (time.ended) continue if (effect == NonGodPotEffect.INVISIBILITY) continue if (effect.isMixin && !config.nonGodPotEffectShowMixins) continue - val seconds = time - now - val format = TimeUtils.formatDuration(seconds, TimeUnit.HOUR) - val color = colorForTime(seconds) + val remaining = time.remaining.coerceAtLeast(0.seconds) + val format = TimeUtils.formatDuration(remaining.inWholeMilliseconds, TimeUnit.HOUR) + val color = colorForTime(remaining) val displayName = effect.displayName newDisplay.add("$displayName $color$format") @@ -115,14 +122,11 @@ class NonGodPotEffectDisplay { return newDisplay } - private fun colorForTime(seconds: Long): String { - return if (seconds <= 60) { - "§c" - } else if (seconds <= 60 * 3) { - "§6" - } else if (seconds <= 60 * 10) { - "§e" - } else "§f" + private fun colorForTime(duration: Duration) = when (duration) { + in 0.seconds..60.seconds -> "§c" + in 60.seconds..3.minutes -> "§6" + in 3.minutes..10.minutes -> "§e" + else -> "§f" } @SubscribeEvent @@ -144,27 +148,27 @@ class NonGodPotEffectDisplay { if (!event.inventoryName.endsWith("Active Effects")) return for (stack in event.inventoryItems.values) { - val name = stack.name ?: continue - for (effect in NonGodPotEffect.entries) { - if (name != effect.displayName) continue - for (line in stack.getLore()) { - if (line.contains("Remaining") && - line != "§7Time Remaining: §aCompleted!" && - !line.contains("Remaining Uses") - ) { - val duration = try { - TimeUtils.getMillis(line.split("§f")[1]) - } catch (e: IndexOutOfBoundsException) { - CopyErrorCommand.logError( - Exception("'§f' not found in line '$line'", e), - "Error while reading Non God-Potion effects from tab list" - ) - continue - } - effectDuration[effect] = System.currentTimeMillis() + duration - update() + val name = stack.name ?: continue + for (effect in NonGodPotEffect.entries) { + if (name != effect.displayName) continue + for (line in stack.getLore()) { + if (line.contains("Remaining") && + line != "§7Time Remaining: §aCompleted!" && + !line.contains("Remaining Uses") + ) { + val duration = try { + TimeUtils.getMillis(line.split("§f")[1]) + } catch (e: IndexOutOfBoundsException) { + CopyErrorCommand.logError( + Exception("'§f' not found in line '$line'", e), + "Error while reading Non God-Potion effects from tab list" + ) + continue } + effectDuration[effect] = Timer(duration.milliseconds) + update() } + } } } } @@ -186,7 +190,7 @@ class NonGodPotEffectDisplay { if (line.startsWith(effect.displayName)) { try { val duration = TimeUtils.getMillis(line.split("§f")[1]) - effectDuration[effect] = System.currentTimeMillis() + duration + effectDuration[effect] = Timer(duration.milliseconds) update() } catch (e: IndexOutOfBoundsException) { LorenzUtils.debug("Error while reading non god pot effects from tab list! line: '$line'") diff --git a/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt b/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt new file mode 100644 index 000000000..55ea90b52 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/Timer.kt @@ -0,0 +1,43 @@ +package at.hannibal2.skyhanni.utils + +import com.google.gson.annotations.Expose +import kotlin.time.Duration + +class Timer( + @Expose + var duration: Duration, + + @Expose + private var started: SimpleTimeMark = SimpleTimeMark.now(), + + startPaused: Boolean = false +): Comparable { + + @Expose + private var paused: SimpleTimeMark? = null + + init { + if (startPaused) { + paused = started + } + } + + val ended get() = !remaining.isPositive() + val remaining get() = duration - elapsed + val elapsed get() = paused?.let { it - started } ?: started.passedSince() + + fun pause() { + paused = SimpleTimeMark.now() + } + + fun resume() { + paused?.let { + started = it + duration = it - started + paused = null + } + } + + override fun compareTo(other: Timer): Int = remaining.compareTo(other.remaining) + +} \ No newline at end of file -- cgit