From 1ab8930cee2d6740b9b9dbf0a496c5e6e0f195fe Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Date: Wed, 24 May 2023 21:26:08 +0200 Subject: Added Estimated Armor Value display --- src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt | 5 +- .../hannibal2/skyhanni/config/features/Misc.java | 6 + .../skyhanni/features/misc/EstimatedItemValue.kt | 544 -------------------- .../features/misc/items/EstimatedItemValue.kt | 549 +++++++++++++++++++++ .../features/misc/items/EstimatedWardrobePrice.kt | 62 +++ 5 files changed, 621 insertions(+), 545 deletions(-) delete mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt (limited to 'src') diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 555761bbe..ef7d6b6ab 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -43,6 +43,8 @@ import at.hannibal2.skyhanni.features.minion.MinionCollectLogic import at.hannibal2.skyhanni.features.minion.MinionFeatures import at.hannibal2.skyhanni.features.misc.* import at.hannibal2.skyhanni.features.misc.discordrpc.DiscordRPCManager +import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue +import at.hannibal2.skyhanni.features.misc.items.EstimatedWardrobePrice import at.hannibal2.skyhanni.features.misc.teleportpad.TeleportPadCompactName import at.hannibal2.skyhanni.features.misc.teleportpad.TeleportPadInventoryNumber import at.hannibal2.skyhanni.features.misc.tiarelay.TiaRelayHelper @@ -252,7 +254,8 @@ class SkyHanniMod { loadModule(GardenComposterInventoryFeatures()) loadModule(MinionCollectLogic()) loadModule(PasteIntoSigns()) - loadModule(EstimatedItemValue()) + loadModule(EstimatedItemValue) + loadModule(EstimatedWardrobePrice()) loadModule(ComposterInventoryNumbers()) loadModule(FarmingFortuneDisplay()) loadModule(ToolTooltipTweaks()) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java index f5ad1513c..6dd895023 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java @@ -231,6 +231,12 @@ public class Misc { @ConfigAccordionId(id = 11) public boolean estimatedIemValueAlwaysEnabled = true; + @Expose + @ConfigOption(name = "Show Armor Value", desc = "Show the value of the full armor in the wardrobe inventory.") + @ConfigEditorBoolean + @ConfigAccordionId(id = 11) + public boolean estimatedIemValueArmor = true; + @Expose public Position itemPriceDataPos = new Position(140, 90, false, true); diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt deleted file mode 100644 index 981795da7..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt +++ /dev/null @@ -1,544 +0,0 @@ -package at.hannibal2.skyhanni.features.misc - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.GuiRenderEvent -import at.hannibal2.skyhanni.events.InventoryCloseEvent -import at.hannibal2.skyhanni.events.RenderItemTooltipEvent -import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList -import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc -import at.hannibal2.skyhanni.utils.NEUItems -import at.hannibal2.skyhanni.utils.NumberUtil -import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getAbilityScrolls -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getArmorDye -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getDrillUpgrades -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFarmingForDummiesCount -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getGemstones -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHelmetSkin -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHotPotatoCount -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getManaDisintegrators -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getMasterStars -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPowerScroll -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getReforgeName -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getRune -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getSilexCount -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getTransmissionTunerCount -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfPiece -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfWar -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasBookOfStats -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasEtherwarp -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasJalapenoBook -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasWoodSingularity -import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated -import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import io.github.moulberry.moulconfig.internal.KeybindHelper -import io.github.moulberry.notenoughupdates.util.Constants -import net.minecraft.init.Items -import net.minecraft.item.ItemStack -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class EstimatedItemValue { - private val config get() = SkyHanniMod.feature.misc - private var display = listOf>() - private val cache = mutableMapOf>>() - private var lastToolTipTime = 0L - - @SubscribeEvent - fun onRenderOverlay(event: GuiRenderEvent.ChestBackgroundRenderEvent) { - if (!LorenzUtils.inSkyBlock) return - if (!config.estimatedIemValueEnabled) return - if (!KeybindHelper.isKeyDown(config.estimatedItemValueHotkey) && !config.estimatedIemValueAlwaysEnabled) return - if (System.currentTimeMillis() > lastToolTipTime + 200) return - - config.itemPriceDataPos.renderStringsAndItems(display, posLabel = "Estimated Item Value") - } - - @SubscribeEvent - fun onInventoryClose(event: InventoryCloseEvent) { - cache.clear() - } - - @SubscribeEvent - fun onRenderItemTooltip(event: RenderItemTooltipEvent) { - if (!LorenzUtils.inSkyBlock) return - if (!config.estimatedIemValueEnabled) return - - val item = event.stack - val oldData = cache[item] - if (oldData != null) { - display = oldData - lastToolTipTime = System.currentTimeMillis() - return - } - - val newDisplay = try { - draw(item) - } catch (e: Exception) { - LorenzUtils.debug("Estimated Item Value error: ${e.message}") - e.printStackTrace() - listOf() - } - - cache[item] = newDisplay - display = newDisplay - lastToolTipTime = System.currentTimeMillis() - } - - private fun draw(stack: ItemStack): List> { - val list = mutableListOf() - list.add("§aEstimated Item Value:") - - val internalName = stack.getInternalName() - if (internalName == "") return listOf() - - // FIX neu item list - if (internalName.startsWith("ULTIMATE_ULTIMATE_")) return listOf() - // We don't need this feature to work on books at all - if (stack.item == Items.enchanted_book) return listOf() - // Block catacombs items in mort inventory - if (internalName.startsWith("CATACOMBS_PASS_") || internalName.startsWith("MASTER_CATACOMBS_PASS_")) return listOf() - // Blocks the dungeon map - if (internalName.startsWith("MAP-")) return listOf() - // Hides the rune item - if (internalName.contains("_RUNE;")) return listOf() - - - if (NEUItems.getItemStackOrNull(internalName) == null) { - LorenzUtils.debug("Estimated Item Value is null for internal name: '$internalName'") - return listOf() - } - - var totalPrice = 0.0 - val basePrice = addBaseItem(stack, list) - totalPrice += basePrice - totalPrice += addReforgeStone(stack, list) - - // once - totalPrice += addRecomb(stack, list) - totalPrice += addArtOfWar(stack, list) - totalPrice += addArtOfPiece(stack, list) - totalPrice += addEtherwarp(stack, list) - totalPrice += addPowerScrolls(stack, list) - totalPrice += addWoodSingularity(stack, list) - totalPrice += addJalapenoBook(stack, list) - totalPrice += addStatsBook(stack, list) - - // counted - totalPrice += addMasterStars(stack, list) - totalPrice += addHotPotatoBooks(stack, list) - totalPrice += addFarmingForDummies(stack, list) - totalPrice += addSilex(stack, list) - totalPrice += addTransmissionTuners(stack, list) - totalPrice += addManaDisintegrators(stack, list) - - // cosmetic - totalPrice += addHelmetSkin(stack, list) - totalPrice += addArmorDye(stack, list) - totalPrice += addRune(stack, list) - - // dynamic - totalPrice += addAbilityScrolls(stack, list) - totalPrice += addDrillUpgrades(stack, list) - totalPrice += addGemstones(stack, list) - totalPrice += addEnchantments(stack, list) - - if (basePrice == totalPrice) return listOf() - - list.add("§aTotal: §6§l" + NumberUtil.format(totalPrice)) - - val newDisplay = mutableListOf>() - for (line in list) { - newDisplay.addAsSingletonList(line) - } - return newDisplay - } - - private fun addReforgeStone(stack: ItemStack, list: MutableList): Double { - val rawReforgeName = stack.getReforgeName() ?: return 0.0 - - for ((internalName, values) in Constants.REFORGESTONES.entrySet()) { - val stone = values.asJsonObject - val reforgeName = stone.get("reforgeName").asString - if (rawReforgeName == reforgeName.lowercase() || rawReforgeName == internalName.lowercase()) { - val price = NEUItems.getPrice(internalName) - val name = NEUItems.getItemStack(internalName).name - list.add("§7Reforge: §9$reforgeName") - list.add(" §7($name §6" + NumberUtil.format(price) + "§7)") - return price - } - } - - return 0.0 - } - - private fun addRecomb(stack: ItemStack, list: MutableList): Double { - if (!stack.isRecombobulated()) return 0.0 - - val wtfHardcodedRecomb = "RECOMBOBULATOR_3000" - val price = NEUItems.getPrice(wtfHardcodedRecomb) - list.add("§7Recombobulated: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addJalapenoBook(stack: ItemStack, list: MutableList): Double { - if (!stack.hasJalapenoBook()) return 0.0 - - val wtfHardcodedJalapeno = "JALAPENO_BOOK" - - val price = NEUItems.getPrice(wtfHardcodedJalapeno) - list.add("§7Jalapeno Book: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addEtherwarp(stack: ItemStack, list: MutableList): Double { - if (!stack.hasEtherwarp()) return 0.0 - - val wtfHardcodedConduit = "ETHERWARP_CONDUIT" - val wtfHardcodedMerger = "ETHERWARP_MERGER" - val price = NEUItems.getPrice(wtfHardcodedConduit) + NEUItems.getPrice(wtfHardcodedMerger) - list.add("§7Etherwarp: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addWoodSingularity(stack: ItemStack, list: MutableList): Double { - if (!stack.hasWoodSingularity()) return 0.0 - - val wtfHardcodedSingularity = "WOOD_SINGULARITY" - val price = NEUItems.getPrice(wtfHardcodedSingularity) - list.add("§7Wood Singularity: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addArtOfWar(stack: ItemStack, list: MutableList): Double { - if (!stack.hasArtOfWar()) return 0.0 - - val ripTechno = "THE_ART_OF_WAR" - val price = NEUItems.getPrice(ripTechno) - list.add("§7The Art of War: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addStatsBook(stack: ItemStack, list: MutableList): Double { - if (!stack.hasBookOfStats()) return 0.0 - - val ripTechno = "BOOK_OF_STATS" - val price = NEUItems.getPrice(ripTechno) - list.add("§7Book of Stats: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - // TODO untested - private fun addArtOfPiece(stack: ItemStack, list: MutableList): Double { - if (!stack.hasArtOfPiece()) return 0.0 - - val ripTechno = "THE_ART_OF_PEACE" - val price = NEUItems.getPrice(ripTechno) - list.add("§7The Art Of Piece: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addHotPotatoBooks(stack: ItemStack, list: MutableList): Double { - val count = stack.getHotPotatoCount() ?: return 0.0 - - val hpb: Int - val fuming: Int - if (count <= 10) { - hpb = count - fuming = 0 - } else { - hpb = 10 - fuming = count - 10 - } - - var totalPrice = 0.0 - - val wtfHardcodedHpb = "HOT_POTATO_BOOK" - val hpbPrice = NEUItems.getPrice(wtfHardcodedHpb) * hpb - list.add("§7HPB's: §e$hpb§7/§e10 §7(§6" + NumberUtil.format(hpbPrice) + "§7)") - totalPrice += hpbPrice - - if (fuming > 0) { - val wtfHardcodedFuming = "FUMING_POTATO_BOOK" - val fumingPrice = NEUItems.getPrice(wtfHardcodedFuming) * fuming - list.add("§7Fuming: §e$fuming§7/§e5 §7(§6" + NumberUtil.format(fumingPrice) + "§7)") - totalPrice += fumingPrice - } - - return totalPrice - } - - private fun addFarmingForDummies(stack: ItemStack, list: MutableList): Double { - val count = stack.getFarmingForDummiesCount() ?: return 0.0 - - val wtfHardcodedDumbFarmers = "FARMING_FOR_DUMMIES" - val price = NEUItems.getPrice(wtfHardcodedDumbFarmers) * count - list.add("§7Farming for Dummies: §e$count§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addSilex(stack: ItemStack, list: MutableList): Double { - val tier = stack.getSilexCount() ?: return 0.0 - - val internalName = stack.getInternalName() - val maxTier = if (internalName == "STONK_PICKAXE") 4 else 5 - - val wtfHardcodedSilex = "SIL_EX" - val price = NEUItems.getPrice(wtfHardcodedSilex) * tier - list.add("§7Silex: §e$tier§7/§e$maxTier §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addTransmissionTuners(stack: ItemStack, list: MutableList): Double { - val count = stack.getTransmissionTunerCount() ?: return 0.0 - - val wtfHardcodedTuner = "TRANSMISSION_TUNER" - val price = NEUItems.getPrice(wtfHardcodedTuner) * count - list.add("§7Transmission Tuners: §e$count§7/§e4 §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addManaDisintegrators(stack: ItemStack, list: MutableList): Double { - val count = stack.getManaDisintegrators() ?: return 0.0 - - val wtfHardcodedTuner = "MANA_DISINTEGRATOR" - val price = NEUItems.getPrice(wtfHardcodedTuner) * count - list.add("§7Mana Disintegrators: §e$count§7/§e10 §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addMasterStars(stack: ItemStack, list: MutableList): Double { - val masterStars = stack.getMasterStars() - if (masterStars == 0) return 0.0 - - var price = 0.0 - - val stars = mapOf( - "FIRST" to 1, - "SECOND" to 2, - "THIRD" to 3, - "FOURTH" to 4, - "FIFTH" to 5, - ) - - for ((prefix, number) in stars) { - if (masterStars >= number) { - val internalName = "${prefix}_MASTER_STAR" - price += NEUItems.getPrice(internalName) - } - } - - list.add("§7Master Stars: §e$masterStars§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addDrillUpgrades(stack: ItemStack, list: MutableList): Double { - val drillUpgrades = stack.getDrillUpgrades() ?: return 0.0 - - var totalPrice = 0.0 - val map = mutableMapOf() - for (internalName in drillUpgrades) { - val name = NEUItems.getItemStackOrNull(internalName)!!.name - val price = NEUItems.getPriceOrNull(internalName) ?: continue - - totalPrice += price - val format = NumberUtil.format(price) - map[" $name §7(§6$format§7)"] = price - } - if (map.isNotEmpty()) { - list.add("§7Drill upgrades: §6" + NumberUtil.format(totalPrice)) - list += map.sortedDesc().keys - } - return totalPrice - } - - private fun addPowerScrolls(stack: ItemStack, list: MutableList): Double { - val internalName = stack.getPowerScroll() ?: return 0.0 - - val price = NEUItems.getPrice(internalName) - val name = NEUItems.getItemStack(internalName).name!!.removeColor() - list.add("§7$name: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addHelmetSkin(stack: ItemStack, list: MutableList): Double { - val internalName = stack.getHelmetSkin() ?: return 0.0 - - val price = NEUItems.getPrice(internalName) - val name = NEUItems.getItemStack(internalName).name - list.add("§7Skin: $name §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addArmorDye(stack: ItemStack, list: MutableList): Double { - val internalName = stack.getArmorDye() ?: return 0.0 - - val price = NEUItems.getPrice(internalName) - val name = NEUItems.getItemStack(internalName).name - list.add("§7Dye: $name §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addRune(stack: ItemStack, list: MutableList): Double { - val internalName = stack.getRune() ?: return 0.0 - - val price = NEUItems.getPrice(internalName) - val name = NEUItems.getItemStack(internalName).name - list.add("§7Rune: $name §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addAbilityScrolls(stack: ItemStack, list: MutableList): Double { - val abilityScrolls = stack.getAbilityScrolls() ?: return 0.0 - - var totalPrice = 0.0 - val map = mutableMapOf() - for (internalName in abilityScrolls) { - val name = NEUItems.getItemStackOrNull(internalName)!!.name - val price = NEUItems.getPriceOrNull(internalName) ?: continue - - totalPrice += price - val format = NumberUtil.format(price) - map[" $name §7(§6$format§7)"] = price - } - if (map.isNotEmpty()) { - list.add("§7Ability Scrolls: §6" + NumberUtil.format(totalPrice)) - list += map.sortedDesc().keys - } - return totalPrice - } - - private fun addBaseItem(stack: ItemStack, list: MutableList): Double { - val internalName = stack.getInternalName() - var price = NEUItems.getPrice(internalName) - if (price == -1.0) { - price = 0.0 - } - - val name = NEUItems.getItemStack(internalName).name - if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) { - list.add("§7Base item: $name") - return 0.0 - } - - list.add("§7Base item: $name §7(§6" + NumberUtil.format(price) + "§7)") - return price - } - - private fun addEnchantments(stack: ItemStack, list: MutableList): Double { - val enchantments = stack.getEnchantments() ?: return 0.0 - - var totalPrice = 0.0 - val map = mutableMapOf() - - val tieredEnchants = listOf("compact", "cultivating", "champion", "expertise", "hecatomb") - val hasAlwaysScavenger = listOf( - "CRYPT_DREADLORD_SWORD", - "ZOMBIE_SOLDIER_CUTLASS", - "CONJURING_SWORD", - "EARTH_SHARD", - "ZOMBIE_KNIGHT_SWORD", - "SILENT_DEATH", - "ZOMBIE_COMMANDER_WHIP", - ) - - 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) { - if (internalName in hasAlwaysScavenger) continue - } - - var level = rawLevel - var multiplier = 1 - if (rawName == "ultimate_chimera") { - - when (rawLevel) { - 2 -> multiplier = 2 - 3 -> multiplier = 4 - 4 -> multiplier = 8 - 5 -> multiplier = 16 - } - level = 1 - - } - if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) { - multiplier = 5 - } - if (rawName in tieredEnchants) level = 1 - - val enchantmentName = "$rawName;$level".uppercase() - val itemStack = NEUItems.getItemStackOrNull(enchantmentName) ?: continue - val singlePrice = NEUItems.getPriceOrNull(enchantmentName) ?: continue - - - var name = itemStack.getLore()[0] - if (multiplier > 1) { - name = "§8${multiplier}x $name" - } - val price = singlePrice * multiplier - - totalPrice += price - val format = NumberUtil.format(price) - - - map[" $name §7(§6$format§7)"] = price - } - if (map.isNotEmpty()) { - list.add("§7Enchantments: §6" + NumberUtil.format(totalPrice)) - var i = 0 - val size = map.size - for (entry in map.sortedDesc().keys) { - if (i == 7) { - val missing = size - i - list.add(" §7§o$missing more enchantments..") - break - } - list.add(entry) - i++ - } - } - return totalPrice - } - - private fun addGemstones(stack: ItemStack, list: MutableList): Double { - val gemstones = stack.getGemstones() ?: return 0.0 - - var totalPrice = 0.0 - val counterMap = mutableMapOf() - for (gemstone in gemstones) { - val internalName = gemstone.getInternalName() - val old = counterMap[internalName] ?: 0 - counterMap[internalName] = old + 1 - } - - val priceMap = mutableMapOf() - for ((internalName, amount) in counterMap) { - - val name = NEUItems.getItemStack(internalName).name - val price = NEUItems.getPrice(internalName) * amount - - totalPrice += price - val format = NumberUtil.format(price) - - val text = if (amount == 1) { - " $name §7(§6$format§7)" - } else { - " §8${amount}x $name §7(§6$format§7)" - } - priceMap[text] = price - } - - if (priceMap.isNotEmpty()) { - list.add("§7Gemstones: §6" + NumberUtil.format(totalPrice)) - list += priceMap.sortedDesc().keys - } - return totalPrice - } -} \ No newline at end of file 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 new file mode 100644 index 000000000..70980a715 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedItemValue.kt @@ -0,0 +1,549 @@ +package at.hannibal2.skyhanni.features.misc.items + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.RenderItemTooltipEvent +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList +import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc +import at.hannibal2.skyhanni.utils.NEUItems +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getAbilityScrolls +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getArmorDye +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getDrillUpgrades +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFarmingForDummiesCount +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getGemstones +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHelmetSkin +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHotPotatoCount +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getManaDisintegrators +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getMasterStars +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPowerScroll +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getReforgeName +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getRune +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getSilexCount +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getTransmissionTunerCount +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfPiece +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfWar +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasBookOfStats +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasEtherwarp +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasJalapenoBook +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasWoodSingularity +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import io.github.moulberry.moulconfig.internal.KeybindHelper +import io.github.moulberry.notenoughupdates.util.Constants +import net.minecraft.init.Items +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object EstimatedItemValue { + private val config get() = SkyHanniMod.feature.misc + private var display = listOf>() + private val cache = mutableMapOf>>() + private var lastToolTipTime = 0L + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.ChestBackgroundRenderEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.estimatedIemValueEnabled) return + if (!KeybindHelper.isKeyDown(config.estimatedItemValueHotkey) && !config.estimatedIemValueAlwaysEnabled) return + if (System.currentTimeMillis() > lastToolTipTime + 200) return + + config.itemPriceDataPos.renderStringsAndItems(display, posLabel = "Estimated Item Value") + } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + cache.clear() + } + + @SubscribeEvent + fun onRenderItemTooltip(event: RenderItemTooltipEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.estimatedIemValueEnabled) return + + val item = event.stack + val oldData = cache[item] + if (oldData != null) { + display = oldData + lastToolTipTime = System.currentTimeMillis() + return + } + + val newDisplay = try { + draw(item) + } catch (e: Exception) { + LorenzUtils.debug("Estimated Item Value error: ${e.message}") + e.printStackTrace() + listOf() + } + + cache[item] = newDisplay + display = newDisplay + lastToolTipTime = System.currentTimeMillis() + } + + private fun draw(stack: ItemStack): List> { + val internalName = stack.getInternalName() + if (internalName == "") return listOf() + + // FIX neu item list + if (internalName.startsWith("ULTIMATE_ULTIMATE_")) return listOf() + // We don't need this feature to work on books at all + if (stack.item == Items.enchanted_book) return listOf() + // Block catacombs items in mort inventory + if (internalName.startsWith("CATACOMBS_PASS_") || internalName.startsWith("MASTER_CATACOMBS_PASS_")) return listOf() + // Blocks the dungeon map + if (internalName.startsWith("MAP-")) return listOf() + // Hides the rune item + if (internalName.contains("_RUNE;")) return listOf() + + + if (NEUItems.getItemStackOrNull(internalName) == null) { + LorenzUtils.debug("Estimated Item Value is null for internal name: '$internalName'") + return listOf() + } + + val list = mutableListOf() + list.add("§aEstimated Item Value:") + val pair = getEstimatedItemPrice(stack, list) + val (totalPrice, basePrice) = pair + + if (basePrice == totalPrice) return listOf() + + list.add("§aTotal: §6§l" + NumberUtil.format(totalPrice)) + + val newDisplay = mutableListOf>() + for (line in list) { + newDisplay.addAsSingletonList(line) + } + return newDisplay + } + + fun getEstimatedItemPrice(stack: ItemStack, list: MutableList): Pair { + var totalPrice = 0.0 + val basePrice = addBaseItem(stack, list) + totalPrice += basePrice + totalPrice += addReforgeStone(stack, list) + + // once + totalPrice += addRecomb(stack, list) + totalPrice += addArtOfWar(stack, list) + totalPrice += addArtOfPiece(stack, list) + totalPrice += addEtherwarp(stack, list) + totalPrice += addPowerScrolls(stack, list) + totalPrice += addWoodSingularity(stack, list) + totalPrice += addJalapenoBook(stack, list) + totalPrice += addStatsBook(stack, list) + + // counted + totalPrice += addMasterStars(stack, list) + totalPrice += addHotPotatoBooks(stack, list) + totalPrice += addFarmingForDummies(stack, list) + totalPrice += addSilex(stack, list) + totalPrice += addTransmissionTuners(stack, list) + totalPrice += addManaDisintegrators(stack, list) + + // cosmetic + totalPrice += addHelmetSkin(stack, list) + totalPrice += addArmorDye(stack, list) + totalPrice += addRune(stack, list) + + // dynamic + totalPrice += addAbilityScrolls(stack, list) + totalPrice += addDrillUpgrades(stack, list) + totalPrice += addGemstones(stack, list) + totalPrice += addEnchantments(stack, list) + return Pair(totalPrice, basePrice) + } + + private fun addReforgeStone(stack: ItemStack, list: MutableList): Double { + val rawReforgeName = stack.getReforgeName() ?: return 0.0 + + for ((internalName, values) in Constants.REFORGESTONES.entrySet()) { + val stone = values.asJsonObject + val reforgeName = stone.get("reforgeName").asString + if (rawReforgeName == reforgeName.lowercase() || rawReforgeName == internalName.lowercase()) { + val price = NEUItems.getPrice(internalName) + val name = NEUItems.getItemStack(internalName).name + list.add("§7Reforge: §9$reforgeName") + list.add(" §7($name §6" + NumberUtil.format(price) + "§7)") + return price + } + } + + return 0.0 + } + + private fun addRecomb(stack: ItemStack, list: MutableList): Double { + if (!stack.isRecombobulated()) return 0.0 + + val wtfHardcodedRecomb = "RECOMBOBULATOR_3000" + val price = NEUItems.getPrice(wtfHardcodedRecomb) + list.add("§7Recombobulated: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addJalapenoBook(stack: ItemStack, list: MutableList): Double { + if (!stack.hasJalapenoBook()) return 0.0 + + val wtfHardcodedJalapeno = "JALAPENO_BOOK" + + val price = NEUItems.getPrice(wtfHardcodedJalapeno) + list.add("§7Jalapeno Book: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addEtherwarp(stack: ItemStack, list: MutableList): Double { + if (!stack.hasEtherwarp()) return 0.0 + + val wtfHardcodedConduit = "ETHERWARP_CONDUIT" + val wtfHardcodedMerger = "ETHERWARP_MERGER" + val price = NEUItems.getPrice(wtfHardcodedConduit) + NEUItems.getPrice(wtfHardcodedMerger) + list.add("§7Etherwarp: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addWoodSingularity(stack: ItemStack, list: MutableList): Double { + if (!stack.hasWoodSingularity()) return 0.0 + + val wtfHardcodedSingularity = "WOOD_SINGULARITY" + val price = NEUItems.getPrice(wtfHardcodedSingularity) + list.add("§7Wood Singularity: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addArtOfWar(stack: ItemStack, list: MutableList): Double { + if (!stack.hasArtOfWar()) return 0.0 + + val ripTechno = "THE_ART_OF_WAR" + val price = NEUItems.getPrice(ripTechno) + list.add("§7The Art of War: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addStatsBook(stack: ItemStack, list: MutableList): Double { + if (!stack.hasBookOfStats()) return 0.0 + + val ripTechno = "BOOK_OF_STATS" + val price = NEUItems.getPrice(ripTechno) + list.add("§7Book of Stats: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + // TODO untested + private fun addArtOfPiece(stack: ItemStack, list: MutableList): Double { + if (!stack.hasArtOfPiece()) return 0.0 + + val ripTechno = "THE_ART_OF_PEACE" + val price = NEUItems.getPrice(ripTechno) + list.add("§7The Art Of Piece: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addHotPotatoBooks(stack: ItemStack, list: MutableList): Double { + val count = stack.getHotPotatoCount() ?: return 0.0 + + val hpb: Int + val fuming: Int + if (count <= 10) { + hpb = count + fuming = 0 + } else { + hpb = 10 + fuming = count - 10 + } + + var totalPrice = 0.0 + + val wtfHardcodedHpb = "HOT_POTATO_BOOK" + val hpbPrice = NEUItems.getPrice(wtfHardcodedHpb) * hpb + list.add("§7HPB's: §e$hpb§7/§e10 §7(§6" + NumberUtil.format(hpbPrice) + "§7)") + totalPrice += hpbPrice + + if (fuming > 0) { + val wtfHardcodedFuming = "FUMING_POTATO_BOOK" + val fumingPrice = NEUItems.getPrice(wtfHardcodedFuming) * fuming + list.add("§7Fuming: §e$fuming§7/§e5 §7(§6" + NumberUtil.format(fumingPrice) + "§7)") + totalPrice += fumingPrice + } + + return totalPrice + } + + private fun addFarmingForDummies(stack: ItemStack, list: MutableList): Double { + val count = stack.getFarmingForDummiesCount() ?: return 0.0 + + val wtfHardcodedDumbFarmers = "FARMING_FOR_DUMMIES" + val price = NEUItems.getPrice(wtfHardcodedDumbFarmers) * count + list.add("§7Farming for Dummies: §e$count§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addSilex(stack: ItemStack, list: MutableList): Double { + val tier = stack.getSilexCount() ?: return 0.0 + + val internalName = stack.getInternalName() + val maxTier = if (internalName == "STONK_PICKAXE") 4 else 5 + + val wtfHardcodedSilex = "SIL_EX" + val price = NEUItems.getPrice(wtfHardcodedSilex) * tier + list.add("§7Silex: §e$tier§7/§e$maxTier §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addTransmissionTuners(stack: ItemStack, list: MutableList): Double { + val count = stack.getTransmissionTunerCount() ?: return 0.0 + + val wtfHardcodedTuner = "TRANSMISSION_TUNER" + val price = NEUItems.getPrice(wtfHardcodedTuner) * count + list.add("§7Transmission Tuners: §e$count§7/§e4 §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addManaDisintegrators(stack: ItemStack, list: MutableList): Double { + val count = stack.getManaDisintegrators() ?: return 0.0 + + val wtfHardcodedTuner = "MANA_DISINTEGRATOR" + val price = NEUItems.getPrice(wtfHardcodedTuner) * count + list.add("§7Mana Disintegrators: §e$count§7/§e10 §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addMasterStars(stack: ItemStack, list: MutableList): Double { + val masterStars = stack.getMasterStars() + if (masterStars == 0) return 0.0 + + var price = 0.0 + + val stars = mapOf( + "FIRST" to 1, + "SECOND" to 2, + "THIRD" to 3, + "FOURTH" to 4, + "FIFTH" to 5, + ) + + for ((prefix, number) in stars) { + if (masterStars >= number) { + val internalName = "${prefix}_MASTER_STAR" + price += NEUItems.getPrice(internalName) + } + } + + list.add("§7Master Stars: §e$masterStars§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addDrillUpgrades(stack: ItemStack, list: MutableList): Double { + val drillUpgrades = stack.getDrillUpgrades() ?: return 0.0 + + var totalPrice = 0.0 + val map = mutableMapOf() + for (internalName in drillUpgrades) { + val name = NEUItems.getItemStackOrNull(internalName)!!.name + val price = NEUItems.getPriceOrNull(internalName) ?: continue + + totalPrice += price + val format = NumberUtil.format(price) + map[" $name §7(§6$format§7)"] = price + } + if (map.isNotEmpty()) { + list.add("§7Drill upgrades: §6" + NumberUtil.format(totalPrice)) + list += map.sortedDesc().keys + } + return totalPrice + } + + private fun addPowerScrolls(stack: ItemStack, list: MutableList): Double { + val internalName = stack.getPowerScroll() ?: return 0.0 + + val price = NEUItems.getPrice(internalName) + val name = NEUItems.getItemStack(internalName).name!!.removeColor() + list.add("§7$name: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addHelmetSkin(stack: ItemStack, list: MutableList): Double { + val internalName = stack.getHelmetSkin() ?: return 0.0 + + val price = NEUItems.getPrice(internalName) + val name = NEUItems.getItemStack(internalName).name + list.add("§7Skin: $name §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addArmorDye(stack: ItemStack, list: MutableList): Double { + val internalName = stack.getArmorDye() ?: return 0.0 + + val price = NEUItems.getPrice(internalName) + val name = NEUItems.getItemStack(internalName).name + list.add("§7Dye: $name §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addRune(stack: ItemStack, list: MutableList): Double { + val internalName = stack.getRune() ?: return 0.0 + + val price = NEUItems.getPrice(internalName) + val name = NEUItems.getItemStack(internalName).name + list.add("§7Rune: $name §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addAbilityScrolls(stack: ItemStack, list: MutableList): Double { + val abilityScrolls = stack.getAbilityScrolls() ?: return 0.0 + + var totalPrice = 0.0 + val map = mutableMapOf() + for (internalName in abilityScrolls) { + val name = NEUItems.getItemStackOrNull(internalName)!!.name + val price = NEUItems.getPriceOrNull(internalName) ?: continue + + totalPrice += price + val format = NumberUtil.format(price) + map[" $name §7(§6$format§7)"] = price + } + if (map.isNotEmpty()) { + list.add("§7Ability Scrolls: §6" + NumberUtil.format(totalPrice)) + list += map.sortedDesc().keys + } + return totalPrice + } + + private fun addBaseItem(stack: ItemStack, list: MutableList): Double { + val internalName = stack.getInternalName() + var price = NEUItems.getPrice(internalName) + if (price == -1.0) { + price = 0.0 + } + + val name = NEUItems.getItemStack(internalName).name + if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) { + list.add("§7Base item: $name") + return 0.0 + } + + list.add("§7Base item: $name §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + private fun addEnchantments(stack: ItemStack, list: MutableList): Double { + val enchantments = stack.getEnchantments() ?: return 0.0 + + var totalPrice = 0.0 + val map = mutableMapOf() + + val tieredEnchants = listOf("compact", "cultivating", "champion", "expertise", "hecatomb") + val hasAlwaysScavenger = listOf( + "CRYPT_DREADLORD_SWORD", + "ZOMBIE_SOLDIER_CUTLASS", + "CONJURING_SWORD", + "EARTH_SHARD", + "ZOMBIE_KNIGHT_SWORD", + "SILENT_DEATH", + "ZOMBIE_COMMANDER_WHIP", + ) + + 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) { + if (internalName in hasAlwaysScavenger) continue + } + + var level = rawLevel + var multiplier = 1 + if (rawName == "ultimate_chimera") { + + when (rawLevel) { + 2 -> multiplier = 2 + 3 -> multiplier = 4 + 4 -> multiplier = 8 + 5 -> multiplier = 16 + } + level = 1 + + } + if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) { + multiplier = 5 + } + if (rawName in tieredEnchants) level = 1 + + val enchantmentName = "$rawName;$level".uppercase() + val itemStack = NEUItems.getItemStackOrNull(enchantmentName) ?: continue + val singlePrice = NEUItems.getPriceOrNull(enchantmentName) ?: continue + + + var name = itemStack.getLore()[0] + if (multiplier > 1) { + name = "§8${multiplier}x $name" + } + val price = singlePrice * multiplier + + totalPrice += price + val format = NumberUtil.format(price) + + + map[" $name §7(§6$format§7)"] = price + } + if (map.isNotEmpty()) { + list.add("§7Enchantments: §6" + NumberUtil.format(totalPrice)) + var i = 0 + val size = map.size + for (entry in map.sortedDesc().keys) { + if (i == 7) { + val missing = size - i + list.add(" §7§o$missing more enchantments..") + break + } + list.add(entry) + i++ + } + } + return totalPrice + } + + private fun addGemstones(stack: ItemStack, list: MutableList): Double { + val gemstones = stack.getGemstones() ?: return 0.0 + + var totalPrice = 0.0 + val counterMap = mutableMapOf() + for (gemstone in gemstones) { + val internalName = gemstone.getInternalName() + val old = counterMap[internalName] ?: 0 + counterMap[internalName] = old + 1 + } + + val priceMap = mutableMapOf() + for ((internalName, amount) in counterMap) { + + val name = NEUItems.getItemStack(internalName).name + val price = NEUItems.getPrice(internalName) * amount + + totalPrice += price + val format = NumberUtil.format(price) + + val text = if (amount == 1) { + " $name §7(§6$format§7)" + } else { + " §8${amount}x $name §7(§6$format§7)" + } + priceMap[text] = price + } + + if (priceMap.isNotEmpty()) { + list.add("§7Gemstones: §6" + NumberUtil.format(totalPrice)) + list += priceMap.sortedDesc().keys + } + return totalPrice + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt new file mode 100644 index 000000000..7dd8ca20a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/items/EstimatedWardrobePrice.kt @@ -0,0 +1,62 @@ +package at.hannibal2.skyhanni.features.misc.items + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.InventoryOpenEvent +import at.hannibal2.skyhanni.events.LorenzToolTipEvent +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NumberUtil +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class EstimatedWardrobePrice { + private val config get() = SkyHanniMod.feature.misc + var data = mutableMapOf>() + + @SubscribeEvent + fun onTooltip(event: LorenzToolTipEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.estimatedIemValueArmor) return + + val slot = event.slot.slotNumber + val id = slot % 9 + // Only showing in the armor select line + if (slot - id != 36) return + val items = data[id] ?: return + + var index = 3 + val toolTip = event.toolTip + toolTip.add(index++, "") + toolTip.add(index++, "§aEstimated Armor Value:") + + var totalPrice = 0.0 + for (item in items) { + val name = item.name + val price = EstimatedItemValue.getEstimatedItemPrice(item, mutableListOf()).first + totalPrice += price + + toolTip.add(index++, " §7-$name: §6${NumberUtil.format(price)}") + } + toolTip.add(index++, " §aTotal Value: §6§l${NumberUtil.format(totalPrice)}") + } + + @SubscribeEvent + fun onInventoryOpen(event: InventoryOpenEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.estimatedIemValueArmor) return + if (!event.inventoryName.startsWith("Wardrobe")) return + + val map = mutableMapOf>() + + for ((slot, item) in event.inventoryItems) { + if (item.getInternalName() == "") continue + val price = EstimatedItemValue.getEstimatedItemPrice(item, mutableListOf()).first + if (price == 0.0) continue + val id = slot % 9 + val list = map.getOrPut(id) { mutableListOf() } + list.add(item) + } + data = map + } +} \ No newline at end of file -- cgit