diff --git a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ItemsJson.kt b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ItemsJson.kt index c70d0afa565e..da980522ff2f 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ItemsJson.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/ItemsJson.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.data.jsonobjects.repo import at.hannibal2.skyhanni.utils.NEUInternalName +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.toInternalName import com.google.gson.annotations.Expose import com.google.gson.annotations.SerializedName @@ -11,4 +12,18 @@ data class ItemsJson( @Expose @SerializedName("lava_fishing_rods") val lavaFishingRods: List, @Expose @SerializedName("water_fishing_rods") val waterFishingRods: List, @Expose @SerializedName("book_bundle_amount") val bookBundleAmount: Map, + @Expose @SerializedName("value_calculation_data") val valueCalculationData: ItemValueCalculationDataJson, ) + +data class ItemValueCalculationDataJson( + @Expose @SerializedName("always_active_enchants") val alwaysActiveEnchants: Map, + @Expose @SerializedName("only_tier_one_prices") val onlyTierOnePrices: List, + @Expose @SerializedName("only_tier_five_prices") val onlyTierFivePrices: List, +) + +data class AlwaysActiveEnchantJson( + @Expose val level: Int, + @Expose val items: List, +) { + val internalNames = items.map { it.toInternalName() } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/CarnivalShopHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/CarnivalShopHelper.kt index b39ea39f9a00..68bbd1c4f85e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/CarnivalShopHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/CarnivalShopHelper.kt @@ -9,18 +9,15 @@ import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.InventoryOpenEvent import at.hannibal2.skyhanni.events.NeuRepositoryReloadEvent import at.hannibal2.skyhanni.events.render.gui.ReplaceItemEvent -import at.hannibal2.skyhanni.features.inventory.EssenceShopHelper.essenceUpgradePattern -import at.hannibal2.skyhanni.features.inventory.EssenceShopHelper.maxedUpgradeLorePattern import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.EssenceUtils import at.hannibal2.skyhanni.utils.ItemUtils.createItemStack import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.NumberUtil.formatInt -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal import at.hannibal2.skyhanni.utils.RegexUtils.firstMatcher import at.hannibal2.skyhanni.utils.RegexUtils.groupOrNull -import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher import at.hannibal2.skyhanni.utils.RegexUtils.matches import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import net.minecraft.init.Items @@ -33,6 +30,13 @@ object CarnivalShopHelper { private const val CUSTOM_STACK_LOCATION = 8 private inline val NAME_TAG_ITEM get() = Items.name_tag + /** + * All upgrades will appear in slots 11 -> 15 + * + * Filter out items outside of these bounds + */ + private val SLOT_RANGE = 11..15 + private var repoEventShops = mutableListOf() private var currentProgress: EventShopProgress? = null private var currentEventType: String = "" @@ -245,26 +249,7 @@ object CarnivalShopHelper { } private fun processEventShopUpgrades(inventoryItems: Map) { - /** - * All upgrades will appear in slots 11 -> 15 - * - * Filter out items outside of these bounds - */ - val upgradeStacks = inventoryItems.filter { it.key in 11..15 && it.value.item != null } - // TODO remove duplicate code fragment with EssenceShopHelper - val purchasedUpgrades: MutableMap = buildMap { - for (value in upgradeStacks.values) { - // Right now Carnival and Essence Upgrade patterns are 'in-sync' - // This may change in the future, and this would then need its own pattern - essenceUpgradePattern.matchMatcher(value.displayName) { - val upgradeName = groupOrNull("upgrade") ?: return - val nextUpgradeRoman = groupOrNull("tier") ?: return - val nextUpgrade = nextUpgradeRoman.romanToDecimal() - val isMaxed = value.getLore().any { loreLine -> maxedUpgradeLorePattern.matches(loreLine) } - put(upgradeName, if (isMaxed) nextUpgrade else nextUpgrade - 1) - } - } - }.toMutableMap() + val purchasedUpgrades = EssenceUtils.extractPurchasedUpgrades(inventoryItems, SLOT_RANGE) currentProgress = EventShopProgress(currentEventType, purchasedUpgrades) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/EssenceShopHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/EssenceShopHelper.kt index 372f6b661c97..27b35f6d56bd 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/EssenceShopHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/EssenceShopHelper.kt @@ -13,6 +13,7 @@ import at.hannibal2.skyhanni.events.render.gui.ReplaceItemEvent import at.hannibal2.skyhanni.features.inventory.bazaar.BazaarApi import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.EssenceUtils import at.hannibal2.skyhanni.utils.ItemPriceSource import at.hannibal2.skyhanni.utils.ItemPriceUtils.getPrice import at.hannibal2.skyhanni.utils.ItemUtils.createItemStack @@ -22,7 +23,6 @@ import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.toInternalName import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.NumberUtil.formatInt -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal import at.hannibal2.skyhanni.utils.RegexUtils.firstMatcher import at.hannibal2.skyhanni.utils.RegexUtils.groupOrNull import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher @@ -40,6 +40,21 @@ object EssenceShopHelper { private const val CUSTOM_STACK_LOCATION = 8 private inline val GOLD_NUGGET_ITEM get() = Items.gold_nugget + /** + * Essence Upgrade Bounds + * Undead -> 10 to 20 + * Wither -> 10 to 16 + * Dragon -> 19 to 33 + * Spider -> 19 to 25 + * Crimson -> 20 to 33 + * Ice -> 21 to 32 + * Gold -> 19 to 25 + * Diamond -> 19 to 25 + * + * Filter out items that fall outside the bounds of 10 - 33 + */ + private val SLOT_RANGE = 10..33 + private var essenceShops = mutableListOf() private var currentProgress: EssenceShopProgress? = null private var currentEssenceType: String = "" @@ -242,34 +257,7 @@ object EssenceShopHelper { } private fun processEssenceShopUpgrades(essenceName: String, inventoryItems: Map) { - /** - * Essence Upgrade Bounds - * Undead -> 10 to 20 - * Wither -> 10 to 16 - * Dragon -> 19 to 33 - * Spider -> 19 to 25 - * Crimson -> 20 to 33 - * Ice -> 21 to 32 - * Gold -> 19 to 25 - * Diamond -> 19 to 25 - * - * Filter out items that fall outside the bounds of 10 - 33 - */ - val upgradeStacks = inventoryItems.filter { it.key in 10..33 && it.value.item != null } - // TODO remove duplicate code fragment with CarnivalShopHelper - val purchasedUpgrades: MutableMap = buildMap { - for (value in upgradeStacks.values) { - // Right now Carnival and Essence Upgrade patterns are 'in-sync' - // This may change in the future, and this would then need its own pattern - essenceUpgradePattern.matchMatcher(value.displayName) { - val upgradeName = groupOrNull("upgrade") ?: return - val nextUpgradeRoman = groupOrNull("tier") ?: return - val nextUpgrade = nextUpgradeRoman.romanToDecimal() - val isMaxed = value.getLore().any { loreLine -> maxedUpgradeLorePattern.matches(loreLine) } - put(upgradeName, if (isMaxed) nextUpgrade else nextUpgrade - 1) - } - } - }.toMutableMap() + val purchasedUpgrades = EssenceUtils.extractPurchasedUpgrades(inventoryItems, SLOT_RANGE) currentProgress = EssenceShopProgress(essenceName, purchasedUpgrades) } diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt index d2f8ed315ac8..2aaf9fc0968c 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt @@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.api.event.HandleEvent import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.config.features.misc.EstimatedItemValueConfig +import at.hannibal2.skyhanni.data.jsonobjects.repo.ItemValueCalculationDataJson import at.hannibal2.skyhanni.data.jsonobjects.repo.ItemsJson import at.hannibal2.skyhanni.events.ConfigLoadEvent import at.hannibal2.skyhanni.events.GuiRenderEvent @@ -48,6 +49,9 @@ object EstimatedItemValue { var bookBundleAmount = mapOf() private var currentlyShowing = false + var itemValueCalculationData: ItemValueCalculationDataJson? = null + private set + fun isCurrentlyShowing() = currentlyShowing && Minecraft.getMinecraft().currentScreen != null @HandleEvent @@ -60,6 +64,7 @@ object EstimatedItemValue { fun onRepoReload(event: RepositoryReloadEvent) { val data = event.getConstant("Items") bookBundleAmount = data.bookBundleAmount + itemValueCalculationData = data.valueCalculationData } @HandleEvent(onlyOnSkyblock = true) diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt index a4f0caaf9fed..25441ed67e0c 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValueCalculator.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.misc.items import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.api.ReforgeAPI +import at.hannibal2.skyhanni.features.misc.discordrpc.DiscordRPCManager import at.hannibal2.skyhanni.features.nether.kuudra.KuudraAPI import at.hannibal2.skyhanni.features.nether.kuudra.KuudraAPI.getKuudraTier import at.hannibal2.skyhanni.features.nether.kuudra.KuudraAPI.isKuudraArmor @@ -10,8 +11,8 @@ import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.CollectionUtils.addOrPut import at.hannibal2.skyhanni.utils.CollectionUtils.sorted import at.hannibal2.skyhanni.utils.CollectionUtils.sortedDesc -import at.hannibal2.skyhanni.utils.EssenceItemUtils -import at.hannibal2.skyhanni.utils.EssenceItemUtils.getEssencePrices +import at.hannibal2.skyhanni.utils.EssenceUtils +import at.hannibal2.skyhanni.utils.EssenceUtils.getEssencePrices import at.hannibal2.skyhanni.utils.ItemPriceUtils.getNpcPriceOrNull import at.hannibal2.skyhanni.utils.ItemPriceUtils.getPriceOrNull import at.hannibal2.skyhanni.utils.ItemPriceUtils.getRawCraftCostOrNull @@ -491,7 +492,7 @@ object EstimatedItemValueCalculator { private fun calculateStarPrice( internalName: NEUInternalName, inputStars: Int, - ): Pair>? { + ): Pair>? { var totalStars = inputStars val (price, maxStars) = if (internalName.isKuudraArmor()) { val tier = (internalName.getKuudraTier() ?: 0) - 1 @@ -501,17 +502,17 @@ object EstimatedItemValueCalculator { val removed = internalName.removeKuudraTier().asString() var maxStars = 0 - var finalPrice: EssenceItemUtils.EssenceUpgradePrice? = null + var finalPrice: EssenceUtils.EssenceUpgradePrice? = null val tiers = mutableMapOf() - for ((id, _) in EssenceItemUtils.itemPrices) { + for ((id, _) in EssenceUtils.itemPrices) { if (!id.contains(removed)) continue tiers[id] = (id.getKuudraTier() ?: 0) - 1 } for ((id, _) in tiers.sorted()) { - val prices = EssenceItemUtils.itemPrices[id].orEmpty() + val prices = EssenceUtils.itemPrices[id].orEmpty() maxStars += prices.size if (remainingStars <= 0) continue @@ -523,9 +524,8 @@ object EstimatedItemValueCalculator { finalPrice to maxStars } else { - if (totalStars == 0) return null - - val prices = internalName.getEssencePrices() ?: return null + val prices = internalName.getEssencePrices() + if (totalStars == 0 || prices == null) return null (getPriceFor(prices, totalStars) ?: return null) to prices.size } @@ -535,10 +535,10 @@ object EstimatedItemValueCalculator { } private fun getPriceFor( - prices: Map, + prices: Map, totalStars: Int, - ): EssenceItemUtils.EssenceUpgradePrice? { - var totalEssencePrice: EssenceItemUtils.EssencePrice? = null + ): EssenceUtils.EssenceUpgradePrice? { + var totalEssencePrice: EssenceUtils.EssencePrice? = null var totalCoinPrice = 0L val totalItemPrice = mutableMapOf() @@ -555,7 +555,7 @@ object EstimatedItemValueCalculator { } } totalEssencePrice ?: return null - return EssenceItemUtils.EssenceUpgradePrice(totalEssencePrice, totalCoinPrice, totalItemPrice) + return EssenceUtils.EssenceUpgradePrice(totalEssencePrice, totalCoinPrice, totalItemPrice) } private fun addMasterStars(stack: ItemStack, list: MutableList): Double { @@ -587,18 +587,27 @@ object EstimatedItemValueCalculator { return price } - private fun addDrillUpgrades(stack: ItemStack, list: MutableList): Double { - val drillUpgrades = stack.getDrillUpgrades() ?: return 0.0 - + private fun getMapAndTotalFromExtra( + extraList: List + ): Pair> { + var totalPrice = 0.0 val map = mutableMapOf() - for (internalName in drillUpgrades) { + for (internalName in extraList) { val name = internalName.itemName val price = internalName.getPriceOrNull(config.priceSource.get()) ?: continue + totalPrice += price val format = price.shortFormat() map[" $name §7(§6$format§7)"] = price } - val totalPrice = map.values.sum() + return totalPrice to map + } + + + private fun addDrillUpgrades(stack: ItemStack, list: MutableList): Double { + val drillUpgrades = stack.getDrillUpgrades() ?: return 0.0 + + val (totalPrice, map) = getMapAndTotalFromExtra(drillUpgrades) if (map.isNotEmpty()) { list.add("§7Drill upgrades: §6" + totalPrice.shortFormat()) list += map.sortedDesc().keys @@ -666,15 +675,7 @@ object EstimatedItemValueCalculator { private fun addAbilityScrolls(stack: ItemStack, list: MutableList): Double { val abilityScrolls = stack.getAbilityScrolls() ?: return 0.0 - val map = mutableMapOf() - for (internalName in abilityScrolls) { - val name = internalName.itemName - val price = internalName.getPriceOrNull(config.priceSource.get()) ?: continue - - val format = price.shortFormat() - map[" $name §7(§6$format§7)"] = price - } - val totalPrice = map.values.sum() + val (totalPrice, map) = getMapAndTotalFromExtra(abilityScrolls) if (map.isNotEmpty()) { list.add("§7Ability Scrolls: §6" + totalPrice.shortFormat()) list += map.sortedDesc().keys @@ -720,51 +721,24 @@ object EstimatedItemValueCalculator { return price } - // TODO repo - private val hasAlwaysScavenger = listOf( - "CRYPT_DREADLORD_SWORD".toInternalName(), - "ZOMBIE_SOLDIER_CUTLASS".toInternalName(), - "CONJURING_SWORD".toInternalName(), - "EARTH_SHARD".toInternalName(), - "ZOMBIE_KNIGHT_SWORD".toInternalName(), - "SILENT_DEATH".toInternalName(), - "ZOMBIE_COMMANDER_WHIP".toInternalName(), - "ICE_SPRAY_WAND".toInternalName(), - ) - - private val hasAlwaysReplenish = listOf( - "ADVANCED_GARDENING_HOE".toInternalName(), - "ADVANCED_GARDENING_AXE".toInternalName() - ) - private fun addEnchantments(stack: ItemStack, list: MutableList): Double { val enchantments = stack.getEnchantments() ?: return 0.0 val map = mutableMapOf() - // todo use repo - val tieredEnchants = listOf("compact", "cultivating", "champion", "expertise", "hecatomb", "toxophilite") - - @Suppress("PropertyWrapping") - val onlyTierOnePrices = listOf("ultimate_chimera", "ultimate_fatal_tempo", "smoldering", "ultimate_flash", "divine_gift") - val onlyTierFivePrices = listOf("ferocious_mana", "hardened_mana", "mana_vampire", "strong_mana") - val internalName = stack.getInternalName() for ((rawName, rawLevel) in enchantments) { // efficiency 1-5 is cheap, 6-10 is handled by silex if (rawName == "efficiency") continue - if (rawName == "scavenger" && rawLevel == 5 && internalName in hasAlwaysScavenger) { - continue - } - - if (rawName == "replenish" && rawLevel == 1 && internalName in hasAlwaysReplenish) { - continue + val isAlwaysActive = EstimatedItemValue.itemValueCalculationData?.alwaysActiveEnchants.orEmpty().entries.any { + it.key == rawName && it.value.level == rawLevel && it.value.internalNames.contains(internalName) } + if (isAlwaysActive) continue var level = rawLevel var multiplier = 1 - if (rawName in onlyTierOnePrices) { + if (rawName in EstimatedItemValue.itemValueCalculationData?.onlyTierOnePrices.orEmpty()) { when (rawLevel) { 2 -> multiplier = 2 @@ -774,7 +748,7 @@ object EstimatedItemValueCalculator { } level = 1 } - if (rawName in onlyTierFivePrices) { + if (rawName in EstimatedItemValue.itemValueCalculationData?.onlyTierFivePrices.orEmpty()) { when (rawLevel) { 6 -> multiplier = 2 7 -> multiplier = 4 @@ -789,7 +763,7 @@ object EstimatedItemValueCalculator { if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) { multiplier = EstimatedItemValue.bookBundleAmount.getOrDefault(rawName, 5) } - if (rawName in tieredEnchants) level = 1 + if (rawName in DiscordRPCManager.stackingEnchants.keys) level = 1 val enchantmentName = "$rawName;$level".toInternalName() val singlePrice = enchantmentName.getPriceOrNull(config.priceSource.get()) ?: continue diff --git a/src/main/java/at/hannibal2/skyhanni/utils/EssenceItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/EssenceUtils.kt similarity index 78% rename from src/main/java/at/hannibal2/skyhanni/utils/EssenceItemUtils.kt rename to src/main/java/at/hannibal2/skyhanni/utils/EssenceUtils.kt index 42c3ddd0d00c..0d4525fb2307 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/EssenceItemUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/EssenceUtils.kt @@ -3,13 +3,21 @@ package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.api.event.HandleEvent import at.hannibal2.skyhanni.data.jsonobjects.repo.neu.NeuEssenceCostJson import at.hannibal2.skyhanni.events.NeuRepositoryReloadEvent +import at.hannibal2.skyhanni.features.inventory.EssenceShopHelper.essenceUpgradePattern +import at.hannibal2.skyhanni.features.inventory.EssenceShopHelper.maxedUpgradeLorePattern import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.CollectionUtils.addOrPut +import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.toInternalName +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal +import at.hannibal2.skyhanni.utils.RegexUtils.groupOrNull +import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher +import at.hannibal2.skyhanni.utils.RegexUtils.matches +import net.minecraft.item.ItemStack @SkyHanniModule -object EssenceItemUtils { +object EssenceUtils { var itemPrices = mapOf>() @HandleEvent @@ -127,4 +135,25 @@ object EssenceItemUtils { } } + fun extractPurchasedUpgrades( + inventoryItems: Map, + keyRange: IntRange, + ) = extractPurchasedUpgrades( + inventoryItems.filter { it.key in keyRange && it.value.item != null } + ) + + private fun extractPurchasedUpgrades(inventoryItems: Map) = buildMap { + for (value in inventoryItems.values) { + // Right now Carnival and Essence Upgrade patterns are 'in-sync' + // This may change in the future, and this would then need its own pattern + essenceUpgradePattern.matchMatcher(value.displayName) { + val upgradeName = groupOrNull("upgrade") ?: continue + val nextUpgradeRoman = groupOrNull("tier") ?: continue + val nextUpgrade = nextUpgradeRoman.romanToDecimal() + val isMaxed = value.getLore().any { loreLine -> maxedUpgradeLorePattern.matches(loreLine) } + put(upgradeName, if (isMaxed) nextUpgrade else nextUpgrade - 1) + } + } + }.toMutableMap() + }