diff options
author | hannibal2 <24389977+hannibal00212@users.noreply.github.com> | 2023-11-25 02:41:24 +0100 |
---|---|---|
committer | hannibal2 <24389977+hannibal00212@users.noreply.github.com> | 2023-11-25 02:41:24 +0100 |
commit | 861f3bece9ee7e48c26392443f44aa75afba21c0 (patch) | |
tree | d70e37d68cc242526facf3938def7e019a000622 /src/main | |
parent | b32344991743f53c94a48f8a0054d0126b15bbfd (diff) | |
download | skyhanni-861f3bece9ee7e48c26392443f44aa75afba21c0.tar.gz skyhanni-861f3bece9ee7e48c26392443f44aa75afba21c0.tar.bz2 skyhanni-861f3bece9ee7e48c26392443f44aa75afba21c0.zip |
migrating backend and much of rendering from slayer profit tracker and fishing tracker into SkyHanni item tracker
Diffstat (limited to 'src/main')
9 files changed, 306 insertions, 283 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt index 0db542e12..a8ec467d9 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt @@ -9,7 +9,7 @@ import com.google.gson.JsonPrimitive object ConfigUpdaterMigrator { val logger = LorenzLogger("ConfigMigration") - const val CONFIG_VERSION = 9 + const val CONFIG_VERSION = 10 fun JsonElement.at(chain: List<String>, init: Boolean): JsonElement? { if (chain.isEmpty()) return this if (this !is JsonObject) return null diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java index af8d9d3de..5c6e9b580 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/fishing/FishingProfitTrackerConfig.java @@ -4,7 +4,6 @@ import at.hannibal2.skyhanni.config.FeatureToggle; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; -import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown; import io.github.moulberry.moulconfig.annotations.ConfigOption; public class FishingProfitTrackerConfig { @@ -19,16 +18,6 @@ public class FishingProfitTrackerConfig { public Position position = new Position(20, 20, false, true); @Expose - @ConfigOption(name = "Show Price From", desc = "Show price from Bazaar or NPC.") - @ConfigEditorDropdown(values = {"Instant Sell", "Sell Offer", "NPC"}) - public int priceFrom = 1; - - @Expose - @ConfigOption(name = "Recent Drops", desc = "Highlight the amount in green on recently caught items.") - @ConfigEditorBoolean - public boolean showRecentDropss = true; - - @Expose @ConfigOption(name = "Hide Moving", desc = "Hide the Fishing Profit Tracker while moving.") @ConfigEditorBoolean public boolean hideMoving = true; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java index a2f7da58d..975e83d9a 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/TrackerConfig.java @@ -15,7 +15,17 @@ public class TrackerConfig { public boolean hideInEstimatedItemValue = true; @Expose + @ConfigOption(name = "Show Price From", desc = "Show price from Bazaar or NPC.") + @ConfigEditorDropdown(values = {"Instant Sell", "Sell Offer", "NPC"}) + public int priceFrom = 1; + + @Expose @ConfigOption(name = "Default Display Mode", desc = "Change the display mode that gets shown when starting.") @ConfigEditorDropdown public Property<SkyHanniTracker.DefaultDisplayMode> defaultDisplayMode = Property.of(SkyHanniTracker.DefaultDisplayMode.TOTAL); + + @Expose + @ConfigOption(name = "Recent Drops", desc = "Highlight the amount in green on recently gained items.") + @ConfigEditorBoolean + public boolean showRecentDrops = true; } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java index a7bc636db..5fc67993b 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/slayer/ItemProfitTrackerConfig.java @@ -4,7 +4,6 @@ import at.hannibal2.skyhanni.config.FeatureToggle; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; -import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown; import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider; import io.github.moulberry.moulconfig.annotations.ConfigOption; @@ -28,11 +27,6 @@ public class ItemProfitTrackerConfig { public boolean priceInChat = false; @Expose - @ConfigOption(name = "Show Price From", desc = "Show price from Bazaar or NPC.") - @ConfigEditorDropdown(values = {"Instant Sell", "Sell Offer", "NPC"}) - public int priceFrom = 1; - - @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; diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt index 69e6848a7..674269c8d 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/tracker/FishingProfitTracker.kt @@ -5,36 +5,26 @@ import at.hannibal2.skyhanni.events.FishingBobberCastEvent import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.ItemAddEvent import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.features.bazaar.BazaarApi.Companion.getBazaarData import at.hannibal2.skyhanni.features.fishing.FishingAPI -import at.hannibal2.skyhanni.test.PriceSource import at.hannibal2.skyhanni.utils.DelayedRun -import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment -import at.hannibal2.skyhanni.utils.KeyboardManager 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.LorenzUtils.addSelector import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName -import at.hannibal2.skyhanni.utils.NEUItems.getItemStack -import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull -import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull 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.SimpleTimeMark import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher -import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.renderables.Renderable +import at.hannibal2.skyhanni.utils.tracker.ItemTrackerData +import at.hannibal2.skyhanni.utils.tracker.SkyHanniItemTracker import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker -import at.hannibal2.skyhanni.utils.tracker.TrackerData import com.google.gson.annotations.Expose import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.minutes -import kotlin.time.Duration.Companion.seconds typealias CategoryName = String @@ -42,48 +32,53 @@ object FishingProfitTracker { val config get() = SkyHanniMod.feature.fishing.fishingProfitTracker private val coinsChatPattern = ".* CATCH! §r§bYou found §r§6(?<coins>.*) Coins§r§b\\.".toPattern() - private var lastClickDelay = 0L - private val tracker = - SkyHanniTracker("Fishing Profit Tracker", { Data() }, { it.fishing.fishingProfitTracker }) { drawDisplay(it) } + private val tracker = SkyHanniItemTracker( + "Fishing Profit Tracker", + { Data() }, + { it.fishing.fishingProfitTracker }) { drawDisplay(it) } - class Data : TrackerData() { - override fun reset() { - items.clear() + class Data : ItemTrackerData() { + override fun resetItems() { totalCatchAmount = 0 } - @Expose - var items = mutableMapOf<NEUInternalName, FishingItem>() - - @Expose - var totalCatchAmount = 0L - - class FishingItem { - @Expose - var internalName: NEUInternalName? = null - - @Expose - var timesCaught: Long = 0 + override fun getDescription(timesCaught: Long): List<String> { + val percentage = timesCaught.toDouble() / totalCatchAmount + val catchRate = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0)) - @Expose - var totalAmount: Long = 0 + return listOf( + "§7Caught §e${timesCaught.addSeparators()} §7times.", + "§7Your catch rate: §c$catchRate" + ) + } - @Expose - var hidden = false + override fun getCoinFormat(item: TrackedItem, numberColor: String): Pair<String, List<String>> { + val mobKillCoinsFormat = NumberUtil.format(item.totalAmount) + val gained = item.timesGained + val text = "$numberColor${gained}x §6Fished Coins§7: §6$mobKillCoinsFormat" + val lore = listOf( + "§7Killing mobs gives you coins (more with scavenger)", + "§7You got §e$mobKillCoinsFormat §7coins in total this way" + ) + return text to lore + } - override fun toString() = "FishingItem{" + - "internalName='" + internalName + '\'' + - ", timesDropped=" + timesCaught + - ", totalAmount=" + totalAmount + - ", hidden=" + hidden + - '}' + override fun getCustomPricePer(internalName: NEUInternalName): Double { + // TODO find better way to tell if the item is a trophy + val neuInternalNames = itemCategories["Trophy Fish"]!! - var lastTimeUpdated = SimpleTimeMark.farPast() + return if (internalName in neuInternalNames) { + SkyHanniTracker.getPricePer(MAGMA_FISH) * FishingAPI.getFilletPerTrophy(internalName) + } else super.getCustomPricePer(internalName) } + + @Expose + var totalCatchAmount = 0L } - private val SKYBLOCK_COIN by lazy { "SKYBLOCK_COIN".asInternalName() } + private val ItemTrackerData.TrackedItem.timesCaught get() = timesGained + private val MAGMA_FISH by lazy { "MAGMA_FISH".asInternalName() } private val nameAll: CategoryName = "All" @@ -131,57 +126,7 @@ object FishingProfitTracker { for ((internalName, itemProfit) in data.items) { if (!filter(internalName)) continue - val amount = itemProfit.totalAmount - - var pricePer = if (internalName == SKYBLOCK_COIN) 1.0 else getPrice(internalName) - if (pricePer == 0.0) { - pricePer = getPrice(MAGMA_FISH) * FishingAPI.getFilletPerTrophy(internalName) - } - - val price = (pricePer * amount).toLong() - val displayAmount = if (internalName == SKYBLOCK_COIN) { - itemProfit.timesCaught - } else amount - - val cleanName = - if (internalName == SKYBLOCK_COIN) "§6Coins" else internalName.getItemStack().nameWithEnchantment - var name = cleanName ?: error("no name for $internalName") - val priceFormat = NumberUtil.format(price) - val hidden = itemProfit.hidden - - val newDrop = itemProfit.lastTimeUpdated.passedSince() < 10.seconds && config.showRecentDropss - val numberColor = if (newDrop) "§a§l" else "§7" - - if (hidden) { - name = "§8§m" + name.removeColor(keepFormatting = true).replace("§r", "") - } - - val text = " $numberColor${displayAmount.addSeparators()}x $name§7: §6$priceFormat" - - val timesCaught = itemProfit.timesCaught - val percentage = timesCaught.toDouble() / data.totalCatchAmount - val catchRate = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0)) - - val renderable = if (tracker.isInventoryOpen()) Renderable.clickAndHover( - text, - buildLore(timesCaught, catchRate, hidden, newDrop) - ) { - if (System.currentTimeMillis() > lastClickDelay + 150) { - - if (KeyboardManager.isControlKeyDown()) { - data.items.remove(internalName) - LorenzUtils.chat("§e[SkyHanni] Removed $cleanName §efrom Fishing Frofit Tracker.") - lastClickDelay = System.currentTimeMillis() + 500 - } else { - itemProfit.hidden = !hidden - lastClickDelay = System.currentTimeMillis() - } - tracker.update() - } - } else Renderable.string(text) - if (tracker.isInventoryOpen() || !hidden) { - map[renderable] = price - } + val price = data.drawItem(tracker, itemProfit, internalName, map) profit += price } @@ -206,34 +151,7 @@ object FishingProfitTracker { val text = "§eTotal Profit: $profitPrefix$profitFormat" addAsSingletonList(Renderable.hoverTips(text, listOf("§7Profit per catch: $profitPrefix$profitPerCatchFormat"))) - if (tracker.isInventoryOpen()) { - addSelector<PriceSource>( - "", - getName = { type -> type.displayName }, - isCurrent = { it.ordinal == config.priceFrom }, - onChange = { - config.priceFrom = it.ordinal - tracker.update() - } - ) - } - } - - private fun buildLore( - timesCaught: Long, - catchRate: String, - hidden: Boolean, - newDrop: Boolean - ) = buildList { - add("§7Caught §e${timesCaught.addSeparators()} §7times.") - add("§7Your catch rate: §c$catchRate") - add("") - if (newDrop) { - add("§aYou caught this item recently.") - add("") - } - add("§eClick to " + (if (hidden) "show" else "hide") + "!") - add("§eControl + Click to remove this item!") + tracker.addPriceFromButton(this) } @SubscribeEvent @@ -248,19 +166,14 @@ object FishingProfitTracker { fun onChat(event: LorenzChatEvent) { coinsChatPattern.matchMatcher(event.message) { val coins = group("coins").formatNumber() - addItem(SKYBLOCK_COIN, coins.toInt()) + tracker.addCoins(coins.toInt()) + addCatch() } } - private fun addItem(internalName: NEUInternalName, stackSize: Int) { + private fun addCatch() { tracker.modify { it.totalCatchAmount++ - - val fishingItem = it.items.getOrPut(internalName) { Data.FishingItem() } - - fishingItem.timesCaught++ - fishingItem.totalAmount += stackSize - fishingItem.lastTimeUpdated = SimpleTimeMark.now() } } @@ -281,20 +194,14 @@ object FishingProfitTracker { return } - addItem(internalName, amount) + tracker.addItem(internalName, amount) + addCatch() } private val itemCategories get() = FishingTrackerCategoryManager.itemCategories private fun isAllowedItem(internalName: NEUInternalName) = itemCategories.any { internalName in it.value } - private fun getPrice(internalName: NEUInternalName) = when (config.priceFrom) { - 0 -> internalName.getBazaarData()?.sellPrice ?: internalName.getPriceOrNull() ?: 0.0 - 1 -> internalName.getBazaarData()?.buyPrice ?: internalName.getPriceOrNull() ?: 0.0 - - else -> internalName.getNpcPriceOrNull() ?: 0.0 - } - @SubscribeEvent fun onBobberThrow(event: FishingBobberCastEvent) { tracker.firstUpdate() diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt index 2f101524a..d71172eb3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerProfitTracker.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.features.slayer import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.config.Storage import at.hannibal2.skyhanni.data.SlayerAPI import at.hannibal2.skyhanni.events.GuiRenderEvent @@ -10,24 +11,20 @@ import at.hannibal2.skyhanni.events.PurseChangeEvent import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.events.SlayerChangeEvent import at.hannibal2.skyhanni.events.SlayerQuestCompleteEvent -import at.hannibal2.skyhanni.features.bazaar.BazaarApi.Companion.getBazaarData -import at.hannibal2.skyhanni.test.PriceSource -import at.hannibal2.skyhanni.utils.KeyboardManager 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.addSelector import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc import at.hannibal2.skyhanni.utils.NEUInternalName -import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull -import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull import at.hannibal2.skyhanni.utils.NumberUtil import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.jsonobjects.SlayerProfitTrackerItemsJson import at.hannibal2.skyhanni.utils.renderables.Renderable -import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker -import at.hannibal2.skyhanni.utils.tracker.TrackerData +import at.hannibal2.skyhanni.utils.tracker.ItemTrackerData +import at.hannibal2.skyhanni.utils.tracker.SkyHanniItemTracker +import com.google.gson.JsonObject +import com.google.gson.JsonPrimitive import com.google.gson.annotations.Expose import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.time.Duration.Companion.seconds @@ -38,58 +35,44 @@ object SlayerProfitTracker { private var itemLogCategory = "" private var baseSlayerType = "" private val logger = LorenzLogger("slayer/profit_tracker") - private var lastClickDelay = 0L - private val trackers = mutableMapOf<String, SkyHanniTracker<Data>>() + private val trackers = mutableMapOf<String, SkyHanniItemTracker<Data>>() - class Data : TrackerData() { - override fun reset() { - items.clear() - mobKillCoins = 0 + class Data : ItemTrackerData() { + override fun resetItems() { slayerSpawnCost = 0 slayerCompletedCount = 0 } @Expose - var items: MutableMap<NEUInternalName, SlayerItem> = HashMap() - - @Expose - var mobKillCoins: Long = 0 - - @Expose var slayerSpawnCost: Long = 0 @Expose var slayerCompletedCount = 0 - class SlayerItem { - @Expose - var internalName: NEUInternalName? = null - - @Expose - var timesDropped: Long = 0 - - @Expose - var totalAmount: Long = 0 - - @Expose - var hidden = false + override fun getDescription(timesDropped: Long): List<String> { + val percentage = timesDropped.toDouble() / slayerCompletedCount + val perBoss = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0)) - override fun toString() = "SlayerItem{" + - "internalName='" + internalName + '\'' + - ", timesDropped=" + timesDropped + - ", totalAmount=" + totalAmount + - ", hidden=" + hidden + - '}' + return listOf( + "§7Dropped §e${timesDropped.addSeparators()} §7times.", + "§7Your drop rate: §c$perBoss", + ) } - override fun toString() = "SlayerProfitTracker.Data{" + - "items=" + items + - ", mobKillCoins=" + mobKillCoins + - ", slayerSpawnCost=" + slayerSpawnCost + - ", slayerCompletedCount=" + slayerCompletedCount + - '}' + override fun getCoinFormat(item: TrackedItem, numberColor: String): Pair<String, List<String>> { + val mobKillCoinsFormat = NumberUtil.format(item.totalAmount) + val gained = item.timesGained + val text = "$numberColor${gained}x §6Mob Kill Coins§7: §6$mobKillCoinsFormat" + val lore = listOf( + "§7Killing mobs gives you coins (more with scavenger)", + "§7You got §6$mobKillCoinsFormat coins §7in total this way" + ) + return text to lore + } } + private val ItemTrackerData.TrackedItem.timesDropped get() = timesGained + private fun addSlayerCosts(price: Int) { getTracker()?.modify { it.slayerSpawnCost += price @@ -126,21 +109,14 @@ object SlayerProfitTracker { } private fun addMobKillCoins(coins: Int) { - getTracker()?.modify { - it.mobKillCoins += coins - } + getTracker()?.addCoins(coins) } private fun addItemPickup(internalName: NEUInternalName, stackSize: Int) { - getTracker()?.modify { - val slayerItem = it.items.getOrPut(internalName) { Data.SlayerItem() } - - slayerItem.timesDropped++ - slayerItem.totalAmount += stackSize - } + getTracker()?.addItem(internalName, stackSize) } - private fun getTracker(): SkyHanniTracker<Data>? { + private fun getTracker(): SkyHanniItemTracker<Data>? { if (itemLogCategory == "") return null return trackers.getOrPut(itemLogCategory) { @@ -149,7 +125,7 @@ object SlayerProfitTracker { itemLogCategory ) { Data() } } - SkyHanniTracker("$itemLogCategory Profit Tracker", { Data() }, getStorage) { drawDisplay(it) } + SkyHanniItemTracker("$itemLogCategory Profit Tracker", { Data() }, getStorage) { drawDisplay(it) } } } @@ -197,61 +173,7 @@ object SlayerProfitTracker { var profit = 0.0 val map = mutableMapOf<Renderable, Long>() for ((internalName, itemProfit) in itemLog.items) { - val amount = itemProfit.totalAmount - - val price = (getPrice(internalName) * amount).toLong() - - val cleanName = SlayerAPI.getNameWithEnchantmentFor(internalName) - var name = cleanName - val priceFormat = NumberUtil.format(price) - val hidden = itemProfit.hidden - if (hidden) { - name = "§8§m" + name.removeColor(keepFormatting = true).replace("§r", "") - } - val text = " §7${amount.addSeparators()}x $name§7: §6$priceFormat" - - val timesDropped = itemProfit.timesDropped - val percentage = timesDropped.toDouble() / itemLog.slayerCompletedCount - val perBoss = LorenzUtils.formatPercentage(percentage.coerceAtMost(1.0)) - - val renderable = if (tracker.isInventoryOpen()) Renderable.clickAndHover( - text, listOf( - "§7Dropped §e${timesDropped.addSeparators()} §7times.", - "§7Your drop rate: §c$perBoss", - "", - "§eClick to " + (if (hidden) "show" else "hide") + "!", - "§eControl + Click to remove this item!", - ) - ) { - if (System.currentTimeMillis() > lastClickDelay + 150) { - - if (KeyboardManager.isControlKeyDown()) { - itemLog.items.remove(internalName) - LorenzUtils.chat("Removed $cleanName §efrom slayer profit display.") - lastClickDelay = System.currentTimeMillis() + 500 - } else { - itemProfit.hidden = !hidden - lastClickDelay = System.currentTimeMillis() - } - tracker.update() - } - } else Renderable.string(text) - if (tracker.isInventoryOpen() || !hidden) { - map[renderable] = price - } - profit += price - } - val mobKillCoins = itemLog.mobKillCoins - if (mobKillCoins != 0L) { - val mobKillCoinsFormat = NumberUtil.format(mobKillCoins) - map[Renderable.hoverTips( - " §7Mob kill coins: §6$mobKillCoinsFormat", - listOf( - "§7Killing mobs gives you coins (more with scavenger)", - "§7You got §e$mobKillCoinsFormat §7coins in total this way" - ) - )] = mobKillCoins - profit += mobKillCoins + profit += itemLog.drawItem(tracker, itemProfit, internalName, map) } val slayerSpawnCost = itemLog.slayerSpawnCost if (slayerSpawnCost != 0L) { @@ -284,24 +206,18 @@ object SlayerProfitTracker { val text = "§eTotal Profit: $profitPrefix$profitFormat" addAsSingletonList(Renderable.hoverTips(text, listOf("§7Profit per boss: $profitPrefix$profitPerBossFormat"))) - if (tracker.isInventoryOpen()) { - addSelector<PriceSource>( - "", - getName = { type -> type.displayName }, - isCurrent = { it.ordinal == config.priceFrom }, - onChange = { - config.priceFrom = it.ordinal - tracker.update() - } - ) - } + tracker.addPriceFromButton(this) } - private fun getPrice(internalName: NEUInternalName) = when (config.priceFrom) { - 0 -> internalName.getBazaarData()?.sellPrice ?: internalName.getPriceOrNull() ?: 0.0 - 1 -> internalName.getBazaarData()?.buyPrice ?: internalName.getPriceOrNull() ?: 0.0 + val coinFormat: (ItemTrackerData.TrackedItem) -> Pair<String, List<String>> = { item -> + val mobKillCoinsFormat = NumberUtil.format(item.totalAmount) + val text = " §6Mob kill coins§7: §6$mobKillCoinsFormat" + val lore = listOf( + "§7Killing mobs gives you coins (more with scavenger)", + "§7You got §e$mobKillCoinsFormat §7coins in total this way" + ) - else -> internalName.getNpcPriceOrNull() ?: 0.0 + text to lore } @SubscribeEvent @@ -312,13 +228,36 @@ object SlayerProfitTracker { getTracker()?.renderDisplay(config.pos) } + @SubscribeEvent + fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { + event.move(10, "#profile.slayerProfitData", "#profile.slayerProfitData") { old -> + for (data in old.asJsonObject.entrySet().map { it.value.asJsonObject }) { + val items = data.get("items").asJsonObject + for (item in items.entrySet().map { it.value.asJsonObject }) { + val oldValue = item.get("timesDropped") + item.add("timesGained", oldValue) + } + + val coinAmount = data.get("mobKillCoins") + val coins = JsonObject() + coins.add("internalName", JsonPrimitive("SKYBLOCK_COIN")) + coins.add("timesDropped", JsonPrimitive(1)) + coins.add("totalAmount", coinAmount) + items.add("SKYBLOCK_COIN", coins) + } + + old + } + + } + fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled fun clearProfitCommand(args: Array<String>) { if (itemLogCategory == "") { LorenzUtils.userError( "No current slayer data found! " + - "§eGo to a slayer area and start the specific slayer type you want to reset the data of.", + "§eGo to a slayer area and start the specific slayer type you want to reset the data of.", ) return } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/ItemTrackerData.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/ItemTrackerData.kt new file mode 100644 index 000000000..985706a38 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/ItemTrackerData.kt @@ -0,0 +1,134 @@ +package at.hannibal2.skyhanni.utils.tracker + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.utils.ItemUtils.nameWithEnchantment +import at.hannibal2.skyhanni.utils.KeyboardManager +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.NEUItems.getItemStack +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import at.hannibal2.skyhanni.utils.renderables.Renderable +import com.google.gson.annotations.Expose +import kotlin.time.Duration.Companion.seconds + +abstract class ItemTrackerData : TrackerData() { + + private val config get() = SkyHanniMod.feature.misc.tracker + + private var lastClickDelay = 0L + + companion object { + val SKYBLOCK_COIN by lazy { "SKYBLOCK_COIN".asInternalName() } + } + + abstract fun resetItems() + + abstract fun getDescription(timesGained: Long): List<String> + + abstract fun getCoinFormat(item: TrackedItem, numberColor: String): Pair<String, List<String>> + + open fun getCustomPricePer(internalName: NEUInternalName) = SkyHanniTracker.getPricePer(internalName) + + override fun reset() { + items.clear() + resetItems() + } + + fun additem(internalName: NEUInternalName, stackSize: Int) { + val item = items.getOrPut(internalName) { TrackedItem() } + + item.timesGained++ + item.totalAmount += stackSize + item.lastTimeUpdated = SimpleTimeMark.now() + } + + fun drawItem( + tracker: SkyHanniItemTracker<out ItemTrackerData>, + item: TrackedItem, + internalName: NEUInternalName, + map: MutableMap<Renderable, Long> + ): Long { + val amount = item.totalAmount + + val pricePer = if (internalName == SKYBLOCK_COIN) 1.0 else getCustomPricePer(internalName) + + val price = (pricePer * amount).toLong() + val displayAmount = if (internalName == SKYBLOCK_COIN) item.timesGained else amount + + var name = if (internalName == SKYBLOCK_COIN) { + "§6Coins" + } else { + internalName.getItemStack().nameWithEnchantment ?: error("no name for $internalName") + } + val priceFormat = NumberUtil.format(price) + val hidden = item.hidden + + val newDrop = item.lastTimeUpdated.passedSince() < 10.seconds && config.showRecentDrops + val numberColor = if (newDrop) "§a§l" else "§7" + + if (hidden) { + name = "§8§m" + name.removeColor(keepFormatting = true).replace("§r", "") + } + + val text = " $numberColor${displayAmount.addSeparators()}x $name§7: §6$priceFormat" + val (displayName, lore) = if (internalName == SKYBLOCK_COIN) { + getCoinFormat(item, numberColor) + } else text to buildLore(item, hidden, newDrop) + + val renderable = if (tracker.isInventoryOpen()) Renderable.clickAndHover(displayName, lore) { + if (System.currentTimeMillis() > lastClickDelay + 150) { + if (KeyboardManager.isControlKeyDown()) { + items.remove(internalName) + LorenzUtils.chat("§e[SkyHanni] Removed ${if (internalName == SKYBLOCK_COIN) "§6Coins" else internalName.getItemStack().nameWithEnchantment} §efrom Fishing Frofit Tracker.") + lastClickDelay = System.currentTimeMillis() + 500 + } else { + item.hidden = !hidden + lastClickDelay = System.currentTimeMillis() + } + tracker.update() + } + } else Renderable.string(displayName) + if (tracker.isInventoryOpen() || !hidden) { + map[renderable] = price + } + return price + } + + private fun buildLore( + item: TrackedItem, + hidden: Boolean, + newDrop: Boolean + ) = buildList { + addAll(getDescription(item.timesGained)) + add("") + if (newDrop) { + add("§aYou caught this item recently.") + add("") + } + add("§eClick to " + (if (hidden) "show" else "hide") + "!") + add("§eControl + Click to remove this item!") + } + + @Expose + var items: MutableMap<NEUInternalName, TrackedItem> = HashMap() + + class TrackedItem { + @Expose + var internalName: NEUInternalName? = null + + @Expose + var timesGained: Long = 0 + + @Expose + var totalAmount: Long = 0 + + @Expose + var hidden = false + + var lastTimeUpdated = SimpleTimeMark.farPast() + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt new file mode 100644 index 000000000..8059123fb --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt @@ -0,0 +1,39 @@ +package at.hannibal2.skyhanni.utils.tracker + +import at.hannibal2.skyhanni.config.Storage +import at.hannibal2.skyhanni.test.PriceSource +import at.hannibal2.skyhanni.utils.LorenzUtils.addSelector +import at.hannibal2.skyhanni.utils.NEUInternalName + +class SkyHanniItemTracker<Data : ItemTrackerData>( + name: String, + createNewSession: () -> Data, + getStorage: (Storage.ProfileSpecific) -> Data, + drawDisplay: (Data) -> List<List<Any>>, +) : SkyHanniTracker<Data>(name, createNewSession, getStorage, drawDisplay) { + + fun addCoins(coins: Int) { + addItem(ItemTrackerData.SKYBLOCK_COIN, coins) + } + + fun addItem(internalName: NEUInternalName, stackSize: Int) { + modify { + it.additem(internalName, stackSize) + } + } + + fun addPriceFromButton(lists: MutableList<List<Any>>) { + if (isInventoryOpen()) { + lists.addSelector<PriceSource>( + "", + getName = { type -> type.displayName }, + isCurrent = { it.ordinal == config.priceFrom }, + onChange = { + config.priceFrom = it.ordinal + update() + } + ) + } + + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt index 29b61faee..3d68b8316 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt @@ -4,9 +4,13 @@ import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.Storage import at.hannibal2.skyhanni.config.core.config.Position import at.hannibal2.skyhanni.data.ProfileStorageData +import at.hannibal2.skyhanni.features.bazaar.BazaarApi.Companion.getBazaarData import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList +import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUItems.getNpcPriceOrNull +import at.hannibal2.skyhanni.utils.NEUItems.getPriceOrNull import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.renderables.Renderable @@ -14,7 +18,7 @@ import net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiInventory import kotlin.time.Duration.Companion.seconds -class SkyHanniTracker<Data : TrackerData>( +open class SkyHanniTracker<Data : TrackerData>( private val name: String, private val createNewSession: () -> Data, private val getStorage: (Storage.ProfileSpecific) -> Data, @@ -28,8 +32,15 @@ class SkyHanniTracker<Data : TrackerData>( private var dirty = false companion object { - private val config get() = SkyHanniMod.feature.misc.tracker + val config get() = SkyHanniMod.feature.misc.tracker private val storedTrackers get() = SkyHanniMod.feature.storage.trackerDisplayModes + + fun getPricePer(name: NEUInternalName) = when (config.priceFrom) { + 0 -> name.getBazaarData()?.sellPrice ?: name.getPriceOrNull() ?: 0.0 + 1 -> name.getBazaarData()?.buyPrice ?: name.getPriceOrNull() ?: 0.0 + + else -> name.getNpcPriceOrNull() ?: 0.0 + } } fun isInventoryOpen() = inventoryOpen |