aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features/misc
diff options
context:
space:
mode:
authorWalker Selby <git@walkerselby.com>2023-10-21 07:31:19 +0100
committerGitHub <noreply@github.com>2023-10-21 08:31:19 +0200
commit68abc8ade546de62aee76e0b786993fc59fbc3cc (patch)
treebfc1e6fe389c7daf5cbf2ca109be70233d014590 /src/main/java/at/hannibal2/skyhanni/features/misc
parentc5745ed4ee07759261da1dc9c0f654617276f163 (diff)
downloadskyhanni-68abc8ade546de62aee76e0b786993fc59fbc3cc.tar.gz
skyhanni-68abc8ade546de62aee76e0b786993fc59fbc3cc.tar.bz2
skyhanni-68abc8ade546de62aee76e0b786993fc59fbc3cc.zip
Internal Change: Misc Refactoring (#551)
Internal Change: Misc Refactoring #551
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features/misc')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/BestiaryData.kt489
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ChatPeek.kt30
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ChestValue.kt277
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ChickenHeadTimer.kt75
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ChumBucketHider.kt83
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/CompactSplashPotionMessage.kt32
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/EnderNode.kt33
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt239
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/FrozenTreasure.kt19
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/FrozenTreasureTracker.kt167
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/HarpFeatures.kt78
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/HideDamageSplash.kt28
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ThunderSparksHighlight.kt77
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostCounter.kt494
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostData.kt90
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostFormatting.kt182
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostUtil.kt144
-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.kt366
-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/PlayerTabComplete.kt86
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/TabComplete.kt38
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/WarpTabComplete.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/Relay.kt48
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/TiaRelayHelper.kt146
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/TiaRelayWaypoints.kt63
26 files changed, 0 insertions, 3503 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/BestiaryData.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/BestiaryData.kt
deleted file mode 100644
index 211641694..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/BestiaryData.kt
+++ /dev/null
@@ -1,489 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.GuiContainerEvent
-import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.InventoryCloseEvent
-import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
-import at.hannibal2.skyhanni.utils.InventoryUtils
-import at.hannibal2.skyhanni.utils.ItemUtils.getLore
-import at.hannibal2.skyhanni.utils.LorenzColor
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
-import at.hannibal2.skyhanni.utils.LorenzUtils.addButton
-import at.hannibal2.skyhanni.utils.NumberUtil
-import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
-import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
-import at.hannibal2.skyhanni.utils.NumberUtil.roundToPrecision
-import at.hannibal2.skyhanni.utils.NumberUtil.toRoman
-import at.hannibal2.skyhanni.utils.RenderUtils.highlight
-import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
-import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.renderables.Renderable
-import net.minecraft.item.ItemStack
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-
-object BestiaryData {
-
- private val config get() = SkyHanniMod.feature.combat.bestiary
- private var display = emptyList<List<Any>>()
- private val mobList = mutableListOf<BestiaryMob>()
- private val stackList = mutableMapOf<Int, ItemStack>()
- private val catList = mutableListOf<Category>()
- private val progressPattern = "(?<current>[0-9kKmMbB,.]+)/(?<needed>[0-9kKmMbB,.]+$)".toPattern()
- private val titlePattern = "^(?:\\(\\d+/\\d+\\) )?(Bestiary|.+) ➜ (.+)$".toPattern()
- private var inInventory = false
- private var isCategory = false
- private var indexes = listOf(
- 10, 11, 12, 13, 14, 15, 16,
- 19, 20, 21, 22, 23, 24, 25,
- 28, 29, 30, 31, 32, 33, 34,
- 37, 38, 39, 40, 41, 42, 43
- )
-
- @SubscribeEvent
- fun onBackgroundDraw(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) {
- if (!isEnabled()) return
- if (inInventory) {
- config.position.renderStringsAndItems(
- display,
- extraSpace = -1,
- itemScale = 1.3,
- posLabel = "Bestiary Data"
- )
- }
- }
-
- @SubscribeEvent
- fun onRender(event: GuiContainerEvent.BackgroundDrawnEvent) {
- if (!isEnabled()) return
- if (inInventory) {
- for (slot in InventoryUtils.getItemsInOpenChest()) {
- val stack = slot.stack
- val lore = stack.getLore()
- if (lore.any { it == "§7Overall Progress: §b100% §7(§c§lMAX!§7)" || it == "§7Families Completed: §a100%" }) {
- slot highlight LorenzColor.GREEN
- }
- }
- }
- }
-
- @SubscribeEvent
- fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
- if (!isEnabled()) return
- val inventoryName = event.inventoryName
- val stack = event.inventoryItems[4] ?: return
- if ((inventoryName == "Bestiary ➜ Fishing" || inventoryName == "Bestiary") || isBestiaryGui(
- stack,
- inventoryName
- )
- ) {
- isCategory = inventoryName == "Bestiary ➜ Fishing" || inventoryName == "Bestiary"
- stackList.putAll(event.inventoryItems)
- inInventory = true
- update()
- }
- }
-
- @SubscribeEvent
- fun onInventoryClose(event: InventoryCloseEvent) {
- mobList.clear()
- stackList.clear()
- inInventory = false
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "misc.bestiaryData", "combat.bestiary")
- }
-
- private fun update() {
- display = drawDisplay()
- }
-
- private fun init() {
- mobList.clear()
- catList.clear()
- if (isCategory) {
- inCategory()
- } else {
- notInCategory()
- }
- }
-
- private fun inCategory() {
- for ((index, stack) in stackList) {
- if (stack.displayName == " ") continue
- if (!indexes.contains(index)) continue
- inInventory = true
- val name = stack.displayName
- var familiesFound: Long = 0
- var totalFamilies: Long = 0
- var familiesCompleted: Long = 0
- for ((lineIndex, loreLine) in stack.getLore().withIndex()) {
- val line = loreLine.removeColor()
- if (!line.startsWith(" ")) continue
- val previousLine = stack.getLore()[lineIndex - 1]
- val progress = line.substring(line.lastIndexOf(' ') + 1)
- if (previousLine.contains("Families Found")) {
- progressPattern.matchMatcher(progress) {
- familiesFound = group("current").formatNumber()
- totalFamilies = group("needed").formatNumber()
- }
- } else if (previousLine.contains("Families Completed")) {
- progressPattern.matchMatcher(progress) {
- familiesCompleted = group("current").formatNumber()
- }
- }
- }
- catList.add(Category(name, familiesFound, totalFamilies, familiesCompleted))
- }
- }
-
- private fun notInCategory() {
- for ((index, stack) in stackList) {
- if (stack.displayName == " ") continue
- if (!indexes.contains(index)) continue
- inInventory = true
- val name = " [IVX0-9]+$".toPattern().matcher(stack.displayName).replaceFirst("")
- val level = " ([IVX0-9]+$)".toRegex().find(stack.displayName)?.groupValues?.get(1) ?: "0"
- var totalKillToMax: Long = 0
- var currentTotalKill: Long = 0
- var totalKillToTier: Long = 0
- var currentKillToTier: Long = 0
- var actualRealTotalKill: Long = 0
- for ((lineIndex, line) in stack.getLore().withIndex()) {
- val loreLine = line.removeColor()
- if (loreLine.startsWith("Kills: ")) {
- actualRealTotalKill =
- "([0-9,.]+)".toRegex().find(loreLine)?.groupValues?.get(1)?.formatNumber()
- ?: 0
- }
- if (!loreLine.startsWith(" ")) continue
- val previousLine = stack.getLore()[lineIndex - 1]
- val progress = loreLine.substring(loreLine.lastIndexOf(' ') + 1)
- if (previousLine.contains("Progress to Tier")) {
- progressPattern.matchMatcher(progress) {
- totalKillToTier = group("needed").formatNumber()
- currentKillToTier = group("current").formatNumber()
- }
- } else if (previousLine.contains("Overall Progress")) {
- progressPattern.matchMatcher(progress) {
- totalKillToMax = group("needed").formatNumber()
- currentTotalKill = group("current").formatNumber()
- }
- }
- }
- mobList.add(
- BestiaryMob(
- name,
- level,
- totalKillToMax,
- currentTotalKill,
- totalKillToTier,
- currentKillToTier,
- actualRealTotalKill
- )
- )
- }
- }
-
- private fun drawDisplay(): List<List<Any>> {
- val newDisplay = mutableListOf<List<Any>>()
- init()
-
- addCategories(newDisplay)
-
- if (mobList.isEmpty()) return newDisplay
-
- addList(newDisplay)
-
- addButtons(newDisplay)
-
- return newDisplay
- }
-
- private fun sortMobList(): MutableList<BestiaryMob> {
- val sortedMobList = when (config.displayType) {
- 0 -> mobList.sortedBy { it.percentToMax() }
- 1 -> mobList.sortedBy { it.percentToTier() }
- 2 -> mobList.sortedBy { it.totalKills }
- 3 -> mobList.sortedByDescending { it.totalKills }
- 4 -> mobList.sortedBy { it.killNeededToMax() }
- 5 -> mobList.sortedByDescending { it.killNeededToMax() }
- 6 -> mobList.sortedBy { it.killNeededToNextLevel() }
- 7 -> mobList.sortedByDescending { it.killNeededToNextLevel() }
- else -> mobList.sortedBy { it.totalKills }
- }.toMutableList()
- return sortedMobList
- }
-
- private fun addList(newDisplay: MutableList<List<Any>>) {
- val sortedMobList = sortMobList()
-
- newDisplay.addAsSingletonList("§7Bestiary Data")
- for (mob in sortedMobList) {
- val isUnlocked = mob.totalKills != 0.toLong()
- val isMaxed = mob.percentToMax() >= 1
- if (!isUnlocked) {
- newDisplay.add(buildList {
- add(" §7- ")
- add("${mob.name}: §cNot unlocked!")
- })
- continue
- }
- if (isMaxed && config.hideMaxed) continue
- val text = getMobLine(mob, isMaxed)
- val tips = getMobHover(mob)
- newDisplay.addAsSingletonList(Renderable.hoverTips(text, tips) { true })
- }
- }
-
- private fun getMobHover(mob: BestiaryMob) = listOf(
- "§6Name: §b${mob.name}",
- "§6Level: §b${mob.level} ${if (!config.replaceRoman) "§7(${mob.level.romanToDecimalIfNeeded()})" else ""}",
- "§6Total Kills: §b${mob.actualRealTotalKill.formatNumber()}",
- "§6Kills needed to max: §b${mob.killNeededToMax().formatNumber()}",
- "§6Kills needed to next lvl: §b${mob.killNeededToNextLevel().formatNumber()}",
- "§6Current kill to next level: §b${mob.currentKillToNextLevel.formatNumber()}",
- "§6Kill needed for next level: §b${mob.killNeededForNextLevel.formatNumber()}",
- "§6Current kill to max: §b${mob.killToMax.formatNumber()}",
- "§6Percent to max: §b${mob.percentToMaxFormatted()}",
- "§6Percent to tier: §b${mob.percentToTierFormatted()}",
- "",
- "§7More info thing"
- )
-
- private fun getMobLine(
- mob: BestiaryMob,
- isMaxed: Boolean
- ): String {
- val displayType = config.displayType
- var text = ""
- text += " §7- "
- text += "${mob.name} ${mob.level.romanOrInt()} "
- text += if (isMaxed) {
- "§c§lMAXED! §7(§b${mob.actualRealTotalKill.formatNumber()}§7 kills)"
- } else {
- when (displayType) {
- 0, 1 -> {
- val currentKill = when (displayType) {
- 0 -> mob.totalKills
- 1 -> mob.currentKillToNextLevel
- else -> 0
- }
- val killNeeded = when (displayType) {
- 0 -> mob.killToMax
- 1 -> mob.killNeededForNextLevel
- else -> 0
- }
- "§7(§b${currentKill.formatNumber()}§7/§b${killNeeded.formatNumber()}§7) §a${
- ((currentKill.toDouble() / killNeeded) * 100).roundToPrecision(
- 2
- )
- }§6% ${if (displayType == 1) "§ato level ${mob.getNextLevel()}" else ""}"
- }
-
- 2, 3 -> {
-
- "§6${mob.totalKills.formatNumber()} §7total kills"
- }
-
- 4, 5 -> {
- "§6${mob.killNeededToMax().formatNumber()} §7kills needed"
- }
-
- 6, 7 -> {
- "§6${mob.killNeededToNextLevel().formatNumber()} §7kills needed"
- }
-
- else -> "§cYou are not supposed to see this, please report it to @HiZe on discord!"
- }
- }
- return text
- }
-
- private fun addButtons(newDisplay: MutableList<List<Any>>) {
- newDisplay.addButton(
- prefix = "§7Number Format: ",
- getName = FormatType.entries[config.numberFormat].type,
- onChange = {
- config.numberFormat = (config.numberFormat + 1) % 2
- update()
- })
-
- newDisplay.addButton(
- prefix = "§7Display Type: ",
- getName = DisplayType.entries[config.displayType].type,
- onChange = {
- config.displayType = (config.displayType + 1) % 8
- update()
- })
-
- newDisplay.addButton(
- prefix = "§7Number Type: ",
- getName = NumberType.entries[if (config.replaceRoman) 0 else 1].type,
- onChange = {
- config.replaceRoman = !config.replaceRoman
- update()
- }
- )
- newDisplay.addButton(
- prefix = "§7Hide Maxed: ",
- getName = HideMaxed.entries[if (config.hideMaxed) 1 else 0].type,
- onChange = {
- config.hideMaxed = !config.hideMaxed
- update()
- }
- )
- }
-
- private fun addCategories(newDisplay: MutableList<List<Any>>) {
- if (catList.isNotEmpty()) {
- newDisplay.addAsSingletonList("§7Category")
- for (cat in catList) {
- newDisplay.add(buildList {
- add(" §7- ${cat.name}§7: ")
- val element = when {
- cat.familiesCompleted == cat.totalFamilies -> "§c§lCompleted!"
- cat.familiesFound == cat.totalFamilies -> "§b${cat.familiesCompleted}§7/§b${cat.totalFamilies} §7completed"
- cat.familiesFound < cat.totalFamilies ->
- "§b${cat.familiesFound}§7/§b${cat.totalFamilies} §7found, §b${cat.familiesCompleted}§7/§b${cat.totalFamilies} §7completed"
-
- else -> continue
- }
- add(element)
- })
- }
- }
- }
-
- private fun isBestiaryGui(stack: ItemStack?, name: String): Boolean {
- if (stack == null) return false
- val bestiaryGuiTitleMatcher = titlePattern.matcher(name)
- if (bestiaryGuiTitleMatcher.matches()) {
- if ("Bestiary" != bestiaryGuiTitleMatcher.group(1)) {
- var loreContainsFamiliesFound = false
- for (line in stack.getLore()) {
- if (line.removeColor().startsWith("Families Found")) {
- loreContainsFamiliesFound = true
- break
- }
- }
- if (!loreContainsFamiliesFound) {
- return false
- }
- }
- return true
- } else if (name == "Search Results") {
- val loreList = stack.getLore()
- if (loreList.size >= 2 && loreList[0].startsWith("§7Query: §a")
- && loreList[1].startsWith("§7Results: §a")
- ) {
- return true
- }
- }
- return false
- }
-
- enum class FormatType(val type: String) {
- SHORT("Short"),
- LONG("Long")
- }
-
- enum class NumberType(val type: String) {
- INT("Normal (1, 2, 3)"),
- ROMAN("Roman (I, II, III")
- }
-
- enum class DisplayType(val type: String) {
- GLOBAL_MAX("Global display (to max)"),
- GLOBAL_TIER("Global display (to next tier)"),
- LOWEST_TOTAL("Lowest total kills"),
- HIGHEST_TOTAL("Highest total kills"),
- LOWEST_NEEDED_MAX("Lowest kills needed to max"),
- HIGHEST_NEEDED_MAX("Highest kills needed to max"),
- LOWEST_NEEDED_TIER("Lowest kills needed to next tier"),
- HIGHEST_NEEDED_TIER("Highest kills needed to next tier"),
- }
-
- enum class HideMaxed(val type: String) {
- NO("Show"),
- YES("Hide")
- }
-
- private fun Long.formatNumber(): String = when (config.numberFormat) {
- 0 -> NumberUtil.format(this)
- 1 -> this.addSeparators()
- else -> "0"
- }
-
- data class Category(
- val name: String,
- val familiesFound: Long,
- val totalFamilies: Long,
- val familiesCompleted: Long
- )
-
- data class BestiaryMob(
- var name: String,
- var level: String,
- var killToMax: Long,
- var totalKills: Long,
- var killNeededForNextLevel: Long,
- var currentKillToNextLevel: Long,
- var actualRealTotalKill: Long
- ) {
-
- fun killNeededToMax(): Long {
- return 0L.coerceAtLeast(killToMax - totalKills)
- }
-
- fun killNeededToNextLevel(): Long {
- return 0L.coerceAtLeast(killNeededForNextLevel - currentKillToNextLevel)
- }
-
- fun percentToMax() = totalKills.toDouble() / killToMax
-
- fun percentToMaxFormatted() = LorenzUtils.formatPercentage(percentToMax())
-
- fun percentToTier() = currentKillToNextLevel.toDouble() / killNeededForNextLevel
-
- fun percentToTierFormatted() = LorenzUtils.formatPercentage(percentToTier())
-
- fun getNextLevel() = level.getNextLevel()
- }
-
-
- private fun String.romanOrInt() = romanToDecimalIfNeeded().let {
- if (config.replaceRoman || it == 0) it.toString() else it.toRoman()
- }
-
- fun Any.getNextLevel(): String {
- return when (this) {
- is Int -> {
- (this + 1).toString().romanOrInt()
- }
-
- is String -> {
- if (this == "0") {
- "I".romanOrInt()
- } else {
- val intValue = romanToDecimalIfNeeded()
- (intValue + 1).toRoman().romanOrInt()
- }
- }
-
- else -> {
- "Unsupported type: ${this::class.simpleName}"
- }
- }
- }
-
- private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
-
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ChatPeek.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ChatPeek.kt
deleted file mode 100644
index b92375f10..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/ChatPeek.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.data.GuiEditManager
-import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI
-import at.hannibal2.skyhanni.features.misc.visualwords.VisualWordGui
-import at.hannibal2.skyhanni.utils.NEUItems
-import io.github.moulberry.moulconfig.gui.GuiScreenElementWrapper
-import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.inventory.GuiEditSign
-import org.lwjgl.input.Keyboard
-
-
-object ChatPeek {
- @JvmStatic
- fun peek(): Boolean {
- val key = SkyHanniMod.feature.chat.peekChat
-
- if (Minecraft.getMinecraft().thePlayer == null) return false
- if (key <= Keyboard.KEY_NONE) return false
- if (Minecraft.getMinecraft().currentScreen is GuiEditSign) return false
- if (Minecraft.getMinecraft().currentScreen is GuiScreenElementWrapper) return false
-
- if (NEUItems.neuHasFocus()) return false
- if (GuiEditManager.isInGui() || FFGuideGUI.isInGui() || VisualWordGui.isInGui()) return false
-
- return key.isKeyHeld()
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ChestValue.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ChestValue.kt
deleted file mode 100644
index 82db5d451..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/ChestValue.kt
+++ /dev/null
@@ -1,277 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.data.IslandType
-import at.hannibal2.skyhanni.events.GuiContainerEvent
-import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.InventoryCloseEvent
-import at.hannibal2.skyhanni.events.InventoryOpenEvent
-import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue
-import at.hannibal2.skyhanni.utils.InventoryUtils
-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.addButton
-import at.hannibal2.skyhanni.utils.NEUInternalName
-import at.hannibal2.skyhanni.utils.NEUItems.getItemStackOrNull
-import at.hannibal2.skyhanni.utils.NumberUtil
-import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
-import at.hannibal2.skyhanni.utils.RenderUtils.highlight
-import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
-import at.hannibal2.skyhanni.utils.SpecialColour
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.renderables.Renderable
-import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.inventory.GuiChest
-import net.minecraft.init.Items
-import net.minecraft.item.ItemStack
-import net.minecraftforge.fml.common.eventhandler.EventPriority
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import java.awt.Color
-
-class ChestValue {
-
- private val config get() = SkyHanniMod.feature.inventory.chestValueConfig
- private var display = emptyList<List<Any>>()
- private val chestItems = mutableMapOf<NEUInternalName, Item>()
- private val inInventory get() = isValidStorage()
-
- @SubscribeEvent
- fun onBackgroundDraw(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) {
- if (!isEnabled()) return
- if (InventoryUtils.openInventoryName() == "") return
- if (inInventory) {
- config.position.renderStringsAndItems(
- display,
- extraSpace = -1,
- itemScale = 1.3,
- posLabel = "Estimated Chest Value"
- )
- }
- }
-
- @SubscribeEvent
- fun onTick(event: LorenzTickEvent) {
- if (!isEnabled()) return
- if (event.isMod(5)) {
- update()
- }
- }
-
- @SubscribeEvent
- fun onInventoryOpen(event: InventoryOpenEvent) {
- if (!isEnabled()) return
- if (inInventory) {
- update()
- }
- }
-
- @SubscribeEvent
- fun onInventoryClose(event: InventoryCloseEvent) {
- chestItems.clear()
- Renderable.list.clear()
- }
-
- @SubscribeEvent(priority = EventPriority.LOW)
- fun onDrawBackground(event: GuiContainerEvent.BackgroundDrawnEvent) {
- if (!isEnabled()) return
- if (!config.enableHighlight) return
- if (inInventory) {
- for ((_, indexes) in Renderable.list) {
- for (slot in InventoryUtils.getItemsInOpenChest()) {
- if (indexes.contains(slot.slotIndex)) {
- slot highlight Color(SpecialColour.specialToChromaRGB(config.highlightColor), true)
- }
- }
- }
- }
- }
-
- private fun update() {
- display = drawDisplay()
- }
-
- private fun drawDisplay(): List<List<Any>> {
- val newDisplay = mutableListOf<List<Any>>()
-
- init()
-
- if (chestItems.isEmpty()) return newDisplay
-
- addList(newDisplay)
- addButton(newDisplay)
-
- return newDisplay
- }
-
- private fun addList(newDisplay: MutableList<List<Any>>) {
- val sortedList = sortedList()
- var totalPrice = 0.0
- var rendered = 0
- val amountShowing = if (config.itemToShow > sortedList.size) sortedList.size else config.itemToShow
- newDisplay.addAsSingletonList("§7Estimated Chest Value: §o(Showing $amountShowing of ${sortedList.size} items)")
- for ((index, amount, stack, total, tips) in sortedList) {
- totalPrice += total
- if (rendered >= config.itemToShow) continue
- if (total < config.hideBelow) continue
- val textAmount = " §7x$amount:"
- val width = Minecraft.getMinecraft().fontRendererObj.getStringWidth(textAmount)
- val name = "${stack.displayName.reduceStringLength((config.nameLength - width), ' ')} $textAmount"
- val price = "§b${(total).formatPrice()}"
- val text = if (config.alignedDisplay)
- "$name $price"
- else
- "${stack.displayName} §7x$amount: §b${total.formatPrice()}"
- newDisplay.add(buildList {
- val renderable = Renderable.hoverTips(
- text,
- tips,
- stack = stack,
- indexes = index
- )
- add(" §7- ")
- if (config.showStacks) add(stack)
- add(renderable)
- })
- rendered++
- }
- newDisplay.addAsSingletonList("§6Total value : §b${totalPrice.formatPrice()}")
- }
-
- private fun sortedList(): MutableList<Item> {
- return when (config.sortingType) {
- 0 -> chestItems.values.sortedByDescending { it.total }
- 1 -> chestItems.values.sortedBy { it.total }
- else -> chestItems.values.sortedByDescending { it.total }
- }.toMutableList()
- }
-
- private fun addButton(newDisplay: MutableList<List<Any>>) {
- newDisplay.addButton("§7Sorted By: ",
- getName = SortType.entries[config.sortingType].longName,
- onChange = {
- config.sortingType = (config.sortingType + 1) % 2
- update()
- })
-
- newDisplay.addButton("§7Value format: ",
- getName = FormatType.entries[config.formatType].type,
- onChange = {
- config.formatType = (config.formatType + 1) % 2
- update()
- })
-
- newDisplay.addButton("§7Display Type: ",
- getName = DisplayType.entries[if (config.alignedDisplay) 1 else 0].type,
- onChange = {
- config.alignedDisplay = !config.alignedDisplay
- update()
- })
- }
-
- private fun init() {
- if (inInventory) {
- val isMinion = InventoryUtils.openInventoryName().contains(" Minion ")
- val slots = InventoryUtils.getItemsInOpenChest().filter {
- it.hasStack && it.inventory != Minecraft.getMinecraft().thePlayer.inventory && (!isMinion || it.slotNumber % 9 != 1)
- }
- val stacks = buildMap {
- slots.forEach {
- put(it.slotIndex, it.stack)
- }
- }
- chestItems.clear()
- for ((i, stack) in stacks) {
- val internalName = stack.getInternalNameOrNull() ?: continue
- if (internalName.getItemStackOrNull() == null) continue
- val list = mutableListOf<String>()
- val pair = EstimatedItemValue.getEstimatedItemPrice(stack, list)
- var (total, _) = pair
- if (stack.item == Items.enchanted_book)
- total /= 2
- list.add("§aTotal: §6§l${total.formatPrice()}")
- if (total == 0.0) continue
- val item = chestItems.getOrPut(internalName) {
- Item(mutableListOf(), 0, stack, 0.0, list)
- }
- item.index.add(i)
- item.amount += stack.stackSize
- item.total += total * stack.stackSize
- }
- }
- }
-
- private fun Double.formatPrice(): String {
- return when (config.formatType) {
- 0 -> if (this > 1_000_000_000) NumberUtil.format(this, true) else NumberUtil.format(this)
- 1 -> this.addSeparators()
- else -> "0"
- }
- }
-
- enum class SortType(val shortName: String, val longName: String) {
- PRICE_DESC("Price D", "Price Descending"),
- PRICE_ASC("Price A", "Price Ascending")
- ;
- }
-
- enum class FormatType(val type: String) {
- SHORT("Formatted"),
- LONG("Unformatted")
- ;
- }
-
- enum class DisplayType(val type: String) {
- NORMAL("Normal"),
- COMPACT("Aligned")
- }
-
- private fun isValidStorage(): Boolean {
- val name = InventoryUtils.openInventoryName().removeColor()
- if (Minecraft.getMinecraft().currentScreen !is GuiChest) return false
-
- if ((name.contains("Backpack") && name.contains("Slot #") || name.startsWith("Ender Chest (")) &&
- !InventoryUtils.isNeuStorageEnabled.getValue()
- ) {
- return true
- }
-
- val inMinion = name.contains("Minion") && !name.contains("Recipe") &&
- LorenzUtils.skyBlockIsland == IslandType.PRIVATE_ISLAND
- return name == "Chest" || name == "Large Chest" || inMinion || name == "Personal Vault"
- }
-
- private fun String.reduceStringLength(targetLength: Int, char: Char): String {
- val mc = Minecraft.getMinecraft()
- val spaceWidth = mc.fontRendererObj.getCharWidth(char)
-
- var currentString = this
- var currentLength = mc.fontRendererObj.getStringWidth(currentString)
-
- while (currentLength > targetLength) {
- currentString = currentString.dropLast(1)
- currentLength = mc.fontRendererObj.getStringWidth(currentString)
- }
-
- val difference = targetLength - currentLength
-
- if (difference > 0) {
- val numSpacesToAdd = difference / spaceWidth
- val spaces = " ".repeat(numSpacesToAdd)
- return currentString + spaces
- }
-
- return currentString
- }
-
- data class Item(
- val index: MutableList<Int>,
- var amount: Int,
- val stack: ItemStack,
- var total: Double,
- val tips: MutableList<String>
- )
-
- private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ChickenHeadTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ChickenHeadTimer.kt
deleted file mode 100644
index c43f1f623..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/ChickenHeadTimer.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.utils.InventoryUtils
-import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.RenderUtils.renderString
-import at.hannibal2.skyhanni.utils.TimeUtils
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-class ChickenHeadTimer {
- private var hasChickenHead = false
- private var lastTime = 0L
- private val config get() = SkyHanniMod.feature.itemAbilities.chickenHead
-
- @SubscribeEvent
- fun onTick(event: LorenzTickEvent) {
- if (!isEnabled()) return
- if (!event.isMod(5)) return
-
- val itemStack = InventoryUtils.getArmor()[3]
- val name = itemStack?.name ?: ""
- hasChickenHead = name.contains("Chicken Head")
- }
-
- @SubscribeEvent
- fun onWorldChange(event: LorenzWorldChangeEvent) {
- lastTime = System.currentTimeMillis()
- }
-
- @SubscribeEvent
- fun onChatMessage(event: LorenzChatEvent) {
- if (!isEnabled()) return
- if (!hasChickenHead) return
- if (event.message == "§aYou laid an egg!") {
- lastTime = System.currentTimeMillis()
- if (config.hideChat) {
- event.blockedReason = "chicken_head_timer"
- }
- }
- }
-
- @SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
- if (!isEnabled()) return
- if (!hasChickenHead) return
-
- val sinceLastTime = System.currentTimeMillis() - lastTime
- val cooldown = 5_000
- val remainingTime = cooldown - sinceLastTime
-
- val displayText = if (remainingTime < 0) {
- "Chicken Head Timer: §aNow"
- } else {
- val formatDuration = TimeUtils.formatDuration(remainingTime)
- "Chicken Head Timer: §b$formatDuration"
- }
-
- config.position.renderString(displayText, posLabel = "Chicken Head Timer")
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "misc.chickenHeadTimerHideChat", "itemAbilities.chickenHead.hideChat")
- event.move(2, "misc.chickenHeadTimerPosition", "itemAbilities.chickenHead.position")
- event.move(2, "misc.chickenHeadTimerDisplay", "itemAbilities.chickenHead.displayTimer")
- }
-
- fun isEnabled() = LorenzUtils.inSkyBlock && config.displayTimer
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ChumBucketHider.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ChumBucketHider.kt
deleted file mode 100644
index 5a0b6fe86..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/ChumBucketHider.kt
+++ /dev/null
@@ -1,83 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.events.CheckRenderEntityEvent
-import at.hannibal2.skyhanni.events.ConfigLoadEvent
-import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.onToggle
-import at.hannibal2.skyhanni.utils.getLorenzVec
-import net.minecraft.entity.Entity
-import net.minecraft.entity.item.EntityArmorStand
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-class ChumBucketHider {
- private val config get() = SkyHanniMod.feature.fishing.chumBucketHider
- private val titleEntity = mutableListOf<Entity>()
- private val hiddenEntities = mutableListOf<Entity>()
-
- @SubscribeEvent
- fun onWorldChange(event: LorenzWorldChangeEvent) {
- reset()
- }
-
- @SubscribeEvent
- fun onCheckRender(event: CheckRenderEntityEvent<*>) {
- if (!LorenzUtils.inSkyBlock) return
- if (!config.enabled.get()) return
-
- val entity = event.entity
- if (entity !is EntityArmorStand) return
-
- if (entity in hiddenEntities) {
- event.isCanceled = true
- return
- }
-
- val name = entity.name
-
- // First text line
- if (name.endsWith("'s Chum Bucket") || name.endsWith("'s Chumcap Bucket")) {
- if (name.contains(LorenzUtils.getPlayerName()) && !config.hideOwn.get()) return
- titleEntity.add(entity)
- hiddenEntities.add(entity)
- event.isCanceled = true
- return
- }
-
- // Second text line
- if (name.contains("/10 §aChums")) {
- val entityLocation = entity.getLorenzVec()
- for (title in titleEntity) {
- if (entityLocation.equalsIgnoreY(title.getLorenzVec())) {
- hiddenEntities.add(entity)
- event.isCanceled = true
- return
- }
- }
- }
-
- // Chum Bucket
- if (config.hideBucket.get() && entity.inventory.any { it != null && (it.name == "§fEmpty Chum Bucket" || it.name == "§aEmpty Chumcap Bucket") }) {
- val entityLocation = entity.getLorenzVec()
- for (title in titleEntity) {
- if (entityLocation.equalsIgnoreY(title.getLorenzVec())) {
- hiddenEntities.add(entity)
- event.isCanceled = true
- return
- }
- }
- }
- }
-
- @SubscribeEvent
- fun onConfigLoad(event: ConfigLoadEvent) {
- onToggle(config.enabled, config.hideBucket, config.hideOwn) { reset() }
- }
-
- private fun reset() {
- titleEntity.clear()
- hiddenEntities.clear()
- }
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/CompactSplashPotionMessage.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/CompactSplashPotionMessage.kt
deleted file mode 100644
index 932cdb1bf..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/CompactSplashPotionMessage.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import net.minecraft.util.ChatComponentText
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-class CompactSplashPotionMessage {
- private val potionEffectPattern =
- "§a§lBUFF! §fYou have gained §r(?<name>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern()
- private val potionEffectOthersPattern =
- "§a§lBUFF! §fYou were splashed by (?<playerName>.*) §fwith §r(?<effectName>.*)§r§f! Press TAB or type /effects to view your active effects!".toPattern()
-
- @SubscribeEvent
- fun onChatMessage(event: LorenzChatEvent) {
- if (!LorenzUtils.inSkyBlock || !SkyHanniMod.feature.chat.compactPotionMessage) return
-
- potionEffectPattern.matchMatcher(event.message) {
- val name = group("name")
- event.chatComponent = ChatComponentText("§a§lPotion Effect! §r$name")
- }
-
- potionEffectOthersPattern.matchMatcher(event.message) {
- val playerName = group("playerName").removeColor()
- val effectName = group("effectName")
- event.chatComponent = ChatComponentText("§a§lPotion Effect! §r$effectName by §b$playerName")
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNode.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNode.kt
deleted file mode 100644
index 301dc65e2..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNode.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.utils.NEUInternalName
-import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
-
-enum class EnderNode(
- val internalName: NEUInternalName,
- val displayName: String,
-) {
-
- ENCHANTED_ENDSTONE("ENCHANTED_ENDSTONE".asInternalName(), "§aEnchanted End Stone"),
- ENCHANTED_OBSIDIAN("ENCHANTED_OBSIDIAN".asInternalName(), "§aEnchanted Obsidian"),
- ENCHANTED_ENDER_PEARL("ENCHANTED_ENDER_PEARL".asInternalName(), "§aEnchanted Ender Pearl"),
- GRAND_EXP_BOTTLE("GRAND_EXP_BOTTLE".asInternalName(), "§aGrand Experience Bottle"),
- TITANIC_EXP_BOTTLE("TITANIC_EXP_BOTTLE".asInternalName(), "§9Titanic Experience Bottle"),
- END_STONE_SHULKER("END_STONE_SHULKER".asInternalName(), "§9End Stone Shulker"),
- ENDSTONE_GEODE("ENDSTONE_GEODE".asInternalName(), "§9End Stone Geode"),
- MAGIC_RUNE("MAGIC_RUNE;1".asInternalName(), "§d◆ Magical Rune I"),
- ENDER_GAUNTLET("ENDER_GAUNTLET".asInternalName(), "§5Ender Gauntlet"),
- MITE_GEL("MITE_GEL".asInternalName(), "§5Mite Gel"),
- SHRIMP_THE_FISH("SHRIMP_THE_FISH".asInternalName(), "§cShrimp the Fish"),
-
- END_HELMET("END_HELMET".asInternalName(), "§5Ender Helmet"),
- END_CHESTPLATE("END_CHESTPLATE".asInternalName(), "§5Ender Chestplate"),
- END_LEGGINGS("END_LEGGINGS".asInternalName(), "§5Ender Leggings"),
- END_BOOTS("END_BOOTS".asInternalName(), "§5Ender Boots"),
- ENDER_NECKLACE("ENDER_NECKLACE".asInternalName(), "§5Ender Necklace"),
- COMMON_ENDERMAN_PET("ENDERMAN;0".asInternalName(), "§fEnderman"),
- UNCOMMON_ENDERMAN_PET("ENDERMAN;1".asInternalName(), "§aEnderman"),
- RARE_ENDERMAN_PET("ENDERMAN;2".asInternalName(), "§9Enderman"),
- EPIC_ENDERMAN_PET("ENDERMAN;3".asInternalName(), "§5Enderman"),
- LEGENDARY_ENDERMAN_PET("ENDERMAN;4".asInternalName(), "§6Enderman")
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt
deleted file mode 100644
index d07ae0ef2..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt
+++ /dev/null
@@ -1,239 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.config.Storage
-import at.hannibal2.skyhanni.data.IslandType
-import at.hannibal2.skyhanni.data.ProfileStorageData
-import at.hannibal2.skyhanni.events.ConfigLoadEvent
-import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.IslandChangeEvent
-import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.events.OwnInventoryItemUpdateEvent
-import at.hannibal2.skyhanni.events.SackChangeEvent
-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.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.combat.enderNodeTracker
- private val storage get() = ProfileStorageData.profileSpecific?.enderNodeTracker
-
- private var totalEnderArmor = 0
- private var miteGelInInventory = 0
- private var display = emptyList<List<Any>>()
- 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\(""")
-
- @SubscribeEvent
- fun onChat(event: LorenzChatEvent) {
- if (!config.enabled) return
- if (!ProfileStorageData.loaded) return
- if (!isInTheEnd()) return
-
- // don't call removeColor because we want to distinguish enderman pet rarity
- 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 {
- storage.totalNodesMined++
- amount = it.groups[1]?.value?.substringBefore("x")?.toIntOrNull() ?: 1
- item = it.groups[2]?.value
- } ?: endermanRegex.find(message)?.let {
- amount = 1
- item = it.groups[2]?.value
- }
-
- when {
- item == null -> return
- isEnderArmor(item) -> totalEnderArmor++
- item == "§cEndermite Nest" -> {
- storage.totalEndermiteNests++
- }
- }
-
- // increment the count of the specific item found
- EnderNode.entries.find { it.displayName == item }?.let {
- val old = storage.lootCount[it] ?: 0
- storage.lootCount = storage.lootCount.editCopy {
- this[it] = old + amount
- }
- }
- 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 onInventoryUpdate(event: OwnInventoryItemUpdateEvent) {
- if (!config.enabled) return
- if (!isInTheEnd()) return
- 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
- }
- }
-
- @SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
- if (!config.enabled) return
- if (!isInTheEnd()) return
- config.position.renderStringsAndItems(display, posLabel = "Ender Node Tracker")
- }
-
- @SubscribeEvent
- fun onConfigLoad(event: ConfigLoadEvent) {
- config.textFormat.afterChange {
- update()
- }
- val storage = storage ?: return
-
- totalEnderArmor = storage.lootCount.filter { isEnderArmor(it.key.displayName) }
- .map { it.value }
- .sum()
- update()
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "misc.enderNodeTracker", "combat.enderNodeTracker")
- }
-
- private fun calculateProfit(storage: Storage.ProfileSpecific.EnderNodeTracker): Map<EnderNode, Double> {
- if (!ProfileStorageData.loaded) return emptyMap()
-
- val newProfit = mutableMapOf<EnderNode, Double>()
- storage.lootCount.forEach { (item, amount) ->
- val price = if (isEnderArmor(item.displayName)) {
- 10_000.0
- } else {
- (if (!LorenzUtils.noTradeMode) item.internalName.getPriceOrNull() else 0.0)
- ?.coerceAtLeast(item.internalName.getNpcPriceOrNull() ?: 0.0)
- ?.coerceAtLeast(georgePrice(item) ?: 0.0)
- ?: 0.0
- }
- newProfit[item] = price * amount
- }
- return newProfit
- }
-
- private fun update() {
- val storage = storage ?: return
- lootProfit = calculateProfit(storage)
- display = formatDisplay(drawDisplay(storage))
- }
-
- private fun isInTheEnd() = LorenzUtils.skyBlockArea == "The End"
-
- private fun isEnderArmor(displayName: String?) = when (displayName) {
- 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
- }
-
- private fun georgePrice(petRarity: EnderNode): Double? = when (petRarity) {
- EnderNode.COMMON_ENDERMAN_PET -> 100.0
- EnderNode.UNCOMMON_ENDERMAN_PET -> 500.0
- EnderNode.RARE_ENDERMAN_PET -> 2_000.0
- EnderNode.EPIC_ENDERMAN_PET -> 10_000.0
- EnderNode.LEGENDARY_ENDERMAN_PET -> 1_000_000.0
- else -> null
- }
-
- private fun drawDisplay(storage: Storage.ProfileSpecific.EnderNodeTracker) = buildList<List<Any>> {
- if (!ProfileStorageData.loaded) return emptyList<List<Any>>()
-
- addAsSingletonList("§5§lEnder Node Tracker")
- addAsSingletonList("§d${storage.totalNodesMined.addSeparators()} Ender Nodes mined")
- addAsSingletonList("§6${format(lootProfit.values.sum())} Coins made")
- addAsSingletonList(" ")
- addAsSingletonList("§b${storage.totalEndermiteNests.addSeparators()} §cEndermite Nest")
-
- for (item in EnderNode.entries.subList(0, 11)) {
- val count = (storage.lootCount[item] ?: 0).addSeparators()
- val profit = format(lootProfit[item] ?: 0.0)
- addAsSingletonList("§b$count ${item.displayName} §7(§6$profit§7)")
- }
- addAsSingletonList(" ")
- addAsSingletonList(
- "§b${totalEnderArmor.addSeparators()} §5Ender Armor " +
- "§7(§6${format(totalEnderArmor * 10_000)}§7)"
- )
- for (item in EnderNode.entries.subList(11, 16)) {
- 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 { (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])
- }
- return newList
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/FrozenTreasure.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/FrozenTreasure.kt
deleted file mode 100644
index e2c70cedc..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/FrozenTreasure.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-enum class FrozenTreasure(
- val internalName: String,
- val displayName: String,
- val defaultAmount: Int,
- val iceMultiplier: Int = 0,
-) {
- WHITE_GIFT("WHITE_GIFT", "§fWhite Gift", 1),
- GREEN_GIFT("GREEN_GIFT", "§aGreen Gift", 1),
- RED_GIFT("RED_GIFT", "§9§cRed Gift", 1),
- PACKED_ICE("PACKED_ICE", "§fPacked Ice", 32, 9),
- ENCHANTED_ICE("ENCHANTED_ICE", "§aEnchanted Ice", 9, 160), // wiki says 1-16 so assuming 9
- ENCHANTED_PACKED_ICE("ENCHANTED_PACKED_ICE", "§9Enchanted Packed Ice", 1, 25600),
- ICE_BAIT("ICE_BAIT", "§aIce Bait", 16),
- GLOWY_CHUM_BAIT("GLOWY_CHUM_BAIT", "§aGlowy Chum Bait", 16),
- GLACIAL_FRAGMENT("GLACIAL_FRAGMENT", "§5Glacial Fragment", 1),
- GLACIAL_TALISMAN("GLACIAL_TALISMAN", "§fGlacial Talisman", 1)
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/FrozenTreasureTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/FrozenTreasureTracker.kt
deleted file mode 100644
index 21e28319d..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/FrozenTreasureTracker.kt
+++ /dev/null
@@ -1,167 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-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.GuiRenderEvent
-import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.events.PreProfileSwitchEvent
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
-import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy
-import at.hannibal2.skyhanni.utils.NumberUtil
-import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
-import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
-import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import kotlin.concurrent.fixedRateTimer
-
-class FrozenTreasureTracker {
- private val config get() = SkyHanniMod.feature.event.winter.frozenTreasureTracker
- private var display = emptyList<List<Any>>()
- private var estimatedIce = 0L
- private var lastEstimatedIce = 0L
- private var icePerSecond = mutableListOf<Long>()
- private var icePerHour = 0
- private var stoppedChecks = 0
- private var compactPattern = "COMPACT! You found an Enchanted Ice!".toPattern()
-
- init {
- fixedRateTimer(name = "skyhanni-frozen-treasure-tracker", period = 1000) {
- if (!onJerryWorkshop()) return@fixedRateTimer
- calculateIcePerHour()
- }
- }
-
- @SubscribeEvent
- fun onWorldChange(event: LorenzWorldChangeEvent) {
- icePerHour = 0
- stoppedChecks = 0
- icePerSecond = mutableListOf()
- saveAndUpdate()
- }
-
- private fun calculateIcePerHour() {
- val difference = estimatedIce - lastEstimatedIce
- lastEstimatedIce = estimatedIce
-
- if (difference == estimatedIce) return
-
-
- if (difference == 0L) {
- if (icePerSecond.isEmpty()) return
- stoppedChecks += 1
- } else {
- if (stoppedChecks > 60) {
- stoppedChecks = 0
- icePerSecond.clear()
- icePerHour = 0
- }
- while (stoppedChecks > 0) {
- stoppedChecks -= 1
- icePerSecond.add(0)
- }
- icePerSecond.add(difference)
- val listCopy = icePerSecond
- while (listCopy.size > 1200) listCopy.removeAt(0)
- icePerSecond = listCopy
- }
- icePerHour = (icePerSecond.average() * 3600).toInt()
- }
-
- private fun formatDisplay(map: List<List<Any>>): List<List<Any>> {
- val newList = mutableListOf<List<Any>>()
- for (index in config.textFormat) {
- newList.add(map[index])
- }
- return newList
- }
-
- @SubscribeEvent
- fun onChat(event: LorenzChatEvent) {
- if (!ProfileStorageData.loaded) return
- if (!onJerryWorkshop()) return
-
- val message = event.message.removeColor().trim()
- val storage = ProfileStorageData.profileSpecific?.frozenTreasureTracker ?: return
-
- compactPattern.matchMatcher(message) {
- storage.compactProcs += 1
- saveAndUpdate()
- if (config.hideMessages) event.blockedReason = "frozen treasure tracker"
- }
-
- for (treasure in FrozenTreasure.entries) {
- if ("FROZEN TREASURE! You found ${treasure.displayName.removeColor()}!".toRegex().matches(message)) {
- storage.treasuresMined += 1
- val old = storage.treasureCount[treasure] ?: 0
- storage.treasureCount = storage.treasureCount.editCopy { this[treasure] = old + 1 }
- saveAndUpdate()
- if (config.hideMessages) event.blockedReason = "frozen treasure tracker"
- }
- }
- }
-
- @SubscribeEvent
- fun onPreProfileSwitch(event: PreProfileSwitchEvent) {
- display = emptyList()
- }
-
- private fun drawTreasureDisplay(storage: Storage.ProfileSpecific.FrozenTreasureTracker) = buildList<List<Any>> {
- addAsSingletonList("§1§lFrozen Treasure Tracker")
- addAsSingletonList("§6${formatNumber(storage.treasuresMined)} Treasures Mined")
- addAsSingletonList("§3${formatNumber(estimatedIce)} Total Ice")
- addAsSingletonList("§3${formatNumber(icePerHour)} Ice/hr")
- addAsSingletonList("§8${formatNumber(storage.treasuresMined)} Compact Procs")
- addAsSingletonList("")
-
- for (treasure in FrozenTreasure.entries) {
- val count = (storage.treasureCount[treasure] ?: 0) * if (config.showAsDrops) treasure.defaultAmount else 1
- addAsSingletonList("§b${formatNumber(count)} ${treasure.displayName}")
- }
- addAsSingletonList("")
- }
-
- fun formatNumber(amount: Number): String {
- if (amount is Int) return amount.addSeparators()
- if (amount is Long) return NumberUtil.format(amount)
- return "$amount"
- }
-
- private fun saveAndUpdate() {
- val storage = ProfileStorageData.profileSpecific?.frozenTreasureTracker ?: return
- calculateIce(storage)
- display = formatDisplay(drawTreasureDisplay(storage))
- }
-
- private fun calculateIce(storage: Storage.ProfileSpecific.FrozenTreasureTracker) {
- estimatedIce = 0
- estimatedIce += storage.compactProcs * 160
- for (treasure in FrozenTreasure.entries) {
- val amount = storage.treasureCount[treasure] ?: 0
- estimatedIce += amount * treasure.defaultAmount * treasure.iceMultiplier
- }
- }
-
- @SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
- if (!config.enabled) return
- if (!onJerryWorkshop()) return
- if (config.onlyInCave && !inGlacialCave()) return
- config.position.renderStringsAndItems(display, posLabel = "Frozen Treasure Tracker")
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "misc.frozenTreasureTracker", "event.winter.frozenTreasureTracker")
- }
-
- private fun onJerryWorkshop() = LorenzUtils.inIsland(IslandType.WINTER)
-
- private fun inGlacialCave() = onJerryWorkshop() && ScoreboardData.sidebarLinesFormatted.contains(" §7⏣ §3Glacial Cave")
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/HarpFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/HarpFeatures.kt
deleted file mode 100644
index e483aa980..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/HarpFeatures.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.RenderItemTipEvent
-import at.hannibal2.skyhanni.utils.InventoryUtils.openInventoryName
-import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.SimpleTimeMark
-import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.inventory.GuiChest
-import net.minecraft.item.Item
-import net.minecraftforge.client.event.GuiScreenEvent
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import org.lwjgl.input.Keyboard
-import kotlin.time.Duration.Companion.milliseconds
-
-// Delaying key presses by 300ms comes from NotEnoughUpdates
-class HarpFeatures {
- private val config get() = SkyHanniMod.feature.inventory.helper.harp
- private var lastClick = SimpleTimeMark.farPast()
-
- private val keys = listOf(
- Keyboard.KEY_1,
- Keyboard.KEY_2,
- Keyboard.KEY_3,
- Keyboard.KEY_4,
- Keyboard.KEY_5,
- Keyboard.KEY_6,
- Keyboard.KEY_7
- )
-
- private val buttonColors = listOf('d', 'e', 'a', '2', '5', '9', 'b')
-
- @SubscribeEvent
- fun onGui(event: GuiScreenEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (!config.keybinds) return
- if (!openInventoryName().startsWith("Harp")) return
- val chest = event.gui as? GuiChest ?: return
-
- for (key in keys) {
- if (key.isKeyHeld()) {
- if (lastClick.passedSince() > 200.milliseconds) {
- Minecraft.getMinecraft().playerController.windowClick(
- chest.inventorySlots.windowId,
- 35 + key,
- 2,
- 3,
- Minecraft.getMinecraft().thePlayer
- ) // middle clicks > left clicks
- lastClick = SimpleTimeMark.now()
- }
- break
- }
- }
- }
-
- @SubscribeEvent
- fun onRenderItemTip(event: RenderItemTipEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (!config.showNumbers) return
- if (!openInventoryName().startsWith("Harp")) return
- if (Item.getIdFromItem(event.stack.item) != 159) return // Stained hardened clay item id = 159
-
- // Example: §9| §7Click! will select the 9
- val index = buttonColors.indexOfFirst { it == event.stack.displayName[1] }
- if (index == -1) return // this should never happen unless there's an update
-
- event.stackTip = (index + 1).toString()
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "misc.harpKeybinds", "inventory.helper.harp.keybinds")
- event.move(2, "misc.harpNumbers", "inventory.helper.harp.showNumbers")
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/HideDamageSplash.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/HideDamageSplash.kt
deleted file mode 100644
index e2512007c..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/HideDamageSplash.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.features.damageindicator.DamageIndicatorManager
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import net.minecraft.entity.EntityLivingBase
-import net.minecraftforge.client.event.RenderLivingEvent
-import net.minecraftforge.fml.common.eventhandler.EventPriority
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-class HideDamageSplash {
-
- @SubscribeEvent(priority = EventPriority.HIGH)
- fun onRenderDamage(event: RenderLivingEvent.Specials.Pre<EntityLivingBase>) {
- if (!LorenzUtils.inSkyBlock) return
- if (!SkyHanniMod.feature.combat.hideDamageSplash) return
-
- if (DamageIndicatorManager.isDamageSplash(event.entity)) {
- event.isCanceled = true
- }
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "misc.hideDamageSplash", "combat.hideDamageSplash")
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ThunderSparksHighlight.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ThunderSparksHighlight.kt
deleted file mode 100644
index cceda92ea..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/ThunderSparksHighlight.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-package at.hannibal2.skyhanni.features.misc
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
-import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled
-import at.hannibal2.skyhanni.utils.BlockUtils.getBlockAt
-import at.hannibal2.skyhanni.utils.EntityUtils
-import at.hannibal2.skyhanni.utils.EntityUtils.hasSkullTexture
-import at.hannibal2.skyhanni.utils.LocationUtils
-import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.RenderUtils.drawString
-import at.hannibal2.skyhanni.utils.SpecialColour
-import at.hannibal2.skyhanni.utils.getLorenzVec
-import net.minecraft.entity.item.EntityArmorStand
-import net.minecraft.init.Blocks
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import java.awt.Color
-
-class ThunderSparksHighlight {
-
- private val config get() = SkyHanniMod.feature.fishing.thunderSpark
- private val texture =
- "ewogICJ0aW1lc3RhbXAiIDogMTY0MzUwNDM3MjI1NiwKICAicHJvZmlsZUlkIiA6ICI2MzMyMDgwZTY3YTI0Y2MxYjE3ZGJhNzZmM2MwMGYxZCIsCiAgInByb2ZpbGVOYW1lIiA6ICJUZWFtSHlkcmEiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2IzMzI4ZDNlOWQ3MTA0MjAzMjI1NTViMTcyMzkzMDdmMTIyNzBhZGY4MWJmNjNhZmM1MGZhYTA0YjVjMDZlMSIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9"
- private val sparks = mutableListOf<EntityArmorStand>()
-
- @SubscribeEvent
- fun onTick(event: LorenzTickEvent) {
- if (!isEnabled()) return
-
-
- EntityUtils.getEntities<EntityArmorStand>().filter {
- it !in sparks && it.hasSkullTexture(texture)
- }.forEach { sparks.add(it) }
- }
-
- @SubscribeEvent
- fun onRenderWorld(event: LorenzRenderWorldEvent) {
- if (!isEnabled()) return
-
- val special = config.color
- val color = Color(SpecialColour.specialToChromaRGB(special), true)
-
- val playerLocation = LocationUtils.playerLocation()
- for (spark in sparks) {
- if (spark.isDead) continue
- val sparkLocation = spark.getLorenzVec()
- val block = sparkLocation.getBlockAt()
- val seeThroughBlocks =
- sparkLocation.distanceToPlayer() < 6 && (block == Blocks.flowing_lava || block == Blocks.lava)
- event.drawWaypointFilled(
- sparkLocation.add(-0.5, 0.0, -0.5), color, extraSize = -0.25, seeThroughBlocks = seeThroughBlocks
- )
- if (sparkLocation.distance(playerLocation) < 10) {
- event.drawString(sparkLocation.add(0.0, 1.5, 0.0), "Thunder Spark", seeThroughBlocks = seeThroughBlocks)
- }
- }
- }
-
- @SubscribeEvent
- fun onWorldChange(event: LorenzWorldChangeEvent) {
- sparks.clear()
- }
-
- private fun isEnabled(): Boolean {
- return LorenzUtils.inSkyBlock && config.highlight
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(3, "fishing.thunderSparkHighlight", "fishing.thunderSpark.highlight")
- event.move(3, "fishing.thunderSparkColor", "fishing.thunderSpark.color")
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostCounter.kt
deleted file mode 100644
index 8c2287720..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostCounter.kt
+++ /dev/null
@@ -1,494 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.ghostcounter
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.data.IslandType
-import at.hannibal2.skyhanni.data.ProfileStorageData
-import at.hannibal2.skyhanni.data.SkillExperience
-import at.hannibal2.skyhanni.events.ConfigLoadEvent
-import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
-import at.hannibal2.skyhanni.events.LorenzActionBarEvent
-import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.events.PurseChangeCause
-import at.hannibal2.skyhanni.events.PurseChangeEvent
-import at.hannibal2.skyhanni.events.TabListUpdateEvent
-import at.hannibal2.skyhanni.features.bazaar.BazaarApi.Companion.getBazaarData
-import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostData.Option
-import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostData.Option.KILLS
-import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostData.bestiaryData
-import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil.formatBestiary
-import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil.formatText
-import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil.isUsingCTGhostCounter
-import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil.preFormat
-import at.hannibal2.skyhanni.features.misc.ghostcounter.GhostUtil.prettyTime
-import at.hannibal2.skyhanni.utils.CombatUtils._isKilling
-import at.hannibal2.skyhanni.utils.CombatUtils.calculateETA
-import at.hannibal2.skyhanni.utils.CombatUtils.calculateXP
-import at.hannibal2.skyhanni.utils.CombatUtils.interp
-import at.hannibal2.skyhanni.utils.CombatUtils.isKilling
-import at.hannibal2.skyhanni.utils.CombatUtils.killGainHour
-import at.hannibal2.skyhanni.utils.CombatUtils.killGainHourLast
-import at.hannibal2.skyhanni.utils.CombatUtils.lastKillUpdate
-import at.hannibal2.skyhanni.utils.CombatUtils.lastUpdate
-import at.hannibal2.skyhanni.utils.CombatUtils.xpGainHour
-import at.hannibal2.skyhanni.utils.CombatUtils.xpGainHourLast
-import at.hannibal2.skyhanni.utils.ItemUtils.getLore
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
-import at.hannibal2.skyhanni.utils.LorenzUtils.chat
-import at.hannibal2.skyhanni.utils.LorenzUtils.clickableChat
-import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
-import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
-import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
-import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal
-import at.hannibal2.skyhanni.utils.NumberUtil.roundToPrecision
-import at.hannibal2.skyhanni.utils.OSUtils
-import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
-import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import at.hannibal2.skyhanni.utils.StringUtils.removeColor
-import at.hannibal2.skyhanni.utils.renderables.Renderable
-import io.github.moulberry.notenoughupdates.util.Utils
-import io.github.moulberry.notenoughupdates.util.XPInformation
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import java.io.File
-import java.text.NumberFormat
-import java.util.Locale
-import kotlin.math.roundToInt
-import kotlin.math.roundToLong
-
-object GhostCounter {
-
- val config get() = SkyHanniMod.feature.combat.ghostCounter
- val hidden get() = ProfileStorageData.profileSpecific?.ghostCounter
- private var display = emptyList<List<Any>>()
- var ghostCounterV3File =
- File("." + File.separator + "config" + File.separator + "ChatTriggers" + File.separator + "modules" + File.separator + "GhostCounterV3" + File.separator + ".persistantData.json")
- private val skillXPPattern = "[+](?<gained>[0-9,.]+) \\((?<current>[0-9,.]+)(?:/(?<total>[0-9,.]+))?\\)".toPattern()
- private val combatSectionPattern =
- ".*[+](?<gained>[0-9,.]+) (?<skillName>[A-Za-z]+) \\((?<progress>(?<current>[0-9.,]+)/(?<total>[0-9.,]+)|(?<percent>[0-9.]+)%)\\).*".toPattern()
- private val killComboExpiredPattern =
- "§cYour Kill Combo has expired! You reached a (?<combo>.*) Kill Combo!".toPattern()
- private val ghostXPPattern =
- "(?<current>\\d+(?:\\.\\d+)?(?:,\\d+)?[kK]?)/(?<total>\\d+(?:\\.\\d+)?(?:,\\d+)?[kKmM]?)".toPattern()
- private val bestiaryPattern =
- ".*(?:§\\d|§\\w)+BESTIARY (?:§\\d|§\\w)+Ghost (?:§\\d|§\\w)(?<previousLevel>\\d+)➜(?:§\\d|§\\w)(?<nextLevel>\\d+).*".toPattern() // &3&lBESTIARY &b&lGhost &89➜&b10
- private val skillLevelPattern = ".*§e§lSkills: §r§a(?<skillName>.*) (?<skillLevel>\\d+).*".toPattern()
- private val format = NumberFormat.getInstance()
- private var percent: Float = 0.0f
- private var totalSkillXp = 0
- private var currentSkillXp = 0.0f
- private var skillText = ""
- private var lastParsedSkillSection = ""
- private var lastSkillProgressString: String? = null
- private var lastXp: String = "0"
- private var gain: Int = 0
- private var num: Double = 0.0
- private var inMist = false
- private var notifyCTModule = true
- var bestiaryCurrentKill = 0
- private var killETA = ""
- private var currentSkill = ""
- private var currentSkillLevel = -1
- private const val CONFIG_VALUE_VERSION = 1
- private val SORROW = "SORROW".asInternalName()
- private val PLASMA = "PLASMA".asInternalName()
- private val VOLTA = "VOLTA".asInternalName()
-
- @SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
- if (!isEnabled()) return
- if (config.onlyOnMist && !inMist) return
- config.position.renderStringsAndItems(
- display,
- extraSpace = config.extraSpace,
- posLabel = "Ghost Counter"
- )
- }
-
- private fun formatDisplay(map: List<List<Any>>): List<List<Any>> {
- val newList = mutableListOf<List<Any>>()
- for (index in config.ghostDisplayText) {
- newList.add(map[index])
- }
- return newList
- }
-
- fun update() {
- display = formatDisplay(drawDisplay())
- }
-
- private fun drawDisplay() = buildList<List<Any>> {
- val textFormatting = config.textFormatting
- val ghostKillPerSorrow: Int = when (Option.SORROWCOUNT.get()) {
- 0.0 -> 0
- else -> "${((((KILLS.get() / Option.SORROWCOUNT.get()) + Math.ulp(1.0)) * 100) / 100).roundToInt()}".toInt()
- }
- val avgMagicFind = when (Option.TOTALDROPS.get()) {
- 0.0 -> "0"
- else -> "${((((hidden?.totalMF!! / Option.TOTALDROPS.get()) + Math.ulp(1.0)) * 100) / 100).roundToPrecision(2)}"
- }
-
- val xpHourFormatting = textFormatting.xpHourFormatting
- val xpInterp: Float
- val xp = if (xpGainHourLast == xpGainHour && xpGainHour <= 0) {
- xpHourFormatting.noData
- } else {
- xpInterp = interp(xpGainHour, xpGainHourLast, lastUpdate)
- val part = "([0-9]{3,}[^,]+)".toRegex().find(format.format(xpInterp))?.groupValues?.get(1) ?: "N/A"
- "$part ${if (isKilling) "" else xpHourFormatting.paused}"
- }
-
- val killHourFormatting = textFormatting.killHourFormatting
- val killHour: String
- var killInterp: Long = 0
- if (killGainHourLast == killGainHour && killGainHour <= 0) {
- killHour = killHourFormatting.noData
- } else {
- killInterp = interp(killGainHour.toFloat(), killGainHourLast.toFloat(), lastKillUpdate).toLong()
- killHour = "${format.format(killInterp)} ${if (_isKilling) "" else killHourFormatting.paused}"
- }
-
- val bestiaryFormatting = textFormatting.bestiaryFormatting
- val currentKill = hidden?.bestiaryCurrentKill?.toInt() ?: 0
- val killNeeded = hidden?.bestiaryKillNeeded?.toInt() ?: 0
- val nextLevel = hidden?.bestiaryNextLevel?.toInt() ?: -1
- val bestiary = if (config.showMax) {
- when (nextLevel) {
- 26 -> bestiaryFormatting.maxed.replace("%currentKill%", currentKill.addSeparators())
- in 1..25 -> {
- val sum = bestiaryData.filterKeys { it <= nextLevel - 1 }.values.sum()
-
- val cKill = sum + currentKill
- bestiaryCurrentKill = cKill
- bestiaryFormatting.showMax_progress
- }
-
- else -> bestiaryFormatting.openMenu
- }
- } else {
- when (nextLevel) {
- 26 -> bestiaryFormatting.maxed
- in 1..25 -> bestiaryFormatting.progress
- else -> bestiaryFormatting.openMenu
- }
- }
-
- val etaFormatting = textFormatting.etaFormatting
- val remaining: Int = when (config.showMax) {
- true -> 250_000 - bestiaryCurrentKill
- false -> killNeeded - currentKill
- }
-
- val eta = if (remaining < 0) {
- etaFormatting.maxed
- } else {
- if (killGainHour < 1) {
- etaFormatting.noData
- } else {
- val timeMap = prettyTime(remaining.toLong() * 1000 * 60 * 60 / killInterp)
- val time = buildString {
- if (timeMap.isNotEmpty()) {
- val formatMap = mapOf(
- "%days%" to "days",
- "%hours%" to "hours",
- "%minutes%" to "minutes",
- "%seconds%" to "seconds"
- )
- for ((format, key) in formatMap) {
- if (etaFormatting.time.contains(format)) {
- timeMap[key]?.let { value ->
- append("$value${format[1]}")
- }
- }
- }
- } else {
- append("§cEnded!")
- }
- }
- killETA = time
- etaFormatting.progress + if (_isKilling) "" else etaFormatting.paused
- }
- }
-
- addAsSingletonList(Utils.chromaStringByColourCode(textFormatting.titleFormat.replace("&", "§")))
- addAsSingletonList(textFormatting.ghostKilledFormat.formatText(KILLS))
- addAsSingletonList(textFormatting.sorrowsFormat.formatText(Option.SORROWCOUNT))
- addAsSingletonList(textFormatting.ghostSinceSorrowFormat.formatText(Option.GHOSTSINCESORROW.getInt()))
- addAsSingletonList(textFormatting.ghostKillPerSorrowFormat.formatText(ghostKillPerSorrow))
- addAsSingletonList(textFormatting.voltasFormat.formatText(Option.VOLTACOUNT))
- addAsSingletonList(textFormatting.plasmasFormat.formatText(Option.PLASMACOUNT))
- addAsSingletonList(textFormatting.ghostlyBootsFormat.formatText(Option.GHOSTLYBOOTS))
- addAsSingletonList(textFormatting.bagOfCashFormat.formatText(Option.BAGOFCASH))
- addAsSingletonList(textFormatting.avgMagicFindFormat.formatText(avgMagicFind))
- addAsSingletonList(textFormatting.scavengerCoinsFormat.formatText(Option.SCAVENGERCOINS))
- addAsSingletonList(textFormatting.killComboFormat.formatText(Option.MAXKILLCOMBO))
- addAsSingletonList(textFormatting.highestKillComboFormat.formatText(Option.MAXKILLCOMBO))
- addAsSingletonList(textFormatting.skillXPGainFormat.formatText(Option.SKILLXPGAINED))
- addAsSingletonList(
- bestiaryFormatting.base.preFormat(bestiary, nextLevel - 1, nextLevel)
- .formatBestiary(currentKill, killNeeded)
- )
-
- addAsSingletonList(xpHourFormatting.base.formatText(xp))
- addAsSingletonList(killHourFormatting.base.formatText(killHour))
- addAsSingletonList(etaFormatting.base.formatText(eta).formatText(killETA))
-
- val rate = 0.12 * (1 + (avgMagicFind.toDouble() / 100))
- val sorrowValue = SORROW.getBazaarData()?.buyPrice?.toLong() ?: 0L
- val final: String = (killInterp * sorrowValue * (rate / 100)).toLong().addSeparators()
- val plasmaValue = PLASMA.getBazaarData()?.buyPrice?.toLong() ?: 0L
- val voltaValue = VOLTA.getBazaarData()?.buyPrice?.toLong() ?: 0L
- var moneyMade: Long = 0
- val priceMap = listOf(
- Triple("Sorrow", Option.SORROWCOUNT.getInt(), sorrowValue),
- Triple("Plasma", Option.PLASMACOUNT.getInt(), plasmaValue),
- Triple("Volta", Option.VOLTACOUNT.getInt(), voltaValue),
- Triple("Bag Of Cash", Option.BAGOFCASH.getInt(), 1_000_000),
- Triple("Scavenger Coins", Option.SCAVENGERCOINS.getInt(), 1),
- Triple("Ghostly Boots", Option.GHOSTLYBOOTS.getInt(), 77_777)
- )
- val moneyMadeTips = buildList {
- for ((name, count, value) in priceMap) {
- moneyMade += (count.toLong() * value.toLong())
- add("$name: §b${value.addSeparators()} §fx §b${count.addSeparators()} §f= §6${(value.toLong() * count.toLong()).addSeparators()}")
- }
- add("§bTotal: §6${moneyMade.addSeparators()}")
- add("§eClick to copy to clipboard!")
- }
- val moneyMadeWithClickableTips = Renderable.clickAndHover(
- textFormatting.moneyMadeFormat.formatText(moneyMade.addSeparators()),
- moneyMadeTips
- ) { OSUtils.copyToClipboard(moneyMadeTips.joinToString("\n").removeColor()) }
- addAsSingletonList(textFormatting.moneyHourFormat.formatText(final))
- addAsSingletonList(moneyMadeWithClickableTips)
- }
-
- @SubscribeEvent
- fun onTick(event: LorenzTickEvent) {
- if (!isEnabled()) return
- if (event.repeatSeconds(1)) {
- skillXPPattern.matchMatcher(skillText) {
- val gained = group("gained").formatNumber().toDouble()
- val current = group("current")
- if (current != lastXp) {
- val res = current.formatNumber().toString()
- gain = (res.toLong() - lastXp.toLong()).toDouble().roundToInt()
- num = (gain.toDouble() / gained)
- if (gained in 150.0..450.0 && lastXp != "0" && num >= 0) {
- KILLS.add(num)
- KILLS.add(num, true)
- Option.GHOSTSINCESORROW.add(num)
- Option.KILLCOMBO.add(num)
- Option.SKILLXPGAINED.add(gained * num.roundToLong())
- Option.SKILLXPGAINED.add(gained * num.roundToLong(), true)
- hidden?.bestiaryCurrentKill = hidden?.bestiaryCurrentKill?.plus(num) ?: num
- }
- lastXp = res
- }
- }
- if (notifyCTModule && ProfileStorageData.profileSpecific?.ghostCounter?.ctDataImported != true) {
- notifyCTModule = false
- if (isUsingCTGhostCounter()) {
- clickableChat(
- "§6[SkyHanni] GhostCounterV3 ChatTriggers module has been detected, do you want to import saved data ? Click here to import data",
- "shimportghostcounterdata"
- )
- }
- }
- inMist = LorenzUtils.skyBlockArea == "The Mist"
- update()
- }
- if (event.repeatSeconds(2)) {
- calculateXP()
- calculateETA()
- }
- }
-
- @SubscribeEvent
- fun onActionBar(event: LorenzActionBarEvent) {
- if (!isEnabled()) return
- if (!inMist) return
- combatSectionPattern.matchMatcher(event.message) {
- if (group("skillName").lowercase() != "combat") return
- parseCombatSection(event.message)
- }
- }
-
- private fun parseCombatSection(section: String) {
- val sb = StringBuilder()
- val nf = NumberFormat.getInstance(Locale.US)
- nf.maximumFractionDigits = 2
- if (lastParsedSkillSection == section) {
- sb.append(lastSkillProgressString)
- } else if (combatSectionPattern.matcher(section).find()) {
- combatSectionPattern.matchMatcher(section) {
- sb.append("+").append(group("gained"))
- val skillName = group("skillName")
- val skillPercent = group("percent") != null
- var parse = true
- if (skillPercent) {
- percent = nf.parse(group("percent")).toFloat()
- val level =
- if (currentSkill == "Combat" && currentSkillLevel != -1) currentSkillLevel else XPInformation.getInstance()
- .getSkillInfo(skillName)?.level ?: 0
- if (level > 0) {
- totalSkillXp = SkillExperience.getExpForNextLevel(level)
- currentSkillXp = totalSkillXp * percent / 100
- } else {
- parse = false
- }
- } else {
- currentSkillXp = nf.parse(group("current")).toFloat()
- totalSkillXp = nf.parse(group("total")).toInt()
- }
- percent = 100f.coerceAtMost(percent)
- if (!parse) {
- sb.append(" (").append(String.format("%.2f", percent)).append("%)")
- } else {
- sb.append(" (").append(nf.format(currentSkillXp))
- if (totalSkillXp != 0) {
- sb.append("/")
- sb.append(nf.format(totalSkillXp))
- }
- sb.append(")")
- }
- lastParsedSkillSection = section
- lastSkillProgressString = sb.toString()
- }
- if (sb.toString().isNotEmpty()) {
- skillText = sb.toString()
- }
- }
- }
-
- @SubscribeEvent
- fun onTabUpdate(event: TabListUpdateEvent) {
- if (!isEnabled()) return
- for (line in event.tabList) {
- skillLevelPattern.matchMatcher(line) {
- currentSkill = group("skillName")
- currentSkillLevel = group("skillLevel").toInt()
- }
- }
- }
-
- @SubscribeEvent
- fun onChat(event: LorenzChatEvent) {
- if (!isEnabled()) return
- if (LorenzUtils.skyBlockIsland != IslandType.DWARVEN_MINES) return
- for (opt in Option.entries) {
- val pattern = opt.pattern ?: continue
- pattern.matchMatcher(event.message) {
- when (opt) {
- Option.SORROWCOUNT, Option.VOLTACOUNT, Option.PLASMACOUNT, Option.GHOSTLYBOOTS -> {
- opt.add(1.0)
- opt.add(1.0, true)
- hidden?.totalMF = hidden?.totalMF?.plus(group("mf").substring(4).toDouble())
- ?: group("mf").substring(4).toDouble()
- Option.TOTALDROPS.add(1.0)
- if (opt == Option.SORROWCOUNT)
- Option.GHOSTSINCESORROW.set(0.0)
- update()
- }
-
- Option.BAGOFCASH -> {
- Option.BAGOFCASH.add(1.0)
- Option.BAGOFCASH.add(1.0, true)
- update()
- }
-
- Option.KILLCOMBOCOINS -> {
- Option.KILLCOMBOCOINS.set(Option.KILLCOMBOCOINS.get() + group("coin").toDouble())
- update()
- }
-
- else -> {}
- }
- }
- }
- killComboExpiredPattern.matchMatcher(event.message) {
- if (Option.KILLCOMBO.getInt() > Option.MAXKILLCOMBO.getInt()) {
- Option.MAXKILLCOMBO.set(group("combo").formatNumber().toDouble())
- }
- if (Option.KILLCOMBO.getInt() > Option.MAXKILLCOMBO.getInt(true)) {
- Option.MAXKILLCOMBO.set(group("combo").formatNumber().toDouble(), true)
- }
- Option.KILLCOMBOCOINS.set(0.0)
- Option.KILLCOMBO.set(0.0)
- update()
- }
- //replace with BestiaryLevelUpEvent ?
- bestiaryPattern.matchMatcher(event.message) {
- val currentLevel = group("nextLevel").toInt()
- when (val nextLevel = if (currentLevel >= 25) 26 else currentLevel + 1) {
- 26 -> {
- hidden?.bestiaryNextLevel = 26.0
- hidden?.bestiaryCurrentKill = 250_000.0
- hidden?.bestiaryKillNeeded = 0.0
- }
-
- else -> {
- val killNeeded: Int = bestiaryData[nextLevel] ?: -1
- hidden?.bestiaryNextLevel = nextLevel.toDouble()
- hidden?.bestiaryCurrentKill = 0.0
- hidden?.bestiaryKillNeeded = killNeeded.toDouble()
- }
- }
- update()
- }
- }
-
- @SubscribeEvent
- fun onPurseChange(event: PurseChangeEvent) {
- if (!isEnabled()) return
- if (LorenzUtils.skyBlockArea != "The Mist") return
- if (event.reason != PurseChangeCause.GAIN_MOB_KILL) return
- Option.SCAVENGERCOINS.add(event.coins, true)
- Option.SCAVENGERCOINS.add(event.coins)
- }
-
- @SubscribeEvent
- fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
- if (!LorenzUtils.inSkyBlock) return
- val inventoryName = event.inventoryName
- if (inventoryName != "Bestiary ➜ Dwarven Mines") return
- val stacks = event.inventoryItems
- val ghostStack = stacks[10] ?: return
- val bestiaryNextLevel =
- if ("§\\wGhost".toRegex().matches(ghostStack.displayName)) 1 else ghostStack.displayName.substring(8)
- .romanToDecimal() + 1
- hidden?.bestiaryNextLevel = bestiaryNextLevel.toDouble()
- var kills = 0.0
- for (line in ghostStack.getLore()) {
- val l = line.removeColor().trim()
- if (l.startsWith("Kills: ")) {
- kills = "Kills: (.*)".toRegex().find(l)?.groupValues?.get(1)?.formatNumber()?.toDouble() ?: 0.0
- }
- ghostXPPattern.matchMatcher(line.removeColor().trim()) {
- hidden?.bestiaryCurrentKill = if (kills > 0) kills else group("current").formatNumber().toDouble()
- hidden?.bestiaryKillNeeded = group("total").formatNumber().toDouble()
- }
- }
- update()
- }
-
- @SubscribeEvent
- fun onConfigLoad(event: ConfigLoadEvent) {
- if (hidden?.configUpdateVersion == 0) {
- config.textFormatting.bestiaryFormatting.base = " &6Bestiary %display%: &b%value%"
- chat("§e[SkyHanni] Your GhostCounter config has been automatically adjusted.")
- hidden?.configUpdateVersion = CONFIG_VALUE_VERSION
- }
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "ghostCounter", "combat.ghostCounter")
- }
-
- fun isEnabled(): Boolean {
- return LorenzUtils.inSkyBlock && config.enabled && LorenzUtils.skyBlockIsland == IslandType.DWARVEN_MINES
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostData.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostData.kt
deleted file mode 100644
index e56e0a7ff..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostData.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.ghostcounter
-
-import java.util.regex.Pattern
-import kotlin.math.roundToInt
-
-object GhostData {
-
- private var session = mutableMapOf(
- Option.KILLS to 0.0,
- Option.SORROWCOUNT to 0.0,
- Option.VOLTACOUNT to 0.0,
- Option.PLASMACOUNT to 0.0,
- Option.GHOSTLYBOOTS to 0.0,
- Option.BAGOFCASH to 0.0,
- Option.TOTALDROPS to 0.0,
- Option.SCAVENGERCOINS to 0.0,
- Option.MAXKILLCOMBO to 0.0,
- Option.SKILLXPGAINED to 0.0
- )
-
- val bestiaryData = mutableMapOf<Int, Int>().apply {
- for (i in 1..25) {
- this[i] = when (i) {
- 1 -> 5
- 2 -> 5
- 3 -> 5
- 4 -> 10
- 5 -> 25
- 6 -> 50
- 7 -> 100
- 8 -> 150
- 9 -> 150
- 10 -> 250
- 11 -> 750
- 12 -> 1_500
- 13 -> 2_000
- 14,15,16,17 -> 2_500
- 18 -> 3_000
- 19,20 -> 3_500
- 21 -> 25_000
- 22,23,24,25 -> 50_000
- else -> 0
- }
- }
- }
-
- enum class Option(val pattern: Pattern? = null) {
- KILLS,
- SORROWCOUNT("§6§lRARE DROP! §r§9Sorrow §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
- VOLTACOUNT("§6§lRARE DROP! §r§9Volta §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
- PLASMACOUNT("§6§lRARE DROP! §r§9Plasma §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
- GHOSTLYBOOTS("§6§lRARE DROP! §r§9Ghostly Boots §r§b\\([+](?<mf>.*)% §r§b✯ Magic Find§r§b\\)".toPattern()),
- BAGOFCASH("§eThe ghost's death materialized §r§61,000,000 coins §r§efrom the mists!".toPattern()),
- KILLCOMBOCOINS("[+]\\d+ Kill Combo [+](?<coin>.*) coins per kill".toPattern()),
- TOTALDROPS,
- GHOSTSINCESORROW,
- SCAVENGERCOINS,
- MAXKILLCOMBO,
- KILLCOMBO("[+]\\d+ Kill Combo [+](?<coin>.*) coins per kill".toPattern()),
- SKILLXPGAINED;
-
- fun add(i: Double, s: Boolean = false) {
- if (s)
- session[this] = session[this]?.plus(i) ?: i
- else
- GhostCounter.hidden?.data?.set(this, GhostCounter.hidden?.data?.get(this)?.plus(i) ?: i)
- }
-
- fun set(i: Double, s: Boolean = false) {
- if (s)
- session[this] = i
- else
- GhostCounter.hidden?.data?.set(this, i)
- }
-
- fun getInt(s: Boolean = false): Int {
- return if (s)
- session[this]?.roundToInt() ?: 0
- else
- GhostCounter.hidden?.data?.get(this)?.roundToInt() ?: 0
- }
-
- fun get(s: Boolean = false): Double {
- return if (s)
- session[this] ?: 0.0
- else
- GhostCounter.hidden?.data?.get(this) ?: 0.0
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostFormatting.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostFormatting.kt
deleted file mode 100644
index 1aee55849..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostFormatting.kt
+++ /dev/null
@@ -1,182 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.ghostcounter
-
-import com.google.gson.JsonArray
-import com.google.gson.JsonParser
-import com.google.gson.JsonPrimitive
-import java.awt.Toolkit
-import java.awt.datatransfer.DataFlavor
-import java.awt.datatransfer.StringSelection
-import java.nio.charset.StandardCharsets
-import java.util.Base64
-
-object GhostFormatting {
-
- private const val exportPrefix = "gc/"
-
- fun importFormat() {
- val base64: String = try {
- Toolkit.getDefaultToolkit().systemClipboard.getData(DataFlavor.stringFlavor) as String
- } catch (e: Exception) {
- return
- }
-
- if (base64.length <= exportPrefix.length) return
- val jsonString = try {
- val t = String(Base64.getDecoder().decode(base64.trim()))
- if (!t.startsWith(exportPrefix)) return
- t.substring(exportPrefix.length)
- } catch (e: IllegalArgumentException) {
- return
- }
-
- val list = try {
- JsonParser().parse(jsonString).asJsonArray
- .filter { it.isJsonPrimitive }
- .map { it.asString }
- } catch (e: Exception) {
- return
- }
-
- if (list.isNotEmpty()) {
- with(GhostCounter.config.textFormatting) {
- titleFormat = list[0]
- ghostKilledFormat = list[1]
- sorrowsFormat = list[2]
- ghostSinceSorrowFormat = list[3]
- ghostKillPerSorrowFormat = list[4]
- voltasFormat = list[5]
- plasmasFormat = list[6]
- ghostlyBootsFormat = list[7]
- bagOfCashFormat = list[8]
- avgMagicFindFormat = list[9]
- scavengerCoinsFormat = list[10]
- killComboFormat = list[11]
- highestKillComboFormat = list[12]
- skillXPGainFormat = list[13]
- with(xpHourFormatting) {
- base = list[14]
- noData = list[15]
- paused = list[16]
- }
- with(bestiaryFormatting) {
- base = list[17]
- openMenu = list[18]
- maxed = list[19]
- showMax_progress = list[20]
- progress = list[21]
- }
- with(killHourFormatting) {
- base = list[22]
- noData = list[23]
- paused = list[24]
- }
- with(etaFormatting) {
- base = list[25]
- maxed = list[26]
- noData = list[27]
- progress = list[28]
- time = list[29]
- }
- moneyHourFormat = list[30]
- moneyMadeFormat = list[31]
- }
- }
- }
-
- fun export() {
- val list = mutableListOf<String>()
- with(GhostCounter.config.textFormatting) {
- list.add(titleFormat)
- list.add(ghostKilledFormat)
- list.add(sorrowsFormat)
- list.add(ghostSinceSorrowFormat)
- list.add(ghostKillPerSorrowFormat)
- list.add(voltasFormat)
- list.add(plasmasFormat)
- list.add(ghostlyBootsFormat)
- list.add(bagOfCashFormat)
- list.add(avgMagicFindFormat)
- list.add(scavengerCoinsFormat)
- list.add(killComboFormat)
- list.add(highestKillComboFormat)
- list.add(skillXPGainFormat)
- with(xpHourFormatting) {
- list.add(base)
- list.add(noData)
- list.add(paused)
- }
- with(bestiaryFormatting) {
- list.add(base)
- list.add(openMenu)
- list.add(maxed)
- list.add(showMax_progress)
- list.add(progress)
- }
- with(killHourFormatting) {
- list.add(base)
- list.add(noData)
- list.add(paused)
- }
- with(etaFormatting) {
- list.add(base)
- list.add(maxed)
- list.add(noData)
- list.add(progress)
- list.add(time)
- }
- list.add(moneyHourFormat)
- list.add(moneyMadeFormat)
- }
- val jsonArray = JsonArray()
- for (l in list) {
- jsonArray.add(JsonPrimitive(l))
- }
- val base64 = Base64.getEncoder().encodeToString((exportPrefix + jsonArray).toByteArray(StandardCharsets.UTF_8))
- Toolkit.getDefaultToolkit().systemClipboard.setContents(StringSelection(base64), null)
- }
-
- fun reset() {
- with(GhostCounter.config.textFormatting) {
- titleFormat = "&6Ghost Counter"
- ghostKilledFormat = " &6Ghost Killed: &b%value% &7(%session%)"
- sorrowsFormat = " &6Sorrow: &b%value% &7(%session%)"
- ghostSinceSorrowFormat = " &6Ghost since Sorrow: &b%value%"
- ghostKillPerSorrowFormat = " &6Ghosts/Sorrow: &b%value%"
- voltasFormat = " &6Volta: &b%value% &7(%session%)"
- plasmasFormat = " &6Plasmas: &b%value% &7(%session%)"
- ghostlyBootsFormat = " &6Ghostly Boots: &b%value% &7(%session%)"
- bagOfCashFormat = " &6Bag Of Cash: &b%value% &7(%session%)"
- avgMagicFindFormat = " &6Avg Magic Find: &b%value%"
- scavengerCoinsFormat = " &6Scavenger Coins: &b%value% &7(%session%)"
- killComboFormat = " &6Kill Combo: &b%value%"
- highestKillComboFormat = " &6Highest Kill Combo: &b%value% &7(%session%)"
- skillXPGainFormat = " &6Skill XP Gained: &b%value% &7(%session%)"
- with(xpHourFormatting) {
- base = " &6XP/h: &b%value%"
- noData = "&bN/A"
- paused = "&c(PAUSED)"
- }
- with(bestiaryFormatting) {
- base = " &6Bestiary %currentLevel%->%nextLevel%: &b%value%"
- openMenu = "§cOpen Bestiary Menu !"
- maxed = "%currentKill% (&c&lMaxed!)"
- showMax_progress = "%currentKill%/250k (%percentNumber%%)"
- progress = "%currentKill%/%killNeeded%"
- }
- with(killHourFormatting) {
- base = " &6Kill/h: &b%value%"
- noData = "§bN/A"
- paused = "&c(PAUSED)"
- }
- with(etaFormatting) {
- base = " &6ETA: &b%value%"
- maxed = "§c§lMAXED!"
- noData = "§bN/A"
- progress = "§b%value%"
- time = "&6%days%%hours%%minutes%%seconds%"
- }
- moneyHourFormat = " &6$/h: &b%value%"
- moneyMadeFormat = " &6Money made: &b%value%"
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostUtil.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostUtil.kt
deleted file mode 100644
index 82acce71b..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/ghostcounter/GhostUtil.kt
+++ /dev/null
@@ -1,144 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.ghostcounter
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigManager
-import at.hannibal2.skyhanni.data.ProfileStorageData
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.NumberUtil
-import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
-import at.hannibal2.skyhanni.utils.NumberUtil.roundToPrecision
-import io.github.moulberry.notenoughupdates.util.Utils
-import java.io.FileReader
-
-object GhostUtil {
-
- fun reset() {
- for (opt in GhostData.Option.entries) {
- opt.set(0.0)
- opt.set(0.0, true)
- }
- GhostCounter.hidden?.totalMF = 0.0
- GhostCounter.update()
- }
-
- fun isUsingCTGhostCounter(): Boolean {
- return GhostCounter.ghostCounterV3File.exists() && GhostCounter.ghostCounterV3File.isFile
- }
-
- fun prettyTime(millis: Long): Map<String, String> {
- val seconds = millis / 1000 % 60
- val minutes = millis / 1000 / 60 % 60
- val hours = millis / 1000 / 60 / 60 % 24
- val days = millis / 1000 / 60 / 60 / 24
- return buildMap {
- when {
- millis < 0 -> {
- clear()
- }
-
- minutes == 0L && hours == 0L && days == 0L -> {
- put("seconds", seconds.toString())
- }
-
- hours == 0L && days == 0L -> {
- put("seconds", seconds.toString())
- put("minutes", minutes.toString())
- }
-
- days == 0L -> {
- put("seconds", seconds.toString())
- put("minutes", minutes.toString())
- put("hours", hours.toString())
- }
-
- else -> {
- put("seconds", seconds.toString())
- put("minutes", minutes.toString())
- put("hours", hours.toString())
- put("days", days.toString())
- }
- }
- }
- }
-
- fun importCTGhostCounterData() {
- val c = ProfileStorageData.profileSpecific?.ghostCounter ?: return
- if (isUsingCTGhostCounter()) {
- if (c.ctDataImported) {
- LorenzUtils.chat("§e[SkyHanni] §cYou already imported GhostCounterV3 data!")
- return
- }
- val json = ConfigManager.gson.fromJson(
- FileReader(GhostCounter.ghostCounterV3File),
- com.google.gson.JsonObject::class.java
- )
- GhostData.Option.GHOSTSINCESORROW.add(json["ghostsSinceSorrow"].asDouble)
- GhostData.Option.SORROWCOUNT.add(json["sorrowCount"].asDouble)
- GhostData.Option.BAGOFCASH.add(json["BagOfCashCount"].asDouble)
- GhostData.Option.PLASMACOUNT.add(json["PlasmaCount"].asDouble)
- GhostData.Option.VOLTACOUNT.add(json["VoltaCount"].asDouble)
- GhostData.Option.GHOSTLYBOOTS.add(json["GhostlyBootsCount"].asDouble)
- GhostData.Option.KILLS.add(json["ghostsKilled"].asDouble)
- GhostCounter.hidden?.totalMF = GhostCounter.hidden?.totalMF?.plus(json["TotalMF"].asDouble)
- ?: json["TotalMF"].asDouble
- GhostData.Option.TOTALDROPS.add(json["TotalDrops"].asDouble)
- c.ctDataImported = true
- LorenzUtils.chat("§e[SkyHanni] §aImported data successfully!")
- } else
- LorenzUtils.chat("§e[SkyHanni] §cGhostCounterV3 ChatTriggers module not found!")
- }
-
- fun String.formatText(option: GhostData.Option) = formatText(option.getInt(), option.getInt(true))
-
- fun String.formatText(value: Int, session: Int = -1) = Utils.chromaStringByColourCode(
- this.replace("%value%", value.addSeparators())
- .replace("%session%", session.addSeparators())
- .replace("&", "§")
- )
-
- fun String.formatText(t: String) = Utils.chromaStringByColourCode(this.replace("%value%", t).replace("&", "§"))
-
- fun String.preFormat(t: String, level: Int, nextLevel: Int) = if (nextLevel == 26) {
- Utils.chromaStringByColourCode(
- replace("%value%", t)
- .replace("%display%", "25")
- )
- } else {
- Utils.chromaStringByColourCode(
- this.replace("%value%", t)
- .replace(
- "%display%",
- "$level->${if (SkyHanniMod.feature.combat.ghostCounter.showMax) "25" else nextLevel}"
- )
- )
- }
-
- fun String.formatText(value: Double, session: Double) = Utils.chromaStringByColourCode(
- this.replace("%value%", value.roundToPrecision(2).addSeparators())
- .replace("%session%", session.roundToPrecision(2).addSeparators())
- .replace("&", "§")
- )
-
- fun String.formatBestiary(currentKill: Int, killNeeded: Int): String {
- val bestiaryNextLevel = GhostCounter.hidden?.bestiaryNextLevel
- val currentLevel =
- bestiaryNextLevel?.let { if (it.toInt() < 0) "25" else "${it.toInt() - 1}" } ?: "§cNo Bestiary Level Data!"
- val nextLevel = bestiaryNextLevel?.let { if (GhostCounter.config.showMax) "25" else "${it.toInt()}" }
- ?: "§cNo Bestiary Level data!"
-
- return Utils.chromaStringByColourCode(
- this.replace(
- "%currentKill%",
- if (GhostCounter.config.showMax) GhostCounter.bestiaryCurrentKill.addSeparators() else currentKill.addSeparators()
- )
- .replace("%percentNumber%", percent(GhostCounter.bestiaryCurrentKill.toDouble()))
- .replace("%killNeeded%", NumberUtil.format(killNeeded))
- .replace("%currentLevel%", currentLevel)
- .replace("%nextLevel%", nextLevel)
- .replace("&", "§")
- )
- }
-
- private fun percent(number: Double) =
- 100.0.coerceAtMost(((number / 250_000) * 100).roundToPrecision(4)).toString()
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderChestReward.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderChestReward.kt
deleted file mode 100644
index 9a9dcae90..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderChestReward.kt
+++ /dev/null
@@ -1,148 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.powdertracker
-
-import java.util.regex.Pattern
-
-enum class PowderChestReward(val displayName: String, val pattern: Pattern) {
-
-
- MITHRIL_POWDER("§aMithril Powder", "§aYou received §r§b[+](?<amount>.*) §r§aMithril Powder.".toPattern()),
- GEMSTONE_POWDER("§dGemstone Powder", "§aYou received §r§b[+](?<amount>.*) §r§aGemstone Powder.".toPattern()),
-
- ROUGH_RUBY_GEMSTONE(
- "§fRough Ruby Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§f❤ §r§fRough Ruby Gemstone§r§a.".toPattern()
- ),
- FLAWED_RUBY_GEMSTONE(
- "§aFlawed Sapphire Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§a❤ §r§aFlawed RubyGemstone§r§a.".toPattern()
- ),
- FINE_RUBY_GEMSTONE(
- "§9Fine Ruby Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9❤ §r§9Fine Ruby Gemstone§r§a.".toPattern()
- ),
- FLAWLESS_RUBY_GEMSTONE(
- "§5Flawless Ruby Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9❤ §r§5Flawless Ruby Gemstone§r§a.".toPattern()
- ),
-
- ROUGH_SAPPHIRE_GEMSTONE(
- "§fRough Sapphire Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§f✎ §r§fRough Sapphire Gemstone§r§a.".toPattern()
- ),
- FLAWED_SAPPHIRE_GEMSTONE(
- "§aFlawed Sapphire Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§a✎ §r§aFlawed Sapphire Gemstone§r§a.".toPattern()
- ),
- FINE_SAPPHIRE_GEMSTONE(
- "§9Fine Sapphire Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9✎ §r§9Fine Sapphire Gemstone§r§a.".toPattern()
- ),
- FLAWLESS_SAPPHIRE_GEMSTONE(
- "§5Flawless Sapphire Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9✎ §r§5Flawless Sapphire Gemstone§r§a.".toPattern()
- ),
-
- ROUGH_AMBER_GEMSTONE(
- "§fRough Amber Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§f⸕ §r§fRough Amber Gemstone§r§a.".toPattern()
- ),
- FLAWED_AMBER_GEMSTONE(
- "§aFlawed Amber Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§a⸕ §r§aFlawed Amber Gemstone§r§a.".toPattern()
- ),
- FINE_AMBER_GEMSTONE(
- "§9Fine Amber Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9⸕ §r§9Fine Amber Gemstone§r§a.".toPattern()
- ),
- FLAWLESS_AMBER_GEMSTONE(
- "§5Flawless Amber Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9⸕ §r§5Flawless Amber Gemstone§r§a.".toPattern()
- ),
-
- ROUGH_AMETHYST_GEMSTONE(
- "§fRough Amethyst Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§f❈ §r§fRough Amethyst Gemstone§r§a.".toPattern()
- ),
- FLAWED_AMETHYST_GEMSTONE(
- "§aFlawed Amethyst Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§a❈ §r§aFlawed Amethyst Gemstone§r§a.".toPattern()
- ),
- FINE_AMETHYST_GEMSTONE(
- "§9Fine Amethyst Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9❈ §r§9Fine Amethyst Gemstone§r§a.".toPattern()
- ),
- FLAWLESS_AMETHYST_GEMSTONE(
- "§5Flawless Amethyst Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9❈ §r§5Flawless Amethyst Gemstone§r§a.".toPattern()
- ),
-
- ROUGH_JADE_GEMSTONE(
- "§fRough Jade Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§f☘ §r§fRough Jade Gemstone§r§a.".toPattern()
- ),
- FLAWED_JADE_GEMSTONE(
- "§aFlawed Jade Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§a☘ §r§aFlawed Jade Gemstone§r§a.".toPattern()
- ),
- FINE_JADE_GEMSTONE(
- "§9Fine Jade Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9☘ §r§9Fine Jade Gemstone§r§a.".toPattern()
- ),
- FLAWLESS_JADE_GEMSTONE(
- "§5Flawless Jade Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9☘ §r§5Flawless Jade Gemstone§r§a.".toPattern()
- ),
-
- ROUGH_TOPAZ_GEMSTONE(
- "§fRough Topaz Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§f✧ §r§fRough Topaz Gemstone§r§a.".toPattern()
- ),
- FLAWED_TOPAZ_GEMSTONE(
- "§aFlawed Topaz Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§a✧ §r§aFlawed Topaz Gemstone§r§a.".toPattern()
- ),
- FINE_TOPAZ_GEMSTONE(
- "§9Fine Topaz Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9✧ §r§9Fine Topaz Gemstone§r§a.".toPattern()
- ),
- FLAWLESS_TOPAZ_GEMSTONE(
- "§5Flawless Topaz Gemstone",
- "§aYou received §r§f(?<amount>.*) §r§9✧ §r§5Flawless Topaz Gemstone§r§a.".toPattern()
- ),
-
- FTX_3070("§9FTX 3070", "§aYou received §r§f(?<amount>.*) §r§9FTX 3070§r§a.".toPattern()),
- ELECTRON_TRANSIMTTER(
- "§9Electron Transmitter",
- "§aYou received §r§f(?<amount>.*) §r§9Electron Transmitter§r§a.".toPattern()
- ),
- ROBOTRON_REFLECTOR(
- "§9Robotron Reflector",
- "§aYou received §r§f(?<amount>.*) §r§9Robotron Reflector§r§a.".toPattern()
- ),
- SUPERLITE_MOTOR("§9Superlite Motor", "§aYou received §r§f(?<amount>.*) §r§9Superlite Motor§r§a.".toPattern()),
- CONTROL_SWITCH("§9Control Switch", "§aYou received §r§f(?<amount>.*) §r§9Control Switch§r§a.".toPattern()),
- SYNTHETIC_HEART("§9Synthetic Heart", "§aYou received §r§f(?<amount>.*) §r§9Synthetic Heart§r§a.".toPattern()),
-
- GOBLIN_EGG("§9Goblin Egg", "§aYou received §r§f(?<amount>.*) §r§9Goblin Egg§r§a.".toPattern()),
- GREEN_GOBLIN_EGG(
- "§aGreen Goblin Egg",
- "§aYou received §r§f(?<amount>.*) §r§a§r§aGreen Goblin Egg§r§a.".toPattern()
- ),
- RED_GOBLIN_EGG("§cRed Goblin Egg", "§aYou received §r§f(?<amount>.*) §r§9§r§cRed Goblin Egg§r§a.".toPattern()),
- YELLOW_GOBLIN_EGG(
- "§eYellow Goblin Egg",
- "§aYou received §r§f(?<amount>.*) §r§9§r§eYellow Goblin Egg§r§a.".toPattern()
- ),
- BLUE_GOBLIN_EGG("§3Blue Goblin Egg", "§aYou received §r§f(?<amount>.*) §r§9§r§3Blue Goblin Egg§r§a.".toPattern()),
-
- WISHING_COMPASS("§aWishing Compass", "§aYou received §r§f(?<amount>.*) §r§aWishing Compass§r§a.".toPattern()),
-
- SLUDGE_JUICE("§aSludge Juice", "§aYou received §r§f(?<amount>.*) §r§aSludge Juice§r§a.".toPattern()),
- ASCENSION_ROPE("§9Ascension Rope", "§aYou received §r§f(?<amount>.*) §r§9Ascension Rope§r§a.".toPattern()),
- TREASURITE("§5Treasurite", "§aYou received §r§f(?<amount>.*) §r§5Treasurite§r§a.".toPattern()),
- JUNGLE_HEART("§6Jungle Heart", "§aYou received §r§f(?<amount>.*) §r§6Jungle Heart§r§a.".toPattern()),
- PICKONIMBUS_2000("§5Pickonimbus 2000", "§aYou received §r§f(?<amount>.*) §r§5Pickonimbus 2000§r§a.".toPattern()),
- YOGGIE("§aYoggie", "§aYou received §r§f(?<amount>.*) §r§aYoggie§r§a.".toPattern()),
- PREHISTORIC_EGG("§fPrehistoric Egg", "§aYou received §r§f(?<amount>.*) §r§fPrehistoric Egg§r§a.".toPattern()),
- OIL_BARREL("§aOil Barrel", "§aYou received §r§f(?<amount>.*) §r§aOil Barrel§r§a.".toPattern()),
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderTracker.kt
deleted file mode 100644
index d4abba1b8..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/powdertracker/PowderTracker.kt
+++ /dev/null
@@ -1,366 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.powdertracker
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.config.Storage
-import at.hannibal2.skyhanni.data.IslandType
-import at.hannibal2.skyhanni.data.ProfileStorageData
-import at.hannibal2.skyhanni.events.ConfigLoadEvent
-import at.hannibal2.skyhanni.events.GuiRenderEvent
-import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
-import at.hannibal2.skyhanni.utils.LorenzUtils.addSelector
-import at.hannibal2.skyhanni.utils.LorenzUtils.afterChange
-import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
-import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber
-import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
-import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
-import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.inventory.GuiInventory
-import net.minecraft.entity.boss.BossStatus
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-import kotlin.concurrent.fixedRateTimer
-
-class PowderTracker {
-
- private val config get() = SkyHanniMod.feature.mining.powderTracker
- private var display = emptyList<List<Any>>()
- private val picked = "§6You have successfully picked the lock on this chest!".toPattern()
- private val uncovered = "§aYou uncovered a treasure chest!".toPattern()
- private val powderEvent = ".*§r§b§l2X POWDER STARTED!.*".toPattern()
- private val powderEnded = ".*§r§b§l2X POWDER ENDED!.*".toPattern()
- private val powderBossBar = "§e§lPASSIVE EVENT §b§l2X POWDER §e§lRUNNING FOR §a§l(?<time>.*)§r".toPattern()
- private var lastChestPicked = 0L
- private var isGrinding = false
- private val gemstoneInfo = ResourceInfo(0L, 0L, 0, 0.0, mutableListOf())
- private val mithrilInfo = ResourceInfo(0L, 0L, 0, 0.0, mutableListOf())
- private val chestInfo = ResourceInfo(0L, 0L, 0, 0.0, mutableListOf())
- private var doublePowder = false
- private var powderTimer = ""
- private var currentDisplayMode = DisplayMode.TOTAL
- private var inventoryOpen = false
- private var currentSessionData = mutableMapOf<Int, Storage.ProfileSpecific.PowderTracker>()
- private val gemstones = listOf(
- "Ruby" to "§c",
- "Sapphire" to "§b",
- "Amber" to "§6",
- "Amethyst" to "§5",
- "Jade" to "§a",
- "Topaz" to "§e"
- )
-
- init {
- fixedRateTimer(name = "skyhanni-powder-tracker", period = 1000) {
- if (!isEnabled()) return@fixedRateTimer
- calculateResourceHour(gemstoneInfo)
- calculateResourceHour(mithrilInfo)
- calculateResourceHour(chestInfo)
- }
- }
-
- @SubscribeEvent
- fun onRenderOverlay(event: GuiRenderEvent) {
- if (!isEnabled()) return
-
- val currentlyOpen = Minecraft.getMinecraft().currentScreen is GuiInventory
- if (inventoryOpen != currentlyOpen) {
- inventoryOpen = currentlyOpen
- saveAndUpdate()
- }
-
- if (config.onlyWhenPowderGrinding && !isGrinding) return
-
- config.position.renderStringsAndItems(
- display,
- posLabel = "Powder Chest Tracker"
- )
- }
-
- @SubscribeEvent
- fun onChat(event: LorenzChatEvent) {
- if (!isEnabled()) return
- val msg = event.message
- val both = currentLog() ?: return
-
- if (config.greatExplorerMaxed) {
- uncovered.matchMatcher(msg) {
- both.modify {
- it.totalChestPicked += 1
- }
- isGrinding = true
- lastChestPicked = System.currentTimeMillis()
- }
- }
-
- picked.matchMatcher(msg) {
- both.modify {
- it.totalChestPicked += 1
- }
- isGrinding = true
- lastChestPicked = System.currentTimeMillis()
- }
-
- powderEvent.matchMatcher(msg) { doublePowder = true }
- powderEnded.matchMatcher(msg) { doublePowder = false }
-
- for (reward in PowderChestReward.entries) {
- reward.pattern.matchMatcher(msg) {
- both.modify {
- val count = it.rewards[reward] ?: 0
- var amount = group("amount").formatNumber()
- if ((reward == PowderChestReward.MITHRIL_POWDER || reward == PowderChestReward.GEMSTONE_POWDER) && doublePowder)
- amount *= 2
- it.rewards[reward] = count + amount
- }
- }
- }
- saveAndUpdate()
- }
-
- @SubscribeEvent
- fun onTick(event: LorenzTickEvent) {
- if (!isEnabled()) return
- if (event.repeatSeconds(1)) {
- doublePowder = powderBossBar.matcher(BossStatus.bossName).find()
- powderBossBar.matchMatcher(BossStatus.bossName) {
- powderTimer = group("time")
- doublePowder = powderTimer != "00:00"
-
- saveAndUpdate()
- }
- }
- if (System.currentTimeMillis() - lastChestPicked > 60_000) {
- isGrinding = false
- }
- }
-
- @SubscribeEvent
- fun onConfigLoad(event: ConfigLoadEvent) {
- config.textFormat.afterChange { saveAndUpdate() }
- }
-
- @SubscribeEvent
- fun onWorldChange(event: LorenzWorldChangeEvent) {
- if (!isEnabled()) return
- gemstoneInfo.perHour = 0.0
- gemstoneInfo.stoppedChecks = 0
- gemstoneInfo.perMin.clear()
- mithrilInfo.perHour = 0.0
- mithrilInfo.stoppedChecks = 0
- mithrilInfo.perMin.clear()
- chestInfo.perHour = 0.0
- chestInfo.stoppedChecks = 0
- chestInfo.perMin.clear()
- doublePowder = false
- saveAndUpdate()
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "misc.powderTrackerConfig", "mining.powderTracker")
- }
-
- private fun saveAndUpdate() {
- calculateGemstone()
- calculateMithril()
- calculateChest()
- display = formatDisplay(drawDisplay())
- }
-
- private fun formatDisplay(map: List<List<Any>>) = buildList {
- if (map.isEmpty()) return@buildList
- for (index in config.textFormat.get()) {
- add(map[index])
- }
- }
-
- private fun drawDisplay() = buildList<List<Any>> {
- addAsSingletonList("§b§lPowder Tracker")
- if (inventoryOpen){
- addSelector<DisplayMode>(
- "§7Display Mode: ",
- getName = { type -> type.displayName },
- isCurrent = { it == currentDisplayMode },
- onChange = {
- currentDisplayMode = it
- saveAndUpdate()
- }
- )
- }else{
- addAsSingletonList("")
- }
-
- val both = currentLog() ?: return@buildList
- val display = both.get(currentDisplayMode)
- val rewards = display.rewards
-
- val chestPerHour = if (chestInfo.perHour < 0) 0 else chestInfo.perHour.toInt().addSeparators()
- addAsSingletonList("§d${display.totalChestPicked.addSeparators()} Total Chests Picked §7($chestPerHour/h)")
- addAsSingletonList("§bDouble Powder: ${if (doublePowder) "§aActive! §7($powderTimer)" else "§cInactive!"}")
-
- val mithril = PowderChestReward.entries[0]
- val mithrilCount = rewards.getOrDefault(mithril, 0).addSeparators()
- val mithrilPerHour = if (mithrilInfo.perHour < 0) 0 else mithrilInfo.perHour.toInt().addSeparators()
- addAsSingletonList("§b$mithrilCount ${mithril.displayName} §7($mithrilPerHour/h)")
-
- val gemstone = PowderChestReward.entries[1]
- val gemstoneCount = rewards.getOrDefault(gemstone, 0).addSeparators()
- val gemstonePerHour = if (gemstoneInfo.perHour < 0) 0 else gemstoneInfo.perHour.toInt().addSeparators()
- addAsSingletonList("§b$gemstoneCount ${gemstone.displayName} §7($gemstonePerHour/h)")
-
- addAsSingletonList("")
-
- for ((gem, color) in gemstones) {
- var totalGemstone = 0L
-
- for (quality in arrayOf("ROUGH", "FLAWED", "FINE", "FLAWLESS")) {
- val gemstoneType = PowderChestReward.valueOf("${quality}_${gem.uppercase()}_GEMSTONE")
- val count = rewards.getOrDefault(gemstoneType, 0)
- val multiplier = when (quality) {
- "FLAWED" -> 80
- "FINE" -> 6400
- "FLAWLESS" -> 512000
- else -> 1
- }
- totalGemstone += count * multiplier
- }
-
- val (flawless, fine, flawed, rough) = convert(totalGemstone)
- addAsSingletonList("§5${flawless}§7-§9${fine}§7-§a${flawed}§f-${rough} $color$gem Gemstone")
- }
-
- var totalParts = 0L
- for (reward in PowderChestReward.entries.subList(26, 32)) { // robots part
- val count = rewards.getOrDefault(reward, 0)
- totalParts += count
- addAsSingletonList("§b${count.addSeparators()} ${reward.displayName}")
- }
- addAsSingletonList("§b${totalParts.addSeparators()} §9Total Robot Parts")
-
- val goblinEgg = rewards.getOrDefault(PowderChestReward.GOBLIN_EGG, 0)
- val greenEgg = rewards.getOrDefault(PowderChestReward.GREEN_GOBLIN_EGG, 0)
- val redEgg = rewards.getOrDefault(PowderChestReward.RED_GOBLIN_EGG, 0)
- val yellowEgg = rewards.getOrDefault(PowderChestReward.YELLOW_GOBLIN_EGG, 0)
- val blueEgg = rewards.getOrDefault(PowderChestReward.BLUE_GOBLIN_EGG, 0)
- addAsSingletonList("§9$goblinEgg§7-§a$greenEgg§7-§c$redEgg§f-§e$yellowEgg§f-§3$blueEgg §fGoblin Egg")
-
- for (reward in PowderChestReward.entries.subList(37, 46)) {
- val count = rewards.getOrDefault(reward, 0).addSeparators()
- addAsSingletonList("§b$count ${reward.displayName}")
- }
-
-
- }
-
- private fun calculateResourceHour(resourceInfo: ResourceInfo) {
- val difference = resourceInfo.estimated - resourceInfo.lastEstimated
- resourceInfo.lastEstimated = resourceInfo.estimated
-
- if (difference == resourceInfo.estimated) {
- return
- }
-
- resourceInfo.perHour = resourceInfo.perMin.average() * 3600
- resourceInfo.perMin.add(difference)
-
- if (difference == 0L) {
- resourceInfo.stoppedChecks += 1
-
- if (resourceInfo.stoppedChecks == 60) {
- resourceInfo.stoppedChecks = 0
- resourceInfo.perMin.clear()
- resourceInfo.perHour = 0.0
- }
- return
- }
- resourceInfo.stoppedChecks = 0
- }
-
- private fun calculateGemstone() {
- val both = currentLog() ?: return
- val display = both.get(currentDisplayMode)
- val rewards = display.rewards
- gemstoneInfo.estimated = 0
- gemstoneInfo.estimated += rewards.getOrDefault(PowderChestReward.GEMSTONE_POWDER, 0)
- }
-
- private fun calculateMithril() {
- val both = currentLog() ?: return
- val display = both.get(currentDisplayMode)
- val rewards = display.rewards
- mithrilInfo.estimated = 0
- mithrilInfo.estimated += rewards.getOrDefault(PowderChestReward.MITHRIL_POWDER, 0)
- }
-
- private fun calculateChest() {
- val both = currentLog() ?: return
- val display = both.get(currentDisplayMode)
- chestInfo.estimated = 0
- chestInfo.estimated += display.totalChestPicked
- }
-
- private fun convert(roughCount: Long): Gem {
- val flawlessRatio = 512000
- val fineRatio = 6400
- val flawedRatio = 80
-
- val flawlessCount = roughCount / flawlessRatio
- val remainingAfterFlawless = roughCount % flawlessRatio
-
- val fineCount = remainingAfterFlawless / fineRatio
- val remainingAfterFine = remainingAfterFlawless % fineRatio
-
- val flawedCount = remainingAfterFine / flawedRatio
- val remainingRoughCount = remainingAfterFine % flawedRatio
-
- return Gem(flawlessCount, fineCount, flawedCount, remainingRoughCount)
- }
-
- data class Gem(val flawless: Long, val fine: Long, val flawed: Long, val rough: Long)
-
- private data class ResourceInfo(
- var estimated: Long,
- var lastEstimated: Long,
- var stoppedChecks: Int,
- var perHour: Double,
- val perMin: MutableList<Long>
- )
-
- enum class DisplayMode(val displayName: String) {
- TOTAL("Total"),
- CURRENT("This Session"),
- ;
- }
-
-
- private fun currentLog(): AbstractPowderTracker? {
- val profileSpecific = ProfileStorageData.profileSpecific ?: return null
-
- return AbstractPowderTracker(
- profileSpecific.powderTracker.getOrPut(0) { Storage.ProfileSpecific.PowderTracker() },
- currentSessionData.getOrPut(0) { Storage.ProfileSpecific.PowderTracker() }
- )
- }
-
- class AbstractPowderTracker(
- private val total: Storage.ProfileSpecific.PowderTracker,
- private val currentSession: Storage.ProfileSpecific.PowderTracker,
- ) {
-
- fun modify(modifyFunction: (Storage.ProfileSpecific.PowderTracker) -> Unit) {
- modifyFunction(total)
- modifyFunction(currentSession)
- }
-
- fun get(displayMode: DisplayMode) = when (displayMode) {
- DisplayMode.TOTAL -> total
- DisplayMode.CURRENT -> currentSession
- }
- }
-
- private fun isEnabled() =
- LorenzUtils.inSkyBlock && LorenzUtils.skyBlockIsland == IslandType.CRYSTAL_HOLLOWS && config.enabled
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/GetFromSacksTabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/GetFromSacksTabComplete.kt
deleted file mode 100644
index 50d1724e5..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/GetFromSacksTabComplete.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.tabcomplete
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.events.PacketEvent
-import at.hannibal2.skyhanni.events.RepositoryReloadEvent
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.jsonobjects.SackListJson
-import net.minecraft.network.play.client.C01PacketChatMessage
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-object GetFromSacksTabComplete {
- private val config get() = SkyHanniMod.feature.commands.tabComplete
- private var sackList = emptyList<String>()
- private val commands = arrayOf("gfs", "getfromsacks")
-
- @SubscribeEvent
- fun onRepoReload(event: RepositoryReloadEvent) {
- sackList = event.getConstant<SackListJson>("Sacks")?.sackList ?: return
- }
-
- fun handleTabComplete(command: String): List<String>? {
- if (!isEnabled()) return null
- if (command !in commands) return null
-
- return sackList.map { it.replace(" ", "_") }
- }
-
- @SubscribeEvent
- fun onSendPacket(event: PacketEvent.SendEvent) {
- if (!isEnabled()) return
-
- val packet = event.packet as? C01PacketChatMessage ?: return
- val message = packet.message
- if (commands.any { message.startsWith("/$it ") }) {
- val rawName = message.split(" ")[1]
- val realName = rawName.replace("_", " ")
- if (realName == rawName) return
- if (realName !in sackList) return
- event.isCanceled = true
- LorenzUtils.sendMessageToServer(message.replace(rawName, realName))
- }
- }
-
- fun isEnabled() = LorenzUtils.inSkyBlock && config.gfsSack
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/PlayerTabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/PlayerTabComplete.kt
deleted file mode 100644
index 28c9733a4..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/PlayerTabComplete.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.tabcomplete
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.data.FriendAPI
-import at.hannibal2.skyhanni.data.PartyAPI
-import at.hannibal2.skyhanni.events.RepositoryReloadEvent
-import at.hannibal2.skyhanni.utils.EntityUtils.isNPC
-import at.hannibal2.skyhanni.utils.jsonobjects.VipVisitsJson
-import net.minecraft.client.Minecraft
-import net.minecraft.client.entity.EntityOtherPlayerMP
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-object PlayerTabComplete {
- private val config get() = SkyHanniMod.feature.commands.tabComplete
- private var vipVisitsJson: VipVisitsJson? = null
-
- @SubscribeEvent
- fun onRepoReload(event: RepositoryReloadEvent) {
- vipVisitsJson = event.getConstant<VipVisitsJson>("VipVisits")
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "misc.tabCompleteCommands", "commands.tabComplete")
- }
-
- enum class PlayerCategory {
- PARTY,
- FRIENDS,
- ISLAND_PLAYERS,
- }
-
- fun handleTabComplete(command: String): List<String>? {
- val commands = mapOf(
- "p" to listOf(PlayerCategory.PARTY),
- "party" to listOf(PlayerCategory.PARTY),
- "pt" to listOf(PlayerCategory.FRIENDS, PlayerCategory.ISLAND_PLAYERS), // /party transfer
- "f" to listOf(PlayerCategory.FRIENDS),
- "friend" to listOf(PlayerCategory.FRIENDS),
-
- "msg" to listOf(),
- "w" to listOf(),
- "tell" to listOf(),
- "boop" to listOf(),
-
- "visit" to listOf(),
- "invite" to listOf(),
- "ah" to listOf(),
-
- "pv" to listOf(), // NEU's Profile Viewer
- "shmarkplayer" to listOf(), // SkyHanni's Mark Player
- )
- val ignored = commands[command] ?: return null
-
- return buildList {
-
- if (config.friends && PlayerCategory.FRIENDS !in ignored) {
- FriendAPI.getAllFriends().filter { it.bestFriend || !config.onlyBestFriends }
- .forEach { add(it.name) }
- }
-
- if (config.islandPlayers && PlayerCategory.ISLAND_PLAYERS !in ignored) {
- for (entity in Minecraft.getMinecraft().theWorld.playerEntities) {
- if (!entity.isNPC() && entity is EntityOtherPlayerMP) {
- add(entity.name)
- }
- }
- }
-
- if (config.party && PlayerCategory.PARTY !in ignored) {
- for (member in PartyAPI.partyMembers) {
- add(member)
- }
- }
-
- if (config.vipVisits && command == "visit") {
- vipVisitsJson?.let {
- for (visit in it.vipVisits) {
- add(visit)
- }
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/TabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/TabComplete.kt
deleted file mode 100644
index b003de699..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/TabComplete.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.tabcomplete
-
-import at.hannibal2.skyhanni.features.misc.CollectionTracker
-
-object TabComplete {
-
- @JvmStatic
- fun handleTabComplete(leftOfCursor: String, originalArray: Array<String>): Array<String>? {
- val splits = leftOfCursor.split(" ")
- if (splits.size > 1) {
- var command = splits.first().lowercase()
- if (command.startsWith("/")) {
- command = command.substring(1)
- customTabComplete(command)?.let {
- return buildResponse(splits, it).toSet().toTypedArray()
- }
- }
- }
- return null
- }
-
- private fun customTabComplete(command: String): List<String>? {
- GetFromSacksTabComplete.handleTabComplete(command)?.let { return it }
- WarpTabComplete.handleTabComplete(command)?.let { return it }
- PlayerTabComplete.handleTabComplete(command)?.let { return it }
- CollectionTracker.handleTabComplete(command)?.let { return it }
-
- return null
- }
-
- private fun buildResponse(arguments: List<String>, fullResponse: List<String>): List<String> {
- if (arguments.size == 2) {
- val start = arguments[1].lowercase()
- return fullResponse.filter { it.lowercase().startsWith(start) }
- }
- return emptyList()
- }
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/WarpTabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/WarpTabComplete.kt
deleted file mode 100644
index 034ea12dc..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/tabcomplete/WarpTabComplete.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.tabcomplete
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.events.RepositoryReloadEvent
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.jsonobjects.WarpsJson
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-object WarpTabComplete {
- private val config get() = SkyHanniMod.feature.commands.tabComplete
- private var warpsJson: WarpsJson? = null
-
- @SubscribeEvent
- fun onRepoReload(event: RepositoryReloadEvent) {
- warpsJson = event.getConstant<WarpsJson>("Warps")
- }
-
- fun handleTabComplete(command: String): List<String>? {
- if (!isEnabled()) return null
- if (command != "warp") return null
-
- return warpsJson?.warpCommands
- }
-
- fun isEnabled() = LorenzUtils.inSkyBlock && config.warps
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/Relay.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/Relay.kt
deleted file mode 100644
index 14804bfd9..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/Relay.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.tiarelay
-
-import at.hannibal2.skyhanni.data.IslandType
-import at.hannibal2.skyhanni.utils.LorenzVec
-
-enum class Relay(
- val relayName: String,
- val waypoint: LorenzVec,
- val island: IslandType,
- val chatMessage: String
-) {
- RELAY_1(
- "1st Relay", LorenzVec(143.5, 108.0, 93.0), IslandType.HUB,
- "§e[NPC] §dTia the Fairy§f: §b✆ §f§rThe first relay is on a branch of the large tree on the north-east of the fairy pond."
- ),
- RELAY_2(
- "2nd Relay", LorenzVec(-246.5, 123.0, 55.5), IslandType.HUB,
- "§e[NPC] §dTia the Fairy§f: §b✆ §f§rThe next relay is in the castle ruins!"
- ),
- RELAY_3(
- "3rd Relay", LorenzVec(128.5, 232.0, 200.5), IslandType.DWARVEN_MINES,
- "§e[NPC] §dTia the Fairy§f: §b✆ §f§rThe next relay is in the §bRoyal Palace §rwithin the Dwarven Mines."
- ),
- RELAY_4(
- "4th Relay", LorenzVec(-560, 164, -287), IslandType.THE_END,
- "§e[NPC] §dTia the Fairy§f: §b✆ §f§rThe next relay is on the highest spike of §dThe End§r."
- ),
- RELAY_5(
- "5th Relay", LorenzVec(-375, 207, -799), IslandType.CRIMSON_ISLE,
- "§e[NPC] §dTia the Fairy§f: §b✆ §f§rThe next relay was placed by our consultant, Odger."
- ),
- RELAY_6(
- "6th Relay", LorenzVec(-69, 157, -879), IslandType.CRIMSON_ISLE,
- "§e[NPC] §dTia the Fairy§f: §b✆ §f§rScarleton itself has one of the most robust connection to the 9f™ Network."
- ),
- RELAY_7(
- "7th Relay", LorenzVec(93, 86, 187), IslandType.HUB,
- "§e[NPC] §dTia the Fairy§f: §b✆ §f§rThe next relay is on top of the shack next to the shady inn right here close to the pond."
- ),
- RELAY_8(
- "8th Relay", LorenzVec(0, 146, -75), IslandType.DUNGEON_HUB,
- "§e[NPC] §dTia the Fairy§f: §b✆ §f§rThe next relay is on top of a statue in the dungeon hub."
- ),
- RELAY_9(
- "9th Relay", LorenzVec(-19.0, 88.5, -91.0), IslandType.HUB,
- "§e[NPC] §dTia the Fairy§f: §b✆ §f§rThe next relay is on top of the Auction House."
- ),
-}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/TiaRelayHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/TiaRelayHelper.kt
deleted file mode 100644
index 8d7c52c7b..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/TiaRelayHelper.kt
+++ /dev/null
@@ -1,146 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.tiarelay
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
-import at.hannibal2.skyhanni.events.GuiContainerEvent
-import at.hannibal2.skyhanni.events.LorenzTickEvent
-import at.hannibal2.skyhanni.events.PlaySoundEvent
-import at.hannibal2.skyhanni.events.RenderInventoryItemTipEvent
-import at.hannibal2.skyhanni.utils.InventoryUtils
-import at.hannibal2.skyhanni.utils.ItemUtils.getLore
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzUtils.sorted
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-class TiaRelayHelper {
- private val config get() = SkyHanniMod.feature.inventory.helper.tiaRelay
- private var inInventory = false
-
- private var lastClickSlot = 0
- private var lastClickTime = 0L
- private var sounds = mutableMapOf<Int, Sound>()
-
- private var resultDisplay = mutableMapOf<Int, Int>()
-
- @SubscribeEvent
- fun onSoundPlay(event: PlaySoundEvent) {
- if (!LorenzUtils.inSkyBlock) return
- val soundName = event.soundName
-
- if (config.tiaRelayMute && soundName == "mob.wolf.whine") {
- event.isCanceled = true
- }
-
- if (!config.soundHelper) return
- if (!inInventory) return
-
- val distance = event.distanceToPlayer
- if (distance >= 2) return
-
- if (lastClickSlot == 0) return
- val duration = System.currentTimeMillis() - lastClickTime
- if (duration > 1_000) return
- if (sounds.contains(lastClickSlot)) return
-
- sounds[lastClickSlot] = Sound(soundName, event.pitch)
-
- lastClickSlot = 0
-
- tryResult()
- }
-
- @SubscribeEvent
- fun onTick(event: LorenzTickEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (!config.soundHelper) return
-
- if (event.repeatSeconds(1)) {
- if (InventoryUtils.openInventoryName().contains("Network Relay")) {
- inInventory = true
- } else {
- inInventory = false
- sounds.clear()
- resultDisplay.clear()
- }
- }
- }
-
- private fun tryResult() {
- if (sounds.size < 4) return
-
- val name = sounds.values.first().name
- for (sound in sounds.toMutableMap()) {
- if (sound.value.name != name) {
- LorenzUtils.chat("§c[SkyHanni] Tia Relay Helper error: Too much background noise! Please try again.")
- sounds.clear()
- return
- }
- }
-
- val pitchMap = mutableMapOf<Int, Float>()
- for (sound in sounds) {
- pitchMap[sound.key] = sound.value.pitch
- }
- sounds.clear()
- resultDisplay.clear()
-
- var i = 1
- for (entry in pitchMap.sorted()) {
- resultDisplay[entry.key] = i
- i++
- }
- }
-
- @SubscribeEvent
- fun onRenderItemTip(event: RenderInventoryItemTipEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (!config.soundHelper) return
- if (!inInventory) return
-
- val slot = event.slot
- val stack = slot.stack
-
- val slotNumber = slot.slotNumber
-
- val position = resultDisplay.getOrDefault(slotNumber, null)
- if (position != null) {
- if (stack.getLore().any { it.contains("Done!") }) {
- resultDisplay.clear()
- return
- }
- event.stackTip = "#$position"
- return
- }
-
- if (!sounds.contains(slotNumber) && stack.getLore().any { it.contains("Hear!") }) {
- event.stackTip = "Hear!"
- event.offsetX = 5
- event.offsetY = -5
- return
- }
- }
-
- @SubscribeEvent
- fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (!config.soundHelper) return
- if (!inInventory) return
-
- // only listen to right clicks
- if (event.clickedButton != 1) return
-
- lastClickSlot = event.slotId
- lastClickTime = System.currentTimeMillis()
- }
-
- @SubscribeEvent
- fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
- event.move(2, "misc.tiaRelayMute", "inventory.helper.tiaRelay.tiaRelayMute")
- event.move(2, "misc.tiaRelayHelper", "inventory.helper.tiaRelay.soundHelper")
-
- event.move(2, "misc.tiaRelayNextWaypoint", "inventory.helper.tiaRelay.nextWaypoint")
- event.move(2, "misc.tiaRelayAllWaypoints", "inventory.helper.tiaRelay.allWaypoints")
- }
-
- class Sound(val name: String, val pitch: Float)
-} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/TiaRelayWaypoints.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/TiaRelayWaypoints.kt
deleted file mode 100644
index ab2320543..000000000
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/tiarelay/TiaRelayWaypoints.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-package at.hannibal2.skyhanni.features.misc.tiarelay
-
-import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.data.IslandType
-import at.hannibal2.skyhanni.events.LorenzChatEvent
-import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
-import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled
-import at.hannibal2.skyhanni.utils.LorenzColor
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.LorenzVec
-import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-
-class TiaRelayWaypoints {
- private val config get() = SkyHanniMod.feature.inventory.helper.tiaRelay
- private var waypoint: LorenzVec? = null
- private var waypointName: String? = null
- private var island = IslandType.NONE
-
- @SubscribeEvent
- fun onChatMessage(event: LorenzChatEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (!config.nextWaypoint) return
-
- val message = event.message
- for (relay in Relay.entries) {
- if (relay.chatMessage == message) {
- waypoint = relay.waypoint
- waypointName = relay.relayName
- island = relay.island
- return
- }
- }
-
- if (message == "§aYou completed the maintenance on the relay!") {
- waypoint = null
- island = IslandType.NONE
- }
- }
-
- @SubscribeEvent
- fun onRenderWorld(event: LorenzRenderWorldEvent) {
- if (!LorenzUtils.inSkyBlock) return
-
- if (config.allWaypoints) {
- for (relay in Relay.entries) {
- if (relay.island == LorenzUtils.skyBlockIsland) {
- event.drawWaypointFilled(relay.waypoint, LorenzColor.LIGHT_PURPLE.toColor())
- event.drawDynamicText(relay.waypoint, "§d" + relay.relayName, 1.5)
- }
- }
- return
- }
-
- if (!config.nextWaypoint) return
- if (LorenzUtils.skyBlockIsland != island) return
-
- waypoint?.let {
- event.drawWaypointFilled(it, LorenzColor.LIGHT_PURPLE.toColor())
- event.drawDynamicText(it, "§d" + waypointName!!, 1.5)
- }
- }
-} \ No newline at end of file