aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerRngMeterDisplay.kt
blob: 7f785cf109fef731f31232607cd082d2b8d6206b (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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package at.hannibal2.skyhanni.features.slayer

import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.Storage
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.data.SlayerAPI
import at.hannibal2.skyhanni.data.TitleUtils
import at.hannibal2.skyhanni.events.*
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName_old
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.StringUtils.removeWordsAtEnd
import io.github.moulberry.notenoughupdates.util.Constants
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.math.ceil
import kotlin.time.Duration.Companion.seconds

class SlayerRngMeterDisplay {
    private val config get() = SkyHanniMod.feature.slayer.rngMeterDisplay
    private var display = ""
    private val inventoryNamePattern = "(?<name>.*) RNG Meter".toPattern()
    private val updatePattern = "   §dRNG Meter §f- §d(?<exp>.*) Stored XP".toPattern()
    private val changedItemPattern = "§aYou set your §r.* RNG Meter §r§ato drop §r.*§a!".toPattern()
    private var lastItemDroppedTime = 0L

    @SubscribeEvent
    fun onTick(event: LorenzTickEvent) {
        if (!isEnabled()) return

        if (event.repeatSeconds(1)) {
            if (lastItemDroppedTime != 0L) {
                if (System.currentTimeMillis() > lastItemDroppedTime + 4_000) {
                    lastItemDroppedTime = 0L
                    update()
                }
            }
        }
    }

    @SubscribeEvent
    fun onSlayerChange(event: SlayerChangeEvent) {
        update()
    }

    @SubscribeEvent
    fun onChat(event: LorenzChatEvent) {

        if (!isEnabled()) return

        if (config.hideChat) {
            if (SlayerAPI.isInSlayerArea) {
                changedItemPattern.matchMatcher(event.message) {
                    event.blockedReason = "slayer_rng_meter"
                }
            }
        }

        val currentMeter = updatePattern.matchMatcher(event.message) {
            group("exp").formatNumber()
        } ?: return

        val storage = getStorage() ?: return
        val old = storage.currentMeter
        storage.currentMeter = currentMeter

        if (old != -1L) {
            val item = storage.itemGoal
            val hasItemSelected = item != "" && item != "?"
            if (!hasItemSelected) {
                if (config.warnEmpty) {
                    LorenzUtils.warning("§c[Skyhanni] No Slayer RNG Meter Item selected!")
                    TitleUtils.sendTitle("§cNo RNG Meter Item!", 3.seconds)
                }
            }
            var blockChat = config.hideChat && hasItemSelected
            val diff = currentMeter - old
            if (diff > 0) {
                storage.gainPerBoss = diff
            } else {
                storage.itemGoal = ""
                blockChat = false
                val from = old.addSeparators()
                val to = storage.goalNeeded.addSeparators()

                var rawPercentage = old.toDouble() / storage.goalNeeded
                if (rawPercentage > 1) rawPercentage = 1.0
                val percentage = LorenzUtils.formatPercentage(rawPercentage)
                LorenzUtils.chat("§e[SkyHanni] §dRNG Meter §7dropped at §e$percentage §7XP ($from/${to}§7)")
                lastItemDroppedTime = System.currentTimeMillis()
            }
            if (blockChat) {
                event.blockedReason = "slayer_rng_meter"
            }
        }
        update()
    }

    private fun getStorage(): Storage.ProfileSpecific.SlayerRngMeterStorage? {
        return ProfileStorageData.profileSpecific?.slayerRngMeter?.getOrPut(getCurrentSlayer()) {
            Storage.ProfileSpecific.SlayerRngMeterStorage()
        }
    }

    private fun getCurrentSlayer() = SlayerAPI.latestSlayerCategory.removeWordsAtEnd(1).removeColor()

    @SubscribeEvent
    fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
        if (!isEnabled()) return

        val name = inventoryNamePattern.matchMatcher(event.inventoryName) {
            group("name")
        } ?: return

        if (name != getCurrentSlayer()) return

        val storage = getStorage() ?: return

        val selectedItem = event.inventoryItems.values.find { item -> item.getLore().any { it.contains("§aSELECTED") } }
        if (selectedItem == null) {
            storage.itemGoal = ""
            storage.goalNeeded = -1
        } else {
            storage.itemGoal = selectedItem.nameWithEnchantment
            val jsonObject = Constants.RNGSCORE["slayer"].asJsonObject.get(getCurrentSlayer()).asJsonObject
            storage.goalNeeded = jsonObject.get(selectedItem.getInternalName_old()).asLong
        }
        update()
    }

    private fun update() {
        display = drawDisplay()
    }

    private fun drawDisplay(): String {
        val storage = getStorage() ?: return ""

        if (SlayerAPI.latestSlayerCategory.let {
                it.endsWith(" I") || it.endsWith(" II")
            }) {
            return ""
        }
        val latestSlayerCategory = SlayerAPI.latestSlayerCategory
        latestSlayerCategory.endsWith(" I")

        with(storage) {
            if (itemGoal == "?") return "§cOpen RNG Meter Inventory!"
            if (itemGoal == "") {
                return if (lastItemDroppedTime != 0L) {
                    "§a§lRNG Item dropped!"
                } else {
                    "§eNo RNG Item selected!"
                }
            }
            if (currentMeter == -1L || gainPerBoss == -1L) return "§cKill the slayer boss 2 times!"

            val missing = goalNeeded - currentMeter + gainPerBoss
            var timesMissing = missing.toDouble() / gainPerBoss
            if (timesMissing < 1) timesMissing = 1.0
            timesMissing = ceil(timesMissing)

            return "$itemGoal §7in §e${timesMissing.toInt().addSeparators()} §7bosses!"
        }
    }

    @SubscribeEvent
    fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) {
        if (!isEnabled()) return
        if (!SlayerAPI.isInSlayerArea) return
        if (!SlayerAPI.hasActiveSlayerQuest()) return

        config.pos.renderString(display, posLabel = "Rng Meter Display")
    }

    fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
}