-
-
Notifications
You must be signed in to change notification settings - Fork 208
/
NonGodPotEffectDisplay.kt
178 lines (152 loc) · 6.35 KB
/
NonGodPotEffectDisplay.kt
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
package at.hannibal2.skyhanni.features.misc.effects
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.api.event.HandleEvent
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.events.EffectDurationChangeEvent
import at.hannibal2.skyhanni.events.EffectDurationChangeType
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.events.ProfileJoinEvent
import at.hannibal2.skyhanni.events.SecondPassedEvent
import at.hannibal2.skyhanni.events.TablistFooterUpdateEvent
import at.hannibal2.skyhanni.features.dungeon.DungeonAPI
import at.hannibal2.skyhanni.api.EffectAPI.NonGodPotEffect
import at.hannibal2.skyhanni.features.rift.RiftAPI
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.CollectionUtils.sorted
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher
import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
import at.hannibal2.skyhanni.utils.SoundUtils.playPlingSound
import at.hannibal2.skyhanni.utils.TimeUnit
import at.hannibal2.skyhanni.utils.TimeUtils.format
import at.hannibal2.skyhanni.utils.TimeUtils.timerColor
import at.hannibal2.skyhanni.utils.Timer
import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
@SkyHanniModule
object NonGodPotEffectDisplay {
private val config get() = SkyHanniMod.feature.misc.potionEffect
private var checkFooter = false
private val effectDuration = mutableMapOf<NonGodPotEffect, Timer>()
private var display = emptyList<String>()
private val effectsCountPattern by RepoPattern.pattern(
"misc.nongodpot.effects",
"§7You have §e(?<name>\\d+) §7non-god effects\\.",
)
private var totalEffectsCount = 0
@SubscribeEvent
fun onProfileJoin(event: ProfileJoinEvent) {
effectDuration.clear()
display = emptyList()
}
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
if (event.message == "§aYou cleared all of your active effects!") {
effectDuration.clear()
update()
}
}
@HandleEvent
fun onEffectUpdate(event: EffectDurationChangeEvent) {
when (event.durationChangeType) {
EffectDurationChangeType.ADD -> {
event.duration?.let {
val existing = effectDuration[event.effect]?.duration ?: Duration.ZERO
effectDuration[event.effect] = Timer(existing + it)
}
}
EffectDurationChangeType.SET -> {
event.duration?.let {
effectDuration[event.effect] = Timer(it)
}
}
EffectDurationChangeType.REMOVE -> {
effectDuration.remove(event.effect)
}
}
update()
}
private fun update() {
if (effectDuration.values.removeIf { it.ended }) {
// to fetch the real amount of active pots
totalEffectsCount = 0
checkFooter = true
}
display = drawDisplay()
}
private fun drawDisplay(): MutableList<String> {
val newDisplay = mutableListOf<String>()
for ((effect, time) in effectDuration.sorted()) {
if (time.ended) continue
if (effect == NonGodPotEffect.INVISIBILITY) continue
if (effect.isMixin && !config.nonGodPotEffectShowMixins) continue
val remaining = time.remaining.coerceAtLeast(0.seconds)
val format = remaining.format(TimeUnit.HOUR)
val color = remaining.timerColor()
val displayName = effect.tabListName
newDisplay.add("$displayName $color$format")
}
val diff = totalEffectsCount - effectDuration.size
if (diff > 0) {
newDisplay.add("§eOpen the /effects inventory")
newDisplay.add("§eto show the missing $diff effects!")
checkFooter = true
}
return newDisplay
}
@SubscribeEvent
fun onSecondPassed(event: SecondPassedEvent) {
if (!isEnabled()) return
if (!ProfileStorageData.loaded) return
if (config.nonGodPotEffectDisplay) update()
val effectWarning = config.expireWarning
val effectSound = config.expireSound
if (!effectWarning && !effectSound) return
effectDuration.sorted().forEach { (effect, time) ->
if (time.remaining.inWholeSeconds != config.expireWarnTime.toLong()) return
if (effectWarning) LorenzUtils.sendTitle(effect.tabListName, 3.seconds)
if (effectSound) repeat(5) { playPlingSound() }
}
}
@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
checkFooter = true
}
@SubscribeEvent
fun onTabUpdate(event: TablistFooterUpdateEvent) {
if (!LorenzUtils.inSkyBlock || !checkFooter) return
val lines = event.footer.split("\n")
if (!lines.any { it.contains("§a§lActive Effects") }) return
checkFooter = false
var effectsCount = 0
for (line in lines) {
effectsCountPattern.matchMatcher(line) {
val group = group("name")
effectsCount = group.toInt()
}
}
totalEffectsCount = effectsCount
}
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
if (!isEnabled() || !config.nonGodPotEffectDisplay) return
if (RiftAPI.inRift()) return
config.nonGodPotEffectPos.renderStrings(
display,
extraSpace = 3,
posLabel = "Non God Pot Effects",
)
}
@SubscribeEvent
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
event.move(3, "misc.nonGodPotEffectDisplay", "misc.potionEffect.nonGodPotEffectDisplay")
event.move(3, "misc.nonGodPotEffectShowMixins", "misc.potionEffect.nonGodPotEffectShowMixins")
event.move(3, "misc.nonGodPotEffectPos", "misc.potionEffect.nonGodPotEffectPos")
}
private fun isEnabled() = LorenzUtils.inSkyBlock && !DungeonAPI.inDungeon() && !LorenzUtils.inKuudraFight
}