aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features/misc
diff options
context:
space:
mode:
authorhannibal2 <24389977+hannibal00212@users.noreply.github.com>2023-09-16 12:34:18 +0200
committerhannibal2 <24389977+hannibal00212@users.noreply.github.com>2023-09-16 12:34:18 +0200
commit4293cfd919c3c93d4532534f722c407d7ad1370d (patch)
treef9f612f021ef7f4283d74312edfaca30badc6749 /src/main/java/at/hannibal2/skyhanni/features/misc
parent538e3ceb76f8e0b590291ce9aa90aa94896cdcb6 (diff)
parent024ba52fb69b6cd44b4e31542867f802de656f15 (diff)
downloadSkyHanni-cum.tar.gz
SkyHanni-cum.tar.bz2
SkyHanni-cum.zip
Merge branch 'beta' into cumcum
# Conflicts: # src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt # src/main/java/at/hannibal2/skyhanni/config/features/AshfangConfig.java
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features/misc')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt171
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/NonGodPotEffectDisplay.kt83
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt42
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/PocketSackInASackDisplay.kt22
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/RealTime.kt24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ServerRestartTitle.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/SuperpairsClicksAlert.kt60
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/TimeFeatures.kt46
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordStatus.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostCounter.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostFormatting.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostUtil.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt146
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/items/GlowingDroppedItems.kt68
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/Category.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/DefaultConfigFeatures.kt99
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/DefaultConfigOptionGui.kt197
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/FeatureToggleProcessor.kt91
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/FeatureToggleableOption.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/massconfiguration/ResetSuggestionState.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderChestReward.kt148
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderTracker.kt356
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/GetFromSacksTabComplete.kt45
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/TabComplete.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorFeatures.kt40
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/trevor/TrevorSolver.kt3
29 files changed, 1488 insertions, 225 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt
index 9205b0154..133e12ab4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt
@@ -1,42 +1,39 @@
package at.hannibal2.skyhanni.features.misc
import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.config.Storage
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.ProfileStorageData
-import at.hannibal2.skyhanni.data.ScoreboardData
-import at.hannibal2.skyhanni.events.ConfigLoadEvent
-import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.events.PlaySoundEvent
-import at.hannibal2.skyhanni.features.bazaar.BazaarApi.Companion.getBazaarData
+import at.hannibal2.skyhanni.events.*
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.afterChange
import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull
-import at.hannibal2.skyhanni.utils.NEUItems.getPrice
+import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.NumberUtil.format
import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
+import io.github.moulberry.notenoughupdates.util.MinecraftExecutor
+import net.minecraft.client.Minecraft
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class EnderNodeTracker {
private val config get() = SkyHanniMod.feature.misc.enderNodeTracker
+ private val storage get() = ProfileStorageData.profileSpecific?.enderNodeTracker
- private var totalNodesMined = 0
- private var totalEndermiteNests = 0
private var totalEnderArmor = 0
+ private var miteGelInInventory = 0
private var display = emptyList<List<Any>>()
- private var lootCount = mapOf<EnderNode, Int>()
private var lootProfit = mapOf<EnderNode, Double>()
private val enderNodeRegex = Regex("""ENDER NODE!.+You found (\d+x )?§r(.+)§r§f!""")
private val endermanRegex = Regex("""(RARE|PET) DROP! §r(.+) §r§b\(""")
- private var lastEndermiteTime = 0L
-
@SubscribeEvent
fun onChat(event: LorenzChatEvent) {
+ if (!config.enabled) return
if (!ProfileStorageData.loaded) return
if (!isInTheEnd()) return
@@ -44,10 +41,11 @@ class EnderNodeTracker {
val message = event.message.trim()
var item: String? = null
var amount = 1
+ val storage = storage ?: return
// check whether the loot is from an ender node or an enderman
enderNodeRegex.find(message)?.let {
- totalNodesMined++
+ storage.totalNodesMined++
amount = it.groups[1]?.value?.substringBefore("x")?.toIntOrNull() ?: 1
item = it.groups[2]?.value
} ?: endermanRegex.find(message)?.let {
@@ -59,37 +57,67 @@ class EnderNodeTracker {
item == null -> return
isEnderArmor(item) -> totalEnderArmor++
item == "§cEndermite Nest" -> {
- lastEndermiteTime = System.currentTimeMillis()
- totalEndermiteNests++
+ storage.totalEndermiteNests++
}
}
// increment the count of the specific item found
EnderNode.entries.find { it.displayName == item }?.let {
- val old = lootCount[it] ?: 0
- lootCount = lootCount.editCopy {
+ val old = storage.lootCount[it] ?: 0
+ storage.lootCount = storage.lootCount.editCopy {
this[it] = old + amount
}
}
- saveAndUpdate()
+ update()
+ }
+
+ @SubscribeEvent
+ fun onIslandChange(event: IslandChangeEvent) {
+ if (!config.enabled) return
+ if (event.newIsland != IslandType.THE_END) return
+ miteGelInInventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory
+ .filter { it?.getInternalNameOrNull() == EnderNode.MITE_GEL.internalName }
+ .sumOf { it.stackSize }
+ }
+
+ @SubscribeEvent
+ fun onSackChange(event: SackChangeEvent) {
+ if (!config.enabled) return
+ if (!ProfileStorageData.loaded) return
+ if (!isInTheEnd()) return
+ val storage = storage ?: return
+
+ val change = event.sackChanges
+ .firstOrNull { it.internalName == EnderNode.MITE_GEL.internalName && it.delta > 0 }
+ ?: return
+ val old = storage.lootCount[EnderNode.MITE_GEL] ?: 0
+ storage.lootCount = storage.lootCount.editCopy {
+ this[EnderNode.MITE_GEL] = old + change.delta
+ }
+ update()
}
@SubscribeEvent
- fun onSoundPlay(event: PlaySoundEvent) {
+ fun onInventoryUpdate(event: OwnInventoryItemUpdateEvent) {
+ if (!config.enabled) return
if (!isInTheEnd()) return
- if (event.soundName != "mob.silverfish.kill") return
- if (event.distanceToPlayer > 15) return
- if (System.currentTimeMillis() - lastEndermiteTime > 7500) return
-
- // listen for nearby endermite death sounds within 7.5s of mining an endermite nest
- // this is a fairly accurate approximation for mite gel drops
- val oldEndStone = lootCount[EnderNode.ENCHANTED_ENDSTONE] ?: 0
- val oldMiteGel = lootCount[EnderNode.MITE_GEL] ?: 0
- lootCount = lootCount.editCopy {
- this[EnderNode.ENCHANTED_ENDSTONE] = oldEndStone + (1 + Math.random() * 2).toInt()
- this[EnderNode.MITE_GEL] = oldMiteGel + (1 + Math.random() * 2).toInt()
+ if (!ProfileStorageData.loaded) return
+ val storage = storage ?: return
+
+ MinecraftExecutor.OnThread.execute {
+ val newMiteGelInInventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory
+ .filter { it?.getInternalNameOrNull() == EnderNode.MITE_GEL.internalName }
+ .sumOf { it.stackSize }
+ val change = newMiteGelInInventory - miteGelInInventory
+ if (change > 0) {
+ val old = storage.lootCount[EnderNode.MITE_GEL] ?: 0
+ storage.lootCount = storage.lootCount.editCopy {
+ this[EnderNode.MITE_GEL] = old + change
+ }
+ update()
+ }
+ miteGelInInventory = newMiteGelInInventory
}
- saveAndUpdate()
}
@SubscribeEvent
@@ -102,60 +130,49 @@ class EnderNodeTracker {
@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
config.textFormat.afterChange {
- saveAndUpdate()
+ update()
}
+ val storage = storage ?: return
- val hidden = ProfileStorageData.profileSpecific?.enderNodeTracker ?: return
- totalNodesMined = hidden.totalNodesMined
- totalEndermiteNests = hidden.totalEndermiteNests
- lootCount = hidden.lootCount
- totalEnderArmor = hidden.lootCount.filter { isEnderArmor(it.key.displayName) }.map { it.value }.sum()
- saveAndUpdate()
+ totalEnderArmor = storage.lootCount.filter { isEnderArmor(it.key.displayName) }
+ .map { it.value }
+ .sum()
+ update()
}
- private fun calculateProfit(): Map<EnderNode, Double> {
+ private fun calculateProfit(storage: Storage.ProfileSpecific.EnderNodeTracker): Map<EnderNode, Double> {
+ if (!ProfileStorageData.loaded) return emptyMap()
+
val newProfit = mutableMapOf<EnderNode, Double>()
- lootCount.forEach { (key, _) ->
- val price = if (isEnderArmor(key.displayName)) {
+ storage.lootCount.forEach { (item, amount) ->
+ val price = if (isEnderArmor(item.displayName)) {
10_000.0
} else {
- val internalName = key.internalName
- val npcPrice = internalName.getNpcPriceOrNull()
- val bazaarData = internalName.getBazaarData()
- if (LorenzUtils.noTradeMode || bazaarData == null) {
- npcPrice ?: georgePrice(key) ?: 0.0
- } else {
- npcPrice
- ?.coerceAtLeast(bazaarData.sellPrice)
- ?.coerceAtLeast(georgePrice(key) ?: 0.0)
- ?: internalName.getPrice()
- }
+ (if (!LorenzUtils.noTradeMode) item.internalName.getPriceOrNull() else 0.0)
+ ?.coerceAtLeast(item.internalName.getNpcPriceOrNull() ?: 0.0)
+ ?.coerceAtLeast(georgePrice(item) ?: 0.0)
+ ?: 0.0
}
- newProfit[key] = price * (lootCount[key] ?: 0)
+ newProfit[item] = price * amount
}
return newProfit
}
- private fun saveAndUpdate() {
- val hidden = ProfileStorageData.profileSpecific?.enderNodeTracker ?: return
- hidden.totalNodesMined = totalNodesMined
- hidden.totalEndermiteNests = totalEndermiteNests
- hidden.lootCount = lootCount
-
- lootProfit = calculateProfit()
- display = formatDisplay(drawDisplay())
+ private fun update() {
+ val storage = storage ?: return
+ lootProfit = calculateProfit(storage)
+ display = formatDisplay(drawDisplay(storage))
}
- private fun isInTheEnd() = LorenzUtils.inIsland(IslandType.THE_END)
- && ScoreboardData.sidebarLines.any { it.contains("The End") }
+ private fun isInTheEnd() = LorenzUtils.skyBlockArea == "The End"
private fun isEnderArmor(displayName: String?) = when (displayName) {
- "§5Ender Helmet",
- "§5Ender Chestplate",
- "§5Ender Leggings",
- "§5Ender Boots",
- "§5Ender Necklace",
- "§5Ender Gauntlet" -> true
+ EnderNode.END_HELMET.displayName,
+ EnderNode.END_CHESTPLATE.displayName,
+ EnderNode.END_LEGGINGS.displayName,
+ EnderNode.END_BOOTS.displayName,
+ EnderNode.ENDER_NECKLACE.displayName,
+ EnderNode.ENDER_GAUNTLET.displayName -> true
else -> false
}
@@ -169,15 +186,17 @@ class EnderNodeTracker {
else -> null
}
- private fun drawDisplay() = buildList<List<Any>> {
+ private fun drawDisplay(storage: Storage.ProfileSpecific.EnderNodeTracker) = buildList<List<Any>> {
+ if (!ProfileStorageData.loaded) return emptyList<List<Any>>()
+
addAsSingletonList("§5§lEnder Node Tracker")
- addAsSingletonList("§d${totalNodesMined.addSeparators()} Ender Nodes mined")
+ addAsSingletonList("§d${storage.totalNodesMined.addSeparators()} Ender Nodes mined")
addAsSingletonList("§6${format(lootProfit.values.sum())} Coins made")
addAsSingletonList(" ")
- addAsSingletonList("§b${totalEndermiteNests.addSeparators()} §cEndermite Nest")
+ addAsSingletonList("§b${storage.totalEndermiteNests.addSeparators()} §cEndermite Nest")
for (item in EnderNode.entries.subList(0, 11)) {
- val count = (lootCount[item] ?: 0).addSeparators()
+ val count = (storage.lootCount[item] ?: 0).addSeparators()
val profit = format(lootProfit[item] ?: 0.0)
addAsSingletonList("§b$count ${item.displayName} §7(§6$profit§7)")
}
@@ -187,17 +206,19 @@ class EnderNodeTracker {
"§7(§6${format(totalEnderArmor * 10_000)}§7)"
)
for (item in EnderNode.entries.subList(11, 16)) {
- val count = (lootCount[item] ?: 0).addSeparators()
+ val count = (storage.lootCount[item] ?: 0).addSeparators()
val profit = format(lootProfit[item] ?: 0.0)
addAsSingletonList("§b$count ${item.displayName} §7(§6$profit§7)")
}
// enderman pet rarities
- val (c, u, r, e, l) = EnderNode.entries.subList(16, 21).map { (lootCount[it] ?: 0).addSeparators() }
+ val (c, u, r, e, l) = EnderNode.entries.subList(16, 21).map { (storage.lootCount[it] ?: 0).addSeparators() }
val profit = format(EnderNode.entries.subList(16, 21).sumOf { lootProfit[it] ?: 0.0 })
addAsSingletonList("§f$c§7-§a$u§7-§9$r§7-§5$e§7-§6$l §fEnderman Pet §7(§6$profit§7)")
}
private fun formatDisplay(map: List<List<Any>>): List<List<Any>> {
+ if (!ProfileStorageData.loaded) return emptyList()
+
val newList = mutableListOf<List<Any>>()
for (index in config.textFormat.get()) {
newList.add(map[index])
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..19d57946a 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<NonGodPotEffect, Long>()
+ private val effectDuration = mutableMapOf<NonGodPotEffect, Timer>()
private var display = emptyList<String>()
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<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 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'")
@@ -214,7 +218,6 @@ class NonGodPotEffectDisplay {
)
}
- private fun isEnabled(): Boolean {
- return LorenzUtils.inSkyBlock && config.nonGodPotEffectDisplay && !LorenzUtils.inDungeons && !LorenzUtils.inKuudraFight
- }
+ private fun isEnabled() =
+ LorenzUtils.inSkyBlock && config.nonGodPotEffectDisplay && !LorenzUtils.inDungeons && !LorenzUtils.inKuudraFight
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt
index bdddcc3a7..98a16eb4c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt
@@ -6,21 +6,23 @@ import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.OSUtils
import kotlinx.coroutines.launch
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import org.lwjgl.input.Keyboard
class PasteIntoSigns {
+ private var lastClicked = false
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
if (!LorenzUtils.onHypixel) return
if (!SkyHanniMod.feature.misc.pasteIntoSigns) return
- if (LorenzUtils.isControlKeyDown() && OSUtils.isKeyHeld(Keyboard.KEY_V)) {
+ val currentlyClicked = LorenzUtils.isPastingKeysDown()
+ if (!lastClicked && currentlyClicked) {
SkyHanniMod.coroutineScope.launch {
OSUtils.readFromClipboard()?.let {
- LorenzUtils.setTextIntoSign(it.take(15))
+ LorenzUtils.addTextIntoSign(it.take(15))
}
}
}
+ lastClicked = currentlyClicked
}
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt
index 5cfcd881d..351e3123d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/PetCandyUsedDisplay.kt
@@ -3,8 +3,8 @@ package at.hannibal2.skyhanni.features.misc
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.GuiRenderItemEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.RenderUtils.drawSlotText
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetCandyUsed
-import net.minecraft.client.renderer.GlStateManager
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class PetCandyUsedDisplay {
@@ -20,26 +20,9 @@ class PetCandyUsedDisplay {
if (petCandyUsed == 0) return
val stackTip = "§c$petCandyUsed"
-
- GlStateManager.disableLighting()
- GlStateManager.disableDepth()
- GlStateManager.disableBlend()
-
- val fontRenderer = event.fontRenderer
- val x = event.x + 13 - fontRenderer.getStringWidth(stackTip)
+ val x = event.x + 13
val y = event.y + 1
- val scale = 0.9
- GlStateManager.pushMatrix()
- GlStateManager.translate(x.toFloat(), y.toFloat(), 0f)
- GlStateManager.scale(scale, scale, scale)
- fontRenderer.drawStringWithShadow(stackTip, 0f, 0f, 16777215)
- val reverseScale = 1 / 0.7
- GlStateManager.scale(reverseScale, reverseScale, reverseScale)
- GlStateManager.popMatrix()
-
- GlStateManager.enableLighting()
- GlStateManager.enableDepth()
+ event.drawSlotText(x, y, stackTip, .9f)
}
-
-}
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt
index 7b54d9d95..35ed88534 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/PetExpTooltip.kt
@@ -1,15 +1,13 @@
package at.hannibal2.skyhanni.features.misc
import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.utils.ItemUtils
+import at.hannibal2.skyhanni.utils.*
+import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrNull
import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.indexOfFirst
import at.hannibal2.skyhanni.utils.LorenzUtils.round
-import at.hannibal2.skyhanni.utils.NumberUtil
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetExp
-import at.hannibal2.skyhanni.utils.StringUtils
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
import net.minecraftforge.event.entity.player.ItemTooltipEvent
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -27,14 +25,10 @@ class PetExpTooltip {
val petExperience = itemStack.getPetExp()?.round(1) ?: return
val name = itemStack.name ?: return
- val index = event.toolTip.indexOfFirst(
- "§5§o§7§eClick to summon!",
- "§5§o§7§cClick to despawn!",
- "§5§o§7§eRight-click to add this pet to",
- ) ?: return
+ val index = findIndex(event.toolTip) ?: return
val maxLevel = ItemUtils.maxPetLevel(name)
- val maxXp = if (maxLevel == 200) 210255385 else 25353230L
+ val maxXp = maxPetExp(name) // lvl 100 legendary
val percentage = petExperience / maxXp
val percentageFormat = LorenzUtils.formatPercentage(percentage)
@@ -44,8 +38,32 @@ class PetExpTooltip {
event.toolTip.add(index, "§7Total experience: §e${NumberUtil.format(petExperience)}")
} else {
val progressBar = StringUtils.progressBar(percentage)
+ val isBelowLegendary = itemStack.getItemRarityOrNull()?.let { it < LorenzRarity.LEGENDARY } ?: false
+ val addLegendaryColor = if (isBelowLegendary) "§6" else ""
event.toolTip.add(index, "$progressBar §e${petExperience.addSeparators()}§6/§e${NumberUtil.format(maxXp)}")
- event.toolTip.add(index, "§7Progress to Level $maxLevel: §e$percentageFormat")
+ event.toolTip.add(index, "§7Progress to ${addLegendaryColor}Level $maxLevel: §e$percentageFormat")
}
}
+
+ private fun findIndex(toolTip: