aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/DetectBrokenHyperion.kt52
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt184
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt54
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerType.kt5
4 files changed, 294 insertions, 1 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/DetectBrokenHyperion.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/DetectBrokenHyperion.kt
new file mode 100644
index 000000000..53baff2f1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/DetectBrokenHyperion.kt
@@ -0,0 +1,52 @@
+package at.hannibal2.skyhanni.features.slayer
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.SlayerAPI
+import at.hannibal2.skyhanni.data.TitleUtils
+import at.hannibal2.skyhanni.events.PurseChangeCause
+import at.hannibal2.skyhanni.events.PurseChangeEvent
+import at.hannibal2.skyhanni.utils.LorenzLogger
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+class DetectBrokenHyperion {
+ private val config get() = SkyHanniMod.feature.slayer
+ private var brokenInRow = 0
+ private val logger = LorenzLogger("detect_broken_hyperion")
+
+ @SubscribeEvent
+ fun onPurseChange(event: PurseChangeEvent) {
+ if (!isEnabled()) return
+ if (event.reason != PurseChangeCause.GAIN_MOB_KILL) return
+ if (!SlayerAPI.hasActiveSlayerQuest()) return
+ if (!SlayerAPI.isInSlayerArea) return
+
+ val diff = System.currentTimeMillis() - SlayerAPI.getLatestProgressChangeTime()
+ logger.log("diff: $diff")
+
+ if (diff < 2_500) {
+ if (brokenInRow != 0) {
+
+ brokenInRow = 0
+ logger.log(" reset to 0")
+ }
+ return
+ }
+
+ brokenInRow++
+ logger.log(" add: $brokenInRow")
+
+ if (brokenInRow > 5) {
+ logger.log(" send warning!")
+ TitleUtils.sendTitle("§eBroken Hyperion!", 3_000)
+ LorenzUtils.chat(
+ "§e[SkyHanni] Your Hyperion is broken! It no longer collects combat exp. " +
+ "Kill a mob with meele-hits to fix this hypixel bug"
+ )
+ }
+
+ LorenzUtils.debug("diff: $diff")
+ }
+
+ fun isEnabled() = LorenzUtils.inSkyBlock && config.brokenHyperion
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt
new file mode 100644
index 000000000..33f9f3170
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemProfitTracker.kt
@@ -0,0 +1,184 @@
+package at.hannibal2.skyhanni.features.slayer
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.SlayerAPI
+import at.hannibal2.skyhanni.events.*
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment
+import at.hannibal2.skyhanni.utils.LorenzLogger
+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.LorenzUtils.sortedDesc
+import at.hannibal2.skyhanni.utils.NEUItems
+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.removeColor
+import com.google.common.cache.CacheBuilder
+import net.minecraft.client.Minecraft
+import net.minecraft.entity.item.EntityItem
+import net.minecraft.network.play.server.S0DPacketCollectItem
+import net.minecraftforge.fml.common.eventhandler.EventPriority
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.util.concurrent.TimeUnit
+
+class SlayerItemProfitTracker {
+ private val config get() = SkyHanniMod.feature.slayer.itemProfitTracker
+ private var collectedCache = CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS).build<Int, Unit>()
+
+ private var itemLogCategory = ""
+ private var display = listOf<List<Any>>()
+ private var itemLogs = mapOf<String, ItemLog>()
+ private val logger = LorenzLogger("slayer_item_profit_tracker")
+
+ private fun addSlayerCosts(price: Double) {
+ val itemLog = currentLog() ?: return
+
+ val name = "Slayer Spawn Costs"
+ itemLog.items = itemLog.items.editCopy {
+ val (oldCoins, oldAmount) = getOrDefault(name, 0.0 to 0)
+ this[name] = oldCoins + price to oldAmount + 1
+ }
+ update()
+ }
+
+ @SubscribeEvent
+ fun onPurseChange(event: PurseChangeEvent) {
+ if (!isEnabled()) return
+ val coins = event.coins
+ if (event.reason == PurseChangeCause.GAIN_MOB_KILL) {
+ if (SlayerAPI.isInSlayerArea) {
+ logger.log("Coins gained for killing mobs: ${coins.addSeparators()}")
+ addMobKillCoins(coins)
+ }
+ }
+ if (event.reason == PurseChangeCause.LOSE_SLAYER_QUEST_STARTED) {
+ logger.log("Coins paid for starting slayer quest: ${coins.addSeparators()}")
+ addSlayerCosts(coins)
+ }
+ }
+
+ @SubscribeEvent
+ fun onSlayerChange(event: SlayerChangeEvent) {
+ val newSlayer = event.newSlayer
+ itemLogCategory = if (newSlayer == "") {
+ ""
+ } else {
+ newSlayer.split(" ").dropLast(1).joinToString(" ")
+ }
+ update()
+ }
+
+ private fun addMobKillCoins(coins: Double) {
+ val itemLog = currentLog() ?: return
+
+ itemLog.mobKillCoins += coins
+ update()
+ }
+
+ private fun addItemPickup(totalPrice: Double, displayName: String, stackSize: Int) {
+ val itemLog = currentLog() ?: return
+
+ itemLog.items = itemLog.items.editCopy {
+ val (oldCoins, oldAmount) = getOrDefault(displayName, 0.0 to 0)
+ this[displayName] = oldCoins + totalPrice to oldAmount + stackSize
+ }
+ update()
+ }
+
+ private fun currentLog(): ItemLog? {
+ if (itemLogCategory == "") return null
+
+ itemLogs[itemLogCategory]?.let {
+ return it
+ }
+
+ val itemLog = ItemLog(itemLogCategory)
+ itemLogs = itemLogs.editCopy { this[itemLogCategory] = itemLog }
+
+ return itemLog
+ }
+
+ @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true)
+ fun onChatPacket(event: PacketEvent.ReceiveEvent) {
+ if (!isEnabled()) return
+ if (!SlayerAPI.isInSlayerArea) return
+
+ val packet = event.packet
+ if (packet !is S0DPacketCollectItem) return
+
+ val entityID = packet.collectedItemEntityID
+ val item = Minecraft.getMinecraft().theWorld.getEntityByID(entityID) ?: return
+ if (item !is EntityItem) return
+
+ if (collectedCache.getIfPresent(entityID) != null) return
+ collectedCache.put(entityID, Unit)
+
+ val itemStack = item.entityItem
+ val name = itemStack.name ?: return
+ if (SlayerAPI.ignoreSlayerDrop(name)) return
+ val internalName = itemStack.getInternalName()
+ if (internalName == "") return
+
+ val (itemName, price) = SlayerAPI.getItemNameAndPrice(itemStack)
+ val displayName = NEUItems.getItemStack(internalName).nameWithEnchantment ?: "internalName"
+ addItemPickup(price, displayName, itemStack.stackSize)
+ logger.log("Coins gained for picking up an item ($itemName) ${price.addSeparators()}")
+ if (config.priceInChat) {
+ if (config.minimumPrice < price) {
+ LorenzUtils.chat("§e[SkyHanni] §a+Slayer Drop§7: §r$itemName")
+ }
+ }
+ }
+
+ fun update() {
+ display = drawDisplay()
+ }
+
+ private fun drawDisplay() = buildList<List<Any>> {
+ val itemLog = currentLog() ?: return@buildList
+
+ val displayName = itemLog.displayName.removeColor()
+ addAsSingletonList("§e§l$displayName Profit Tracker")
+ var profit = 0.0
+ val map = mutableMapOf<String, Double>()
+ for ((name, value) in itemLog.items) {
+ val (price, amount) = value
+ val profitPrefix = if (price < 0) "§c" else "§6"
+ val priceFormat = NumberUtil.format(price)
+ map["§7${amount.addSeparators()}x $name§7: $profitPrefix$priceFormat"] = price
+ profit += price
+ }
+ val mobKillCoins = itemLog.mobKillCoins
+ if (mobKillCoins != 0.0) {
+ val mobKillCoinsFormat = NumberUtil.format(mobKillCoins)
+ map["§7Mob kill coins: §6$mobKillCoinsFormat"] = mobKillCoins
+ }
+
+ for (text in map.sortedDesc().keys) {
+ addAsSingletonList(" $text")
+ }
+
+ profit += mobKillCoins
+ val profitFormat = NumberUtil.format(profit)
+ val profitPrefix = if (profit < 0) "§c" else "§6"
+ addAsSingletonList("§eTotal Profit: $profitPrefix$profitFormat")
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent) {
+ if (!isEnabled()) return
+ if (!SlayerAPI.isInSlayerArea) return
+ SkyHanniMod.feature.dev.debugPos.renderStringsAndItems(display, posLabel = "Slayer Item Profit Tracker")
+ }
+
+ fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
+
+ class ItemLog(val displayName: String) {
+ // display name -> (totalCoins, amount)
+ var items = mapOf<String, Pair<Double, Int>>()
+ var mobKillCoins = 0.0
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt
new file mode 100644
index 000000000..64b5e9fce
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerItemsOnGround.kt
@@ -0,0 +1,54 @@
+package at.hannibal2.skyhanni.features.slayer
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.SlayerAPI
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LocationUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzVec
+import at.hannibal2.skyhanni.utils.RenderUtils.drawString
+import at.hannibal2.skyhanni.utils.RenderUtils.exactLocation
+import com.google.common.cache.CacheBuilder
+import net.minecraft.client.Minecraft
+import net.minecraft.entity.item.EntityItem
+import net.minecraft.init.Items
+import net.minecraftforge.client.event.RenderWorldLastEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.util.concurrent.TimeUnit
+
+class SlayerItemsOnGround {
+ private val config get() = SkyHanniMod.feature.slayer.itemsOnGround
+
+ private var itemsOnGround =
+ CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS)
+ .build<EntityItem, Pair<LorenzVec, String>>()
+
+ @SubscribeEvent
+ fun onRenderWorld(event: RenderWorldLastEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+ if (!config.enabled) return
+ if (!SlayerAPI.isInSlayerArea) return
+
+ for (entityItem in Minecraft.getMinecraft().theWorld.loadedEntityList.filterIsInstance<EntityItem>()) {
+ val location = event.exactLocation(entityItem).add(0.0, 0.8, 0.0)
+ if (location.distance(LocationUtils.playerLocation()) > 15) continue
+
+ val itemStack = entityItem.entityItem
+ val name = itemStack.name ?: continue
+ if (SlayerAPI.ignoreSlayerDrop(name)) continue
+ // happens in spiders den sometimes
+ if (itemStack.item == Items.spawn_egg) continue
+ if (itemStack.getInternalName() == "") continue
+
+ val (itemName, price) = SlayerAPI.getItemNameAndPrice(itemStack)
+ if (config.minimumPrice > price) continue
+
+ itemsOnGround.put(entityItem, location to itemName)
+ }
+
+ for ((location, text) in itemsOnGround.asMap().values) {
+ event.drawString(location, text)
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerType.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerType.kt
index 37a879106..73069c586 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerType.kt
@@ -21,7 +21,9 @@ enum class SlayerType(val displayName: String, val clazz: Class<*>) {
"Coal Mine",
-> REVENANT
- "Spiders Den",
+ "Spider Mound",
+ "Arachne's Burrow",
+ "Arachne's Sanctuary",
-> TARANTULA
"Ruins",
@@ -30,6 +32,7 @@ enum class SlayerType(val displayName: String, val clazz: Class<*>) {
"The End",
"Void Sepulture",
+ "Zealot Bruiser Hideout",
-> VOID
"Stronghold",