summaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features/rift/everywhere/RiftTimer.kt
blob: 21f13c1560eeacafb71dbffe981e34f71c652409 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package at.hannibal2.skyhanni.features.rift.everywhere

import at.hannibal2.skyhanni.events.ActionBarUpdateEvent
import at.hannibal2.skyhanni.events.ConfigLoadEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.entity.EntityHealthDisplayEvent
import at.hannibal2.skyhanni.features.rift.RiftAPI
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.ConditionalUtils
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RegexUtils.matchFirst
import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher
import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
import at.hannibal2.skyhanni.utils.TimeUtils
import at.hannibal2.skyhanni.utils.TimeUtils.format
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds

@SkyHanniModule
object RiftTimer {

    private val config get() = RiftAPI.config.timer

    private val repoGroup = RepoPattern.group("rift.everywhere")
    private val timePattern by repoGroup.pattern(
        "timer",
        "§(?<color>[a7])(?<time>.*)ф Left.*"
    )

    /**
     * REGEX-TEST: 3150 §aф
     */
    private val nametagPattern by repoGroup.pattern(
        "nametag.timer",
        "(?<time>\\d+) §aф"
    )

    private var display = emptyList<String>()
    private var maxTime = 0.seconds
    private var currentTime = 0.seconds
    private var latestTime = 0.seconds
    private val changes = mutableMapOf<Long, String>()

    @SubscribeEvent
    fun onWorldChange(event: LorenzWorldChangeEvent) {
        display = emptyList()
        maxTime = 0.seconds
        latestTime = 0.seconds
        currentTime = 0.seconds
    }

    //todo use ActionBarValueUpdateEvent
    @SubscribeEvent
    fun onActionBarUpdate(event: ActionBarUpdateEvent) {
        if (!isEnabled()) return

        event.actionBar.split("     ").matchFirst(timePattern) {
            val color = group("color")
            val newTime = TimeUtils.getDuration(group("time").replace("m", "m "))

            if (color == "7") {
                if (newTime > maxTime) {
                    maxTime = newTime
                }
            }
            currentTime = newTime
            update()
        }
    }

    private fun update() {
        if (currentTime != latestTime) {
            val diff = (currentTime - latestTime) + 1.seconds
            latestTime = currentTime
            if (latestTime != maxTime) {
                addDiff(diff)
            }
        }

        val currentFormat = currentTime.format()
        val percentage =
            LorenzUtils.formatPercentage(currentTime.inWholeMilliseconds.toDouble() / maxTime.inWholeMilliseconds)
        val percentageFormat = if (config.percentage.get()) " §7($percentage)" else ""
        val maxTimeFormat = if (config.maxTime.get()) "§7/§b" + maxTime.format() else ""
        val color = if (currentTime <= 1.minutes) "§c" else if (currentTime <= 5.minutes) "§e" else "§b"
        val firstLine = "§eRift Timer: $color$currentFormat$maxTimeFormat$percentageFormat"

        display = buildList {
            add(firstLine)
            changes.keys.removeIf { System.currentTimeMillis() > it + 4_000 }
            for (entry in changes.values) {
                add(entry)
            }
        }
    }

    private fun addDiff(diff: Duration) {
        val diffFormat = if (diff > 0.seconds) {
            "§a+${diff.format()}"
        } else if (diff < 0.seconds) {
            "§c-${(-diff).format()}"
        } else return

        changes[System.currentTimeMillis()] = diffFormat
    }

    @SubscribeEvent
    fun onConfigLoad(event: ConfigLoadEvent) {
        ConditionalUtils.onToggle(
            config.percentage,
            config.maxTime,
        ) {
            if (isEnabled()) {
                update()
            }
        }
    }

    @SubscribeEvent
    fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
        if (!isEnabled()) return
        if (LorenzUtils.skyBlockArea == "Mirrorverse") return

        config.timerPosition.renderStrings(display, posLabel = "Rift Timer")
    }

    @SubscribeEvent
    fun onEntityHealthDisplay(event: EntityHealthDisplayEvent) {
        if (!RiftAPI.inRift() || !config.nametag) return
        val time = nametagPattern.matchMatcher(event.text) {
            group("time")?.toIntOrNull()
        } ?: return
        event.text = "${time.seconds.format()} §aф"
    }

    fun isEnabled() = RiftAPI.inRift() && config.enabled
}