diff options
author | Eric W <42985687+ericpretzel@users.noreply.github.com> | 2023-09-10 00:12:30 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-10 09:12:30 +0200 |
commit | 8dabd75537ad58654018b29c144143d43cf956fa (patch) | |
tree | df7f036fdbe0a633db6fce24a65b81bbc8a3c066 /src/main/java/at/hannibal2/skyhanni/features/misc | |
parent | c54eccb4204d0d1212b71020b05c1c01d5be0fe1 (diff) | |
download | skyhanni-8dabd75537ad58654018b29c144143d43cf956fa.tar.gz skyhanni-8dabd75537ad58654018b29c144143d43cf956fa.tar.bz2 skyhanni-8dabd75537ad58654018b29c144143d43cf956fa.zip |
Fixed Ender Node Tracker tracking Mite Gel incorrectly and npc/george/lowest bin price problems. #430
* fix not using lBIN for certain items
* set loaded to true before broadcasting ConfigLoadEvent
* now accurately tracks mite gel
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features/misc')
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt | 155 |
1 files changed, 86 insertions, 69 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 a6a9d44d3..a66079f08 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/EnderNodeTracker.kt @@ -4,39 +4,36 @@ import at.hannibal2.skyhanni.SkyHanniMod 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 @@ -47,7 +44,7 @@ class EnderNodeTracker { // 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 +56,65 @@ 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 onSoundPlay(event: PlaySoundEvent) { + 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 - 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() + + val change = event.sackChanged + .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: OwnInventorItemUpdateEvent) { + if (!config.enabled) return + if (!isInTheEnd()) return + if (!ProfileStorageData.loaded) 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,46 +127,34 @@ class EnderNodeTracker { @SubscribeEvent fun onConfigLoad(event: ConfigLoadEvent) { config.textFormat.afterChange { - saveAndUpdate() + update() } - - 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() + ?: 0 + update() } private fun calculateProfit(): 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 - + private fun update() { lootProfit = calculateProfit() display = formatDisplay(drawDisplay()) } @@ -149,12 +162,12 @@ class EnderNodeTracker { 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,14 +182,16 @@ class EnderNodeTracker { } private fun drawDisplay() = 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)") } @@ -186,17 +201,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]) |