diff options
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt')
| -rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt | 171 |
1 files changed, 96 insertions, 75 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt index 9205b0154..133e12ab4 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt @@ -1,42 +1,39 @@ package at.hannibal2.skyhanni.features.misc import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.Storage import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.ProfileStorageData -import at.hannibal2.skyhanni.data.ScoreboardData -import at.hannibal2.skyhanni.events.ConfigLoadEvent -import at.hannibal2.skyhanni.events.GuiRenderEvent -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.PlaySoundEvent -import at.hannibal2.skyhanni.features.bazaar.BazaarApi.Companion.getBazaarData +import at.hannibal2.skyhanni.events.* +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.LorenzUtils.afterChange import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull -import at.hannibal2.skyhanni.utils.NEUItems.getPrice +import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.NumberUtil.format import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems +import io.github.moulberry.notenoughupdates.util.MinecraftExecutor +import net.minecraft.client.Minecraft import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class EnderNodeTracker { private val config get() = SkyHanniMod.feature.misc.enderNodeTracker + private val storage get() = ProfileStorageData.profileSpecific?.enderNodeTracker - private var totalNodesMined = 0 - private var totalEndermiteNests = 0 private var totalEnderArmor = 0 + private var miteGelInInventory = 0 private var display = emptyList<List<Any>>() - private var lootCount = mapOf<EnderNode, Int>() private var lootProfit = mapOf<EnderNode, Double>() private val enderNodeRegex = Regex("""ENDER NODE!.+You found (\d+x )?§r(.+)§r§f!""") private val endermanRegex = Regex("""(RARE|PET) DROP! §r(.+) §r§b\(""") - private var lastEndermiteTime = 0L - @SubscribeEvent fun onChat(event: LorenzChatEvent) { + if (!config.enabled) return if (!ProfileStorageData.loaded) return if (!isInTheEnd()) return @@ -44,10 +41,11 @@ class EnderNodeTracker { val message = event.message.trim() var item: String? = null var amount = 1 + val storage = storage ?: return // check whether the loot is from an ender node or an enderman enderNodeRegex.find(message)?.let { - totalNodesMined++ + storage.totalNodesMined++ amount = it.groups[1]?.value?.substringBefore("x")?.toIntOrNull() ?: 1 item = it.groups[2]?.value } ?: endermanRegex.find(message)?.let { @@ -59,37 +57,67 @@ class EnderNodeTracker { item == null -> return isEnderArmor(item) -> totalEnderArmor++ item == "§cEndermite Nest" -> { - lastEndermiteTime = System.currentTimeMillis() - totalEndermiteNests++ + storage.totalEndermiteNests++ } } // increment the count of the specific item found EnderNode.entries.find { it.displayName == item }?.let { - val old = lootCount[it] ?: 0 - lootCount = lootCount.editCopy { + val old = storage.lootCount[it] ?: 0 + storage.lootCount = storage.lootCount.editCopy { this[it] = old + amount } } - saveAndUpdate() + update() + } + + @SubscribeEvent + fun onIslandChange(event: IslandChangeEvent) { + if (!config.enabled) return + if (event.newIsland != IslandType.THE_END) return + miteGelInInventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory + .filter { it?.getInternalNameOrNull() == EnderNode.MITE_GEL.internalName } + .sumOf { it.stackSize } + } + + @SubscribeEvent + fun onSackChange(event: SackChangeEvent) { + if (!config.enabled) return + if (!ProfileStorageData.loaded) return + if (!isInTheEnd()) return + val storage = storage ?: return + + val change = event.sackChanges + .firstOrNull { it.internalName == EnderNode.MITE_GEL.internalName && it.delta > 0 } + ?: return + val old = storage.lootCount[EnderNode.MITE_GEL] ?: 0 + storage.lootCount = storage.lootCount.editCopy { + this[EnderNode.MITE_GEL] = old + change.delta + } + update() } @SubscribeEvent - fun onSoundPlay(event: PlaySoundEvent) { + fun onInventoryUpdate(event: OwnInventoryItemUpdateEvent) { + if (!config.enabled) return if (!isInTheEnd()) return - if (event.soundName != "mob.silverfish.kill") return - if (event.distanceToPlayer > 15) return - if (System.currentTimeMillis() - lastEndermiteTime > 7500) return - - // listen for nearby endermite death sounds within 7.5s of mining an endermite nest - // this is a fairly accurate approximation for mite gel drops - val oldEndStone = lootCount[EnderNode.ENCHANTED_ENDSTONE] ?: 0 - val oldMiteGel = lootCount[EnderNode.MITE_GEL] ?: 0 - lootCount = lootCount.editCopy { - this[EnderNode.ENCHANTED_ENDSTONE] = oldEndStone + (1 + Math.random() * 2).toInt() - this[EnderNode.MITE_GEL] = oldMiteGel + (1 + Math.random() * 2).toInt() + if (!ProfileStorageData.loaded) return + val storage = storage ?: return + + MinecraftExecutor.OnThread.execute { + val newMiteGelInInventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory + .filter { it?.getInternalNameOrNull() == EnderNode.MITE_GEL.internalName } + .sumOf { it.stackSize } + val change = newMiteGelInInventory - miteGelInInventory + if (change > 0) { + val old = storage.lootCount[EnderNode.MITE_GEL] ?: 0 + storage.lootCount = storage.lootCount.editCopy { + this[EnderNode.MITE_GEL] = old + change + } + update() + } + miteGelInInventory = newMiteGelInInventory } - saveAndUpdate() } @SubscribeEvent @@ -102,60 +130,49 @@ class EnderNodeTracker { @SubscribeEvent fun onConfigLoad(event: ConfigLoadEvent) { config.textFormat.afterChange { - saveAndUpdate() + update() } + val storage = storage ?: return - val hidden = ProfileStorageData.profileSpecific?.enderNodeTracker ?: return - totalNodesMined = hidden.totalNodesMined - totalEndermiteNests = hidden.totalEndermiteNests - lootCount = hidden.lootCount - totalEnderArmor = hidden.lootCount.filter { isEnderArmor(it.key.displayName) }.map { it.value }.sum() - saveAndUpdate() + totalEnderArmor = storage.lootCount.filter { isEnderArmor(it.key.displayName) } + .map { it.value } + .sum() + update() } - private fun calculateProfit(): Map<EnderNode, Double> { + private fun calculateProfit(storage: Storage.ProfileSpecific.EnderNodeTracker): Map<EnderNode, Double> { + if (!ProfileStorageData.loaded) return emptyMap() + val newProfit = mutableMapOf<EnderNode, Double>() - lootCount.forEach { (key, _) -> - val price = if (isEnderArmor(key.displayName)) { + storage.lootCount.forEach { (item, amount) -> + val price = if (isEnderArmor(item.displayName)) { 10_000.0 } else { - val internalName = key.internalName - val npcPrice = internalName.getNpcPriceOrNull() - val bazaarData = internalName.getBazaarData() - if (LorenzUtils.noTradeMode || bazaarData == null) { - npcPrice ?: georgePrice(key) ?: 0.0 - } else { - npcPrice - ?.coerceAtLeast(bazaarData.sellPrice) - ?.coerceAtLeast(georgePrice(key) ?: 0.0) - ?: internalName.getPrice() - } + (if (!LorenzUtils.noTradeMode) item.internalName.getPriceOrNull() else 0.0) + ?.coerceAtLeast(item.internalName.getNpcPriceOrNull() ?: 0.0) + ?.coerceAtLeast(georgePrice(item) ?: 0.0) + ?: 0.0 } - newProfit[key] = price * (lootCount[key] ?: 0) + newProfit[item] = price * amount } return newProfit } - private fun saveAndUpdate() { - val hidden = ProfileStorageData.profileSpecific?.enderNodeTracker ?: return - hidden.totalNodesMined = totalNodesMined - hidden.totalEndermiteNests = totalEndermiteNests - hidden.lootCount = lootCount - - lootProfit = calculateProfit() - display = formatDisplay(drawDisplay()) + private fun update() { + val storage = storage ?: return + lootProfit = calculateProfit(storage) + display = formatDisplay(drawDisplay(storage)) } - private fun isInTheEnd() = LorenzUtils.inIsland(IslandType.THE_END) - && ScoreboardData.sidebarLines.any { it.contains("The End") } + private fun isInTheEnd() = LorenzUtils.skyBlockArea == "The End" private fun isEnderArmor(displayName: String?) = when (displayName) { - "§5Ender Helmet", - "§5Ender Chestplate", - "§5Ender Leggings", - "§5Ender Boots", - "§5Ender Necklace", - "§5Ender Gauntlet" -> true + EnderNode.END_HELMET.displayName, + EnderNode.END_CHESTPLATE.displayName, + EnderNode.END_LEGGINGS.displayName, + EnderNode.END_BOOTS.displayName, + EnderNode.ENDER_NECKLACE.displayName, + EnderNode.ENDER_GAUNTLET.displayName -> true else -> false } @@ -169,15 +186,17 @@ class EnderNodeTracker { else -> null } - private fun drawDisplay() = buildList<List<Any>> { + private fun drawDisplay(storage: Storage.ProfileSpecific.EnderNodeTracker) = buildList<List<Any>> { + if (!ProfileStorageData.loaded) return emptyList<List<Any>>() + addAsSingletonList("§5§lEnder Node Tracker") - addAsSingletonList("§d${totalNodesMined.addSeparators()} Ender Nodes mined") + addAsSingletonList("§d${storage.totalNodesMined.addSeparators()} Ender Nodes mined") addAsSingletonList("§6${format(lootProfit.values.sum())} Coins made") addAsSingletonList(" ") - addAsSingletonList("§b${totalEndermiteNests.addSeparators()} §cEndermite Nest") + addAsSingletonList("§b${storage.totalEndermiteNests.addSeparators()} §cEndermite Nest") for (item in EnderNode.entries.subList(0, 11)) { - val count = (lootCount[item] ?: 0).addSeparators() + val count = (storage.lootCount[item] ?: 0).addSeparators() val profit = format(lootProfit[item] ?: 0.0) addAsSingletonList("§b$count ${item.displayName} §7(§6$profit§7)") } @@ -187,17 +206,19 @@ class EnderNodeTracker { "§7(§6${format(totalEnderArmor * 10_000)}§7)" ) for (item in EnderNode.entries.subList(11, 16)) { - val count = (lootCount[item] ?: 0).addSeparators() + val count = (storage.lootCount[item] ?: 0).addSeparators() val profit = format(lootProfit[item] ?: 0.0) addAsSingletonList("§b$count ${item.displayName} §7(§6$profit§7)") } // enderman pet rarities - val (c, u, r, e, l) = EnderNode.entries.subList(16, 21).map { (lootCount[it] ?: 0).addSeparators() } + val (c, u, r, e, l) = EnderNode.entries.subList(16, 21).map { (storage.lootCount[it] ?: 0).addSeparators() } val profit = format(EnderNode.entries.subList(16, 21).sumOf { lootProfit[it] ?: 0.0 }) addAsSingletonList("§f$c§7-§a$u§7-§9$r§7-§5$e§7-§6$l §fEnderman Pet §7(§6$profit§7)") } private fun formatDisplay(map: List<List<Any>>): List<List<Any>> { + if (!ProfileStorageData.loaded) return emptyList() + val newList = mutableListOf<List<Any>>() for (index in config.textFormat.get()) { newList.add(map[index]) |
