From 8bd79d3e44dcaf156e4e48c2ecedadcd22a5e172 Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Date: Tue, 4 Apr 2023 08:04:54 +0200 Subject: Added Estimated Item Value - Displays an estimated item value for the item you hover over. --- .../java/at/hannibal2/skyhanni/SkyHanniMod.java | 1 + .../hannibal2/skyhanni/config/features/Misc.java | 32 +- .../skyhanni/features/misc/EstimatedItemValue.kt | 527 +++++++++++++++++++++ .../java/at/hannibal2/skyhanni/utils/ItemUtils.kt | 5 +- .../java/at/hannibal2/skyhanni/utils/NEUItems.kt | 8 + .../skyhanni/utils/SkyBlockItemModifierUtils.kt | 283 +++++++++++ 6 files changed, 851 insertions(+), 5 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt (limited to 'src/main/java/at/hannibal2/skyhanni') diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java index 9a4990595..5a1a92a4b 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java @@ -241,6 +241,7 @@ public class SkyHanniMod { loadModule(new GardenComposterInventoryFeatures()); loadModule(new MinionCollectLogic()); loadModule(new PasteIntoSigns()); + loadModule(new EstimatedItemValue()); Commands.INSTANCE.init(); 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 609f72e43..8b9ea625a 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java @@ -2,11 +2,9 @@ package at.hannibal2.skyhanni.config.features; import at.hannibal2.skyhanni.config.core.config.Position; import com.google.gson.annotations.Expose; -import io.github.moulberry.moulconfig.annotations.ConfigAccordionId; -import io.github.moulberry.moulconfig.annotations.ConfigEditorAccordion; -import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; -import io.github.moulberry.moulconfig.annotations.ConfigOption; +import io.github.moulberry.moulconfig.annotations.*; import io.github.moulberry.moulconfig.observer.Property; +import org.lwjgl.input.Keyboard; public class Misc { @@ -210,6 +208,32 @@ public class Misc { @Expose public Position chickenHeadTimerPosition = new Position(-372, 73, false, true); + @Expose + @ConfigOption(name = "Estimated Item Value", desc = "(Enchantments, reforging stone prices, gemstones, gemstones, drill parts and more)") + @ConfigEditorAccordion(id = 11) + public boolean estimatedItemValue = false; + + @Expose + @ConfigOption(name = "Enable Estimated Price", desc = "Displays an estimated item value for the item you hover over.") + @ConfigEditorBoolean + @ConfigAccordionId(id = 11) + public boolean estimatedIemValueEnabled = false; + + @Expose + @ConfigOption(name = "Hotkey", desc = "Press this key to show the estimated item value.") + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) + @ConfigAccordionId(id = 11) + public int estimatedItemValueHotkey = Keyboard.KEY_NONE; + + @Expose + @ConfigOption(name = "Show always", desc = "Ignore the hotkey and always display the item value.") + @ConfigEditorBoolean + @ConfigAccordionId(id = 11) + public boolean estimatedIemValueAlwaysEnabled = true; + + @Expose + public Position itemPriceDataPos = new Position(140, 90, false, true); + @Expose @ConfigOption(name = "Exp Bottles", desc = "Hides all the experience orbs lying on the ground.") @ConfigEditorBoolean diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt new file mode 100644 index 000000000..a92dcf231 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt @@ -0,0 +1,527 @@ +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.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.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.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.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.event.entity.player.ItemTooltipEvent +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 onItemTooltipLow(event: ItemTooltipEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.estimatedIemValueEnabled) return + + val item = event.itemStack + 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): MutableList> { + val list = mutableListOf() + list.add("§aEstimated Item Value:") + + val internalName = stack.getInternalName() + if (internalName == "") return mutableListOf() + + //FIX neu item list + if (internalName.startsWith("ULTIMATE_ULTIMATE_")) return mutableListOf() + if (stack.item == Items.enchanted_book) return mutableListOf() + + 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) + + // counted + totalPrice += addMasterStars(stack, list) + totalPrice += addHotPotatoBooks(stack, list) + totalPrice += addFarmingForDummies(stack, list) + totalPrice += addSilex(stack, list) + totalPrice += addStatsBook(stack, list) + totalPrice += addTransmissionTuners(stack, list) + totalPrice += addManaDisintegrators(stack, list) + + // dynamic + totalPrice += addAbilityScrolls(stack, list) + totalPrice += addDrillUpgrades(stack, list) + totalPrice += addGemstones(stack, list) + totalPrice += addEnchantments(stack, list) + + if (basePrice == totalPrice) return mutableListOf() + + 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()) { + 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()) { + val wtfHardcodedRecomb = "RECOMBOBULATOR_3000" + val price = NEUItems.getPrice(wtfHardcodedRecomb) + list.add("§7Recombobulated: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + return 0.0 + } + + private fun addJalapenoBook(stack: ItemStack, list: MutableList): Double { + if (stack.hasJalapenoBook()) { + val wtfHardcodedJalapeno = "JALAPENO_BOOK" + + val price = NEUItems.getPrice(wtfHardcodedJalapeno) + list.add("§7Jalapeno Book: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + return 0.0 + } + + private fun addEtherwarp(stack: ItemStack, list: MutableList): Double { + if (stack.hasEtherwarp()) { + 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 + } + + return 0.0 + } + + private fun addWoodSingularity(stack: ItemStack, list: MutableList): Double { + if (stack.hasWoodSingularity()) { + val wtfHardcodedSingularity = "WOOD_SINGULARITY" + val price = NEUItems.getPrice(wtfHardcodedSingularity) + list.add("§7Wood Singularity: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)") + return price + } + + return 0.0 + } + + private fun addArtOfWar(stack: ItemStack, list: MutableList): Double { + if (stack.hasArtOfWar()) { + 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 + } + + return 0.0 + } + + private fun addStatsBook(stack: ItemStack, list: MutableList): Double { + if (stack.hasBookOfStats()) { + 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 + } + + return 0.0 + } + + // TODO untested + private fun addArtOfPiece(stack: ItemStack, list: MutableList): Double { + if (stack.hasArtOfPiece()) { + 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 + } + + return 0.0 + } + + private fun addHotPotatoBooks(stack: ItemStack, list: MutableList): Double { + val count = stack.getHotPotatoCount() + if (count == 0) 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() + if (count == 0) 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() + if (tier == 0) 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() + if (count == 0) 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() + if (count == 0) 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 { + var totalPrice = 0.0 + val map = mutableMapOf() + for (internalName in stack.getDrillUpgrades()) { + 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 addAbilityScrolls(stack: ItemStack, list: MutableList): Double { + var totalPrice = 0.0 + val map = mutableMapOf() + for (internalName in stack.getAbilityScrolls()) { + 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 { + 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 stack.getEnchantments()) { + // 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 + if (rawName in tieredEnchants) level = 1 + + val enchantmentName = "$rawName;$level".uppercase() + val itemStack = NEUItems.getItemStackOrNull(enchantmentName) ?: continue + var name = itemStack.getLore()[0] + val singlePrice = NEUItems.getPriceOrNull(enchantmentName) ?: continue + val multiplier = if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) { + name = "§85x $name" + 5 + } else 1 + 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() + if (gemstones.isEmpty()) 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 + } + + class GemstoneSlot(val type: GemstoneType, val tier: GemstoneTier) { + fun getInternalName() = "${tier}_${type}_GEM" + } + + enum class GemstoneTier(val displayName: String) { + ROUGH("Rough"), + FLAWED("Flawed"), + FINE("Fine"), + FLAWLESS("Flawless"), + PERFECT("Perfect"), + ; + + companion object { + fun getByName(name: String) = GemstoneTier.values().firstOrNull { it.name == name } + } + } + + enum class GemstoneType(val displayName: String) { + JADE("Jade"), + AMBER("Amber"), + TOPAZ("Topaz"), + SAPPHIRE("Sapphire"), + AMETHYST("Amethyst"), + JASPER("Jasper"), + RUBY("Ruby"), + OPAL("Opal"), + ; + + companion object { + fun getByName(name: String) = values().firstOrNull { it.name == name } + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt index 557950fbe..049caf3d1 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.utils +import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated import at.hannibal2.skyhanni.utils.StringUtils.matchRegex import at.hannibal2.skyhanni.utils.StringUtils.removeColor import com.google.gson.GsonBuilder @@ -28,15 +29,17 @@ object ItemUtils { return list } + // TODO change else janni is sad fun isCoopSoulBound(stack: ItemStack): Boolean = stack.getLore().any { it == "§8§l* §8Co-op Soulbound §8§l*" || it == "§8§l* §8Soulbound §8§l*" } + // TODO change else janni is sad fun isSoulBound(stack: ItemStack): Boolean = stack.getLore().any { it == "§8§l* §8Soulbound §8§l*" } - fun isRecombobulated(stack: ItemStack): Boolean = stack.getLore().any { it.contains("§k") }//TODO use item api + fun isRecombobulated(stack: ItemStack) = stack.isRecombobulated() fun isPet(name: String): Boolean = name.matchRegex("\\[Lvl (.*)] (.*)") && !listOf( "Archer", diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt index 23ed9be71..25d67bb07 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt @@ -47,6 +47,14 @@ object NEUItems { .resolveInternalName() ?: "" } + fun getPriceOrNull(internalName: String, useSellingPrice: Boolean = false): Double? { + val price = getPrice(internalName, useSellingPrice) + if (price == -1.0) { + return null + } + return price + } + fun getPrice(internalName: String, useSellingPrice: Boolean = false): Double { val bazaarData = BazaarApi.getBazaarDataForInternalName(internalName) bazaarData?.let { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt new file mode 100644 index 000000000..4229a80df --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt @@ -0,0 +1,283 @@ +package at.hannibal2.skyhanni.utils + +import at.hannibal2.skyhanni.features.misc.EstimatedItemValue +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.name +import net.minecraft.item.ItemStack + +object SkyBlockItemModifierUtils { + private val drillPartTypes = listOf("drill_part_upgrade_module", "drill_part_engine", "drill_part_fuel_tank") + + fun ItemStack.getHotPotatoCount(): Int { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "hot_potato_count") continue + return extraAttributes.getInteger(attributes) + } + } + return 0 + } + + fun ItemStack.getFarmingForDummiesCount(): Int { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "farming_for_dummies_count") continue + return extraAttributes.getInteger(attributes) + } + } + return 0 + } + + fun ItemStack.getSilexCount(): Int { + var silexTier = 0 + for ((name, amount) in getEnchantments()) { + if (name == "efficiency") { + if (amount > 5) { + silexTier = amount - 5 + } + } + } + + if (getInternalName() == "STONK_PICKAXE") { + silexTier-- + } + + return silexTier + } + + fun ItemStack.getTransmissionTunerCount(): Int { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "tuned_transmission") continue + return extraAttributes.getInteger(attributes) + } + } + return 0 + } + + fun ItemStack.getManaDisintegrators(): Int { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "mana_disintegrator_count") continue + return extraAttributes.getInteger(attributes) + } + } + return 0 + } + + fun ItemStack.getMasterStars(): Int { + val stars = mapOf( + "➊" to 1, + "➋" to 2, + "➌" to 3, + "➍" to 4, + "➎" to 5, + ) + val itemName = name!! + for ((icon, number) in stars) { + if (itemName.endsWith(icon)) { + return number + } + } + + return 0 + } + + fun ItemStack.getDrillUpgrades(): List { + val list = mutableListOf() + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes in drillPartTypes) { + val upgradeItem = extraAttributes.getString(attributes) + list.add(upgradeItem.uppercase()) + } + } + } + + return list + } + + fun ItemStack.getPowerScroll(): String? { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes == "power_ability_scroll") { + return extraAttributes.getString(attributes) + } + } + } + + return null + } + + fun ItemStack.getAbilityScrolls(): List { + val list = mutableListOf() + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes == "ability_scroll") { + + val tagList = extraAttributes.getTagList(attributes, 8) + for (i in 0..3) { + val text = tagList.get(i).toString() + if (text == "END") break + var internalName = text.replace("\"", "") + list.add(internalName) + } + } + } + } + + return list + } + + fun ItemStack.getReforgeName(): String? { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "modifier") continue + return extraAttributes.getString(attributes) + } + } + return null + } + + fun ItemStack.isRecombobulated(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("rarity_upgrades") + } + + return false + } + + fun ItemStack.hasJalapenoBook(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("jalapeno_count") + } + + return false + } + + fun ItemStack.hasEtherwarp(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("ethermerge") + } + + return false + } + + fun ItemStack.hasWoodSingularity(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("wood_singularity_count") + } + + return false + } + + fun ItemStack.hasArtOfWar(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("art_of_war_count") + } + + return false + } + + // TODO untested + fun ItemStack.hasBookOfStats(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("stats_book") + } + + return false + } + + fun ItemStack.hasArtOfPiece(): Boolean { + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + return extraAttributes.hasKey("artOfPeaceApplied") + } + + return false + } + + fun ItemStack.getEnchantments(): Map { + val map = mutableMapOf() + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "enchantments") continue + val enchantments = extraAttributes.getCompoundTag(attributes) + for (key in enchantments.keySet) { + map[key] = enchantments.getInteger(key) + } + } + } + return map + } + + fun ItemStack.getGemstones(): List { + val list = mutableListOf() + for (tags in tagCompound.keySet) { + if (tags != "ExtraAttributes") continue + val extraAttributes = tagCompound.getCompoundTag(tags) + for (attributes in extraAttributes.keySet) { + if (attributes != "gems") continue + val gemstones = extraAttributes.getCompoundTag(attributes) + for (key in gemstones.keySet) { + if (key.endsWith("_gem")) continue + if (key == "unlocked_slots") continue + val value = gemstones.getString(key) + if (value == "") continue + + val rawType = key.split("_")[0] + val type = EstimatedItemValue.GemstoneType.getByName(rawType) + + val tier = EstimatedItemValue.GemstoneTier.getByName(value) + if (tier == null) { + LorenzUtils.debug("Gemstone tier is null for item $name: ('$key' = '$value')") + continue + } + if (type != null) { + list.add(EstimatedItemValue.GemstoneSlot(type, tier)) + } else { + val newKey = gemstones.getString(key + "_gem") + val newType = EstimatedItemValue.GemstoneType.getByName(newKey) + if (newType == null) { + LorenzUtils.debug("Gemstone type is null for item $name: ('$newKey' with '$key' = '$value')") + continue + } + list.add(EstimatedItemValue.GemstoneSlot(newType, tier)) + } + } + } + } + return list + } +} \ No newline at end of file -- cgit