diff options
author | hannibal2 <24389977+hannibal00212@users.noreply.github.com> | 2023-06-09 22:36:52 +0200 |
---|---|---|
committer | hannibal2 <24389977+hannibal00212@users.noreply.github.com> | 2023-06-09 22:36:52 +0200 |
commit | 50905075a70f4419f6772a99ae854d49d105351e (patch) | |
tree | 39ae9d8011168a65039caad66caa343e69893beb | |
parent | 1647e8c472ba950e122b89c7c4b2889dd254d1ea (diff) | |
download | skyhanni-50905075a70f4419f6772a99ae854d49d105351e.tar.gz skyhanni-50905075a70f4419f6772a99ae854d49d105351e.tar.bz2 skyhanni-50905075a70f4419f6772a99ae854d49d105351e.zip |
Added Item Profit Tracker, Items on Ground and Broken Hyperion Warning
13 files changed, 570 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 21e2ac4d7..bea37562f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,14 @@ + Supports party members, friends (need to visit all friend list pages), player on the same server + Supports these commands: /p, /party, /pt (party transfer), /f, /friend /msg, /w, /tell, /boop, /visit, /invite, /ah, /pv (NEU's Profile Viewer), /shmarkplayer (SkyHanni's Mark Player feature) + Supports VIP /visit suggestions (currently PortalHub and prtlhub, if you know similar islands, tell us please) ++ Added Item Profit Tracker (Slayer only) + + Count items collected and how much you pay while doing slayer, calculates final profit + + Shows the price of the item collected in chat (default disabled) ++ Added Items on Ground (Slayer only) + + Show item name and price over items laying on ground (only in slayer areas) ++ Added Broken Hyperion Warning (Slayer only) + + Warns when right-clicking with a Wither Impact weapon (e.g. Hyperion) no longer gains combat exp + (Kill a mob with melee-hits to fix this hypixel bug) ### Changes + Added Options for displays Crop Milestone and Best Crop Time. diff --git a/FEATURES.md b/FEATURES.md index 7fa6c1fe9..99ccf3bb7 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -142,6 +142,14 @@ + Hide particles and fireballs near blaze slayer bosses and demons. + Option to remove the wrong dagger messages from chat. + Warning when wrong slayer quest is selected, or killing mobs for the wrong slayer. ++ **Item Profit Tracker** + + Count items collected and how much you pay while doing slayer, calculates final profit + + Shows the price of the item collected in chat (default disabled) ++ **Items on Ground** + + Show item name and price over items laying on ground (only in slayer areas) ++ **Broken Hyperion Warning** + + Warns when right-clicking with a Wither Impact weapon (e.g. Hyperion) no longer gains combat exp + (Kill a mob with melee-hits to fix this hypixel bug) ### Diana + Show burrows near you. diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index b0a96be99..b4a9ebe75 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -58,10 +58,7 @@ import at.hannibal2.skyhanni.features.mobs.AshfangMinisNametagHider import at.hannibal2.skyhanni.features.mobs.MobHighlight import at.hannibal2.skyhanni.features.nether.ashfang.* import at.hannibal2.skyhanni.features.nether.reputationhelper.CrimsonIsleReputationHelper -import at.hannibal2.skyhanni.features.slayer.EndermanSlayerBeacon -import at.hannibal2.skyhanni.features.slayer.HideMobNames -import at.hannibal2.skyhanni.features.slayer.HighlightSlayerMiniBoss -import at.hannibal2.skyhanni.features.slayer.SlayerQuestWarning +import at.hannibal2.skyhanni.features.slayer.* import at.hannibal2.skyhanni.features.slayer.blaze.BlazeSlayerClearView import at.hannibal2.skyhanni.features.slayer.blaze.BlazeSlayerDaggerHelper import at.hannibal2.skyhanni.features.slayer.blaze.BlazeSlayerFirePitsWarning @@ -146,6 +143,8 @@ class SkyHanniMod { loadModule(FarmingContestAPI) loadModule(FriendAPI()) loadModule(PartyAPI()) + loadModule(SlayerAPI) + loadModule(PurseAPI()) // features loadModule(BazaarOrderHelper()) @@ -293,6 +292,9 @@ class SkyHanniMod { loadModule(ShowFishingItemName()) loadModule(WarpTabComplete) loadModule(PlayerTabComplete) + loadModule(SlayerItemProfitTracker()) + loadModule(SlayerItemsOnGround()) + loadModule(DetectBrokenHyperion()) init() diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java b/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java index eb9bd078a..e243fcc81 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java @@ -82,6 +82,57 @@ public class Slayer { public boolean blazeClearView = false; @Expose + @ConfigOption(name = "Item Profit Tracker", desc = "") + @Accordion + public ItemProfitTracker itemProfitTracker = new ItemProfitTracker(); + + public static class ItemProfitTracker { + + @Expose + @ConfigOption(name = "Enabled", desc = "Count all items you pick up while doing slayer, " + + "keep track of how much you pay for starting slayers and calculating the overall profit.") + @ConfigEditorBoolean + public boolean enabled = true; + + @Expose + @ConfigOption(name = "Price in Chat", desc = "Show an extra chat message when you pick up an item. " + + "(This contains name, amount and price)") + @ConfigEditorBoolean + public boolean priceInChat = false; + + @Expose + @ConfigOption(name = "Minimum Price", desc = "Items below this price will not show up in chat.") + @ConfigEditorSlider(minValue = 1, maxValue = 5_000_000, minStep = 1) + public int minimumPrice = 100_000; + } + + @Expose + @ConfigOption(name = "Items on Ground", desc = "") + @Accordion + public ItemsOnGround itemsOnGround = new ItemsOnGround(); + + public static class ItemsOnGround { + + @Expose + @ConfigOption(name = "Enabled", desc = "Show the name and price of items laying on the ground. §cOnly in slayer areas!") + @ConfigEditorBoolean + public boolean enabled = true; + + @Expose + @ConfigOption(name = "Minimum Price", desc = "Items below this price will be ignored.") + @ConfigEditorSlider(minValue = 1, maxValue = 1_000_000, minStep = 1) + public int minimumPrice = 50_000; + } + + @Expose + @ConfigOption(name = "Broken Wither Impact", + desc = "Warns when right-clicking with a Wither Impact weapon (e.g. Hyperion) no longer gains combat exp. " + + "Kill a mob with melee-hits to fix this hypixel bug. §cOnly works while doing slayers!" + ) + @ConfigEditorBoolean + public boolean brokenHyperion = true; + + @Expose @ConfigOption(name = "Miniboss Highlight", desc = "Highlight slayer miniboss in blue color.") @ConfigEditorBoolean public boolean slayerMinibossHighlight = false; diff --git a/src/main/java/at/hannibal2/skyhanni/data/PurseAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/PurseAPI.kt new file mode 100644 index 000000000..750e23794 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/PurseAPI.kt @@ -0,0 +1,61 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.PurseChangeCause +import at.hannibal2.skyhanni.events.PurseChangeEvent +import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent + +class PurseAPI { + private val pattern = "(Piggy|Purse): §6(?<coins>[\\d,]*).*".toPattern() + private var currentPurse = 0.0 + private var inventoryCloseTime = 0L + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + inventoryCloseTime = System.currentTimeMillis() + } + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (event.phase != TickEvent.Phase.START) return + + for (line in ScoreboardData.sidebarLinesFormatted) { + val newPurse = pattern.matchMatcher(line) { + group("coins").formatNumber().toDouble() + } ?: continue + val diff = newPurse - currentPurse + if (diff == 0.0) continue + currentPurse = newPurse + + PurseChangeEvent(diff, getCause(diff)).postAndCatch() + } + } + + // TODO add more causes in the future (e.g. ah/bz/bank) + private fun getCause(diff: Double): PurseChangeCause { + if (diff > 0) { + if (diff == 1.0) { + return PurseChangeCause.GAIN_TALISMAN_OF_COINS + } + if (Minecraft.getMinecraft().currentScreen == null) { + val timeDiff = System.currentTimeMillis() - inventoryCloseTime + if (timeDiff > 2_000) { + return PurseChangeCause.GAIN_MOB_KILL + } + + } + return PurseChangeCause.GAIN_UNKNOWN + } else { + val timeDiff = System.currentTimeMillis() - SlayerAPI.questStartTime + if (timeDiff < 1500) { + return PurseChangeCause.LOSE_SLAYER_QUEST_STARTED + } + + return PurseChangeCause.LOSE_UNKNOWN + } + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt new file mode 100644 index 000000000..6b4adc54c --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/SlayerAPI.kt @@ -0,0 +1,110 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.SlayerChangeEvent +import at.hannibal2.skyhanni.features.bazaar.BazaarApi +import at.hannibal2.skyhanni.features.slayer.SlayerType +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.nextAfter +import at.hannibal2.skyhanni.utils.NEUItems +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import com.google.common.cache.CacheBuilder +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import java.util.concurrent.TimeUnit + +object SlayerAPI { + + var tick = 0 + + private var nameCache = + CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build<Pair<String, Int>, Pair<String, Double>>() + + var questStartTime = 0L + var isInSlayerArea = false + private var latestSlayerCategory = "" + private var latestProgressChangeTime = 0L + private var latestSlayerProgress = "" + + fun hasActiveSlayerQuest() = latestSlayerCategory != "" + + fun getLatestProgressChangeTime() = if (latestSlayerProgress == "§eSlay the boss!") { + System.currentTimeMillis() + } else latestProgressChangeTime + + + // TODO use repo + fun ignoreSlayerDrop(name: String) = when (name.removeColor()) { + // maybe everywhere? + "Stone" -> true + "Head" -> true + + // Spider + "Cobweb" -> true + "String" -> true + "Spider Eye" -> true + "Bone" -> true + + // Blaze + "Water Bottle" -> true + + else -> false + } + + fun getItemNameAndPrice(stack: ItemStack): Pair<String, Double> { + val internalName = stack.getInternalName() + val amount = stack.stackSize + val key = internalName to amount + nameCache.getIfPresent(key)?.let { + return it + } + + val amountFormat = if (amount != 1) "§7${amount}x §r" else "" + val displayName = NEUItems.getItemStack(internalName).nameWithEnchantment + + val price = NEUItems.getPrice(internalName) + val npcPrice = BazaarApi.getBazaarDataByInternalName(internalName)?.npcPrice ?: 0.0 + val maxPrice = npcPrice.coerceAtLeast(price) + val totalPrice = maxPrice * amount + + val format = NumberUtil.format(totalPrice) + val priceFormat = " §7(§6$format coins§7)" + + val result = "$amountFormat$displayName$priceFormat" to totalPrice + nameCache.put(key, result) + return result + } + + @SubscribeEvent + fun onChat(event: LorenzChatEvent) { + if (event.message.contains("§r§5§lSLAYER QUEST STARTED!")) { + questStartTime = System.currentTimeMillis() + } + } + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (event.phase != TickEvent.Phase.START) return + if (!LorenzUtils.inSkyBlock) return + + val slayerQuest = ScoreboardData.sidebarLinesFormatted.nextAfter("Slayer Quest") ?: "" + if (slayerQuest != latestSlayerCategory) { + SlayerChangeEvent(latestSlayerCategory, slayerQuest).postAndCatch() + latestSlayerCategory = slayerQuest + } + + val slayerProgress = ScoreboardData.sidebarLinesFormatted.nextAfter("Slayer Quest", 2) ?: "" + if (latestSlayerProgress != slayerProgress) { + latestSlayerProgress = slayerProgress + latestProgressChangeTime = System.currentTimeMillis() + } + + if (tick++ % 5 == 0) { + isInSlayerArea = SlayerType.getByArea(LorenzUtils.skyBlockArea) != null + } + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/events/PurseChangeEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/PurseChangeEvent.kt new file mode 100644 index 000000000..50343a7d9 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/PurseChangeEvent.kt @@ -0,0 +1,12 @@ +package at.hannibal2.skyhanni.events + +class PurseChangeEvent(val coins: Double, val reason: PurseChangeCause) : LorenzEvent() + +enum class PurseChangeCause { + GAIN_MOB_KILL, + GAIN_TALISMAN_OF_COINS, + GAIN_UNKNOWN, + + LOSE_SLAYER_QUEST_STARTED, + LOSE_UNKNOWN, +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/events/SlayerChangeEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/SlayerChangeEvent.kt new file mode 100644 index 000000000..9bbf1672a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/SlayerChangeEvent.kt @@ -0,0 +1,3 @@ +package at.hannibal2.skyhanni.events + +class SlayerChangeEvent(val oldSlayer: String, val newSlayer: String): LorenzEvent()
\ No newline at end of file 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", diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt index 556eb59a0..656030c97 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt @@ -346,4 +346,21 @@ object LorenzUtils { child.set(rootObj, value) } } + + fun List<String>.nextAfter(after: String, skip: Int = 1): String? { + var missing = -1 + for (line in this) { + if (line == after) { + missing = skip - 1 + continue + } + if (missing == 0) { + return line + } + if (missing != -1) { + missing-- + } + } + return null + } }
\ No newline at end of file |