summaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features/inventory/HighlightBonzoMasks.kt
blob: 2b298a8031dbebba331a803166b0960c677f72de (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
package at.hannibal2.skyhanni.features.inventory

import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GuiContainerEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import at.hannibal2.skyhanni.utils.RegexUtils.matches
import at.hannibal2.skyhanni.utils.RenderUtils.highlight
import at.hannibal2.skyhanni.utils.RenderUtils.interpolate
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.awt.Color
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds

/**
 * @author Linnea Gräf
 */
@SkyHanniModule
object HighlightBonzoMasks {

    private val config get() = SkyHanniMod.feature.inventory.itemAbilities

    private val maskTimers = mutableMapOf<MaskType, SimpleTimeMark>()

    private val patternGroup = RepoPattern.group("inventory.masks.timers")
    private val bonzoMaskPattern by patternGroup.pattern(
        "bonzo",
        "Your .*Bonzo's Mask saved your life!"
    )
    private val spiritMaskPattern by patternGroup.pattern(
        "spirit",
        "Second Wind Activated! Your Spirit Mask saved your life!"
    )

    private val greenHue = Color.RGBtoHSB(0, 255, 0, null)[0].toDouble()
    private val redHue = Color.RGBtoHSB(255, 0, 0, null)[0].toDouble()

    @SubscribeEvent
    fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) {
        if (!config.depletedBonzosMasks) return
        for (slot in event.gui.inventorySlots.inventorySlots) {
            val internalName = slot.stack?.getInternalName() ?: continue
            val maskType = MaskType.getByInternalName(internalName) ?: continue
            val readyAt = maskTimers[maskType] ?: continue

            if (readyAt.isInFuture()) {
                val hue = interpolate(redHue, greenHue, maskType.percentageComplete(readyAt.timeUntil()))
                slot.highlight(Color(Color.HSBtoRGB(hue.toFloat(), 1F, 1F)))
            }
        }
    }

    @SubscribeEvent
    fun onChat(event: LorenzChatEvent) {
        val message = event.message.removeColor()
        // TODO move pattern into enum
        if (bonzoMaskPattern.matches(message)) {
            maskTimers[MaskType.BONZO_MASK] = SimpleTimeMark.now() + MaskType.BONZO_MASK.cooldown
        } else if (spiritMaskPattern.matches(message)) {
            maskTimers[MaskType.SPIRIT_MASK] = SimpleTimeMark.now() + MaskType.SPIRIT_MASK.cooldown
        }
    }

    @SubscribeEvent
    fun onWorldChange(event: LorenzWorldChangeEvent) {
        maskTimers.clear()
    }

    @SubscribeEvent
    fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
        event.move(2, "inventory.highlightDepletedBonzosMasks", "itemAbilities.depletedBonzosMasks")
    }

    // This timer is overestimating since mage level affects the cooldown
    private enum class MaskType(val internalNames: List<NEUInternalName>, val cooldown: Duration) {
        BONZO_MASK(listOf("BONZO_MASK".asInternalName(), "STARRED_BONZO_MASK".asInternalName()), 6.minutes),
        SPIRIT_MASK(listOf("SPIRIT_MASK".asInternalName(), "STARRED_SPIRIT_MASK".asInternalName()), 30.seconds),
        ;

        fun percentageComplete(timeUntil: Duration): Double {
            return timeUntil.inWholeMilliseconds / cooldown.inWholeMilliseconds.toDouble()
        }

        companion object {
            fun getByInternalName(internalName: NEUInternalName): MaskType? {
                return entries.firstOrNull { internalName in it.internalNames }
            }
        }
    }
}