diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | FEATURES.md | 1 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java | 3 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/config/features/Garden.java | 20 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt | 141 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt | 7 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt | 7 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartCopperPrice.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt) | 65 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt | 4 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt | 19 |
10 files changed, 216 insertions, 52 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c6529d10..482728305 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ + Added **Visitor Item Preview** - Show the base type for the required items next to new visitors (Note that some visitors may require any crop) + Added **Teleport Pad Compact Name** - Hide the 'Warp to' and 'No Destination' texts over teleport pads. + Added Money per Hour Advanced stats - Show not only Sell Offer price but also Instant Sell price and NPC Sell price (Suggestion: Enable Compact Price as well for this) ++ Added Anita Medal Profit - Helps to identify profitable items to buy at the Anita item shop and potential profit from selling the item at the auction house. ### Features from other Mods diff --git a/FEATURES.md b/FEATURES.md index 8795883e0..0f89fb71a 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -197,6 +197,7 @@ + **Visitor Item Preview** - Show the base type for the required items next to new visitors (Note that some visitors may require any crop) + **Teleport Pad Compact Name** - Hide the 'Warp to' and 'No Destination' texts over teleport pads. + Money per Hour Advanced stats - Show not only Sell Offer price but also Instant Sell price and NPC Sell price (Suggestion: Enable Compact Price as well for this) ++ Added Anita Medal Profit - Helps to identify profitable items to buy at the Anita item shop and potential profit from selling the item at the auction house. ## Commands - /wiki (using hypixel-skyblock.fandom.com instead of Hypixel wiki) diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java index e23c2c37b..1d5281b60 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java @@ -212,7 +212,7 @@ public class SkyHanniMod { loadModule(new TpsCounter()); loadModule(new ParticleHider()); loadModule(new MiscFeatures()); - loadModule(new SkyMartBestProfit()); + loadModule(new SkyMartCopperPrice()); loadModule(new GardenVisitorFeatures()); loadModule(new GardenInventoryNumbers()); loadModule(new GardenVisitorTimer()); @@ -233,6 +233,7 @@ public class SkyHanniMod { loadModule(new JoinCrystalHollows()); loadModule(new GardenVisitorColorNames()); loadModule(new GardenTeleportPadCompactName()); + loadModule(new AnitaMedalProfit()); Commands.INSTANCE.init(); diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java index 528eb7966..b440f9dbd 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java @@ -585,6 +585,26 @@ public class Garden { public boolean teleportPadsCompactName = false; @Expose + @ConfigOption(name = "Anita Medal Profit", desc = "") + @ConfigEditorAccordion(id = 12) + public boolean anitaMedalProfit = false; + + @Expose + @ConfigOption( + name = "Show Prices", + desc = "Helps to identify profitable items to buy at the Anita item shop " + + "and potential profit from selling the item at the auction house." + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 12) + public boolean anitaMedalProfitEnabled = true; + + @Expose + public Position anitaMedalProfitPos = new Position(206, 158, false, true); + + + + @Expose @ConfigOption(name = "Plot Price", desc = "Show the price of the plot in coins when inside the Configure Plots inventory.") @ConfigEditorBoolean public boolean plotPrice = true; diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt new file mode 100644 index 000000000..fa6500bcb --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt @@ -0,0 +1,141 @@ +package at.hannibal2.skyhanni.features.garden + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryOpenEvent +import at.hannibal2.skyhanni.utils.ItemUtils +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.NEUItems +import at.hannibal2.skyhanni.utils.NumberUtil +import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class AnitaMedalProfit { + private val config get() = SkyHanniMod.feature.garden + private var display = listOf<List<Any>>() + + companion object { + var inInventory = false + } + + enum class MedalType(val displayName: String, val factorBronze: Int) { + GOLD("§6Gold medal", 8), + SILVER("§fSilver medal", 2), + BRONZE("§cBronze medal", 1), + ; + } + + private fun getMedal(name: String) = MedalType.values().firstOrNull { it.displayName == name } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + inInventory = false + } + + @SubscribeEvent + fun onInventoryOpen(event: InventoryOpenEvent) { + if (!config.anitaMedalProfitEnabled) return + if (event.inventoryName != "Anita") return + + inInventory = true + + val table = mutableMapOf<Pair<String, String>, Pair<Double, String>>() + for ((_, item) in event.inventoryItems) { + readItem(item, table) + } + + val newList = mutableListOf<List<Any>>() + newList.addAsSingletonList("§eMedal Profit") + LorenzUtils.fillTable(newList, table) + display = newList + } + + private fun readItem(item: ItemStack, table: MutableMap<Pair<String, String>, Pair<Double, String>>) { + var itemName = item.name ?: return + if (itemName == " ") return + if (itemName.endsWith("Enchanted Book")) { + itemName = item.getLore()[0] + } + + val fullCost = getFullCost(getRequiredItems(item)) + if (fullCost < 0) return + + val (name, amount) = ItemUtils.readItemAmount(itemName) + if (name == null) return + + val internalName = try { + NEUItems.getInternalName(name) + } catch (e: Exception) { + // TODO make a better alternative + item.getInternalName() + } + + val itemPrice = NEUItems.getPrice(internalName) * amount + if (itemPrice < 0) return + + val profit = itemPrice - fullCost + val format = NumberUtil.format(profit) + val color = if (profit > 0) "§6" else "§c" + table[Pair(itemName, "$color$format")] = Pair(profit, internalName) + } + + private fun getFullCost(requiredItems: MutableList<String>): Double { + val jacobTicketPrice = NEUItems.getPrice("JACOBS_TICKET") + var otherItemsPrice = 0.0 + for (rawItemName in requiredItems) { + val (name, amount) = ItemUtils.readItemAmount(rawItemName) + if (name == null) { + LorenzUtils.error("§c[SkyHanni] Could not read item '$rawItemName'") + continue + } + + val medal = getMedal(name) + otherItemsPrice += if (medal != null) { + val bronze = medal.factorBronze * amount + bronze * jacobTicketPrice + } else { + val internalName = NEUItems.getInternalName(name) + NEUItems.getPrice(internalName) * amount + } + } + return otherItemsPrice + } + + private fun getRequiredItems(item: ItemStack): MutableList<String> { + val items = mutableListOf<String>() + var next = false + for (line in item.getLore()) { + if (line == "§7Cost") { + next = true + continue + } + if (next) { + if (line == "") { + next = false + continue + } + + items.add(line.replace("§8 ", " §8")) + } + } + return items + } + + @SubscribeEvent + fun onBackgroundDraw(event: GuiRenderEvent.ChestBackgroundRenderEvent) { + if (inInventory) { + config.anitaMedalProfitPos.renderStringsAndItems( + display, + extraSpace = 5, + itemScale = 1.7, + posLabel = "Anita Medal Profit" + ) + } + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt index abea33203..85b61db60 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt @@ -1,11 +1,8 @@ package at.hannibal2.skyhanni.features.garden import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.utils.InventoryUtils -import at.hannibal2.skyhanni.utils.ItemUtils +import at.hannibal2.skyhanni.utils.* import at.hannibal2.skyhanni.utils.ItemUtils.name -import at.hannibal2.skyhanni.utils.NEUItems -import at.hannibal2.skyhanni.utils.NumberUtil import net.minecraftforge.event.entity.player.ItemTooltipEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -39,6 +36,8 @@ class GardenNextPlotPrice { val price = lowestBin * amount val format = NumberUtil.format(price) list[i] = list[i] + " §7(§6$format§7)" + } else { + LorenzUtils.error("§c[SkyHanni] Could not read item '$line'") } break } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt index df71986ed..917b40b85 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt @@ -77,7 +77,10 @@ class GardenVisitorFeatures { if (line.isEmpty()) break val (itemName, amount) = ItemUtils.readItemAmount(line) - if (itemName == null) continue + if (itemName == null) { + LorenzUtils.error("§c[SkyHanni] Could not read item '$line'") + continue + } val internalName = NEUItems.getInternalName(itemName) visitor.items[internalName] = amount } @@ -287,6 +290,8 @@ class GardenVisitorFeatures { list.add(i + itemsWithSpeedCounter, " §7- $formatName($formatSpeed§7)") } } + } else { + LorenzUtils.error("§c[SkyHanni] Could not read item '$line'") } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartCopperPrice.kt index a4d1e5bd1..7457224e6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartCopperPrice.kt @@ -7,32 +7,30 @@ import at.hannibal2.skyhanni.events.InventoryOpenEvent 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.StringUtils.removeColor -import net.minecraft.client.Minecraft -import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.regex.Pattern -class SkyMartBestProfit { - +class SkyMartCopperPrice { private val pattern = Pattern.compile("§c(.*) Copper") private var display = listOf<List<Any>>() private val config get() = SkyHanniMod.feature.garden + companion object { + var inInventory = false + } + @SubscribeEvent fun onInventoryOpen(event: InventoryOpenEvent) { if (!isEnabled()) return - if (event.inventoryName != "SkyMart") return - val priceMap = mutableMapOf<Pair<String, String>, Double>() - val iconMap = mutableMapOf<String, ItemStack>() - + inInventory = true + val table = mutableMapOf<Pair<String, String>, Pair<Double, String>>() for (stack in event.inventoryItems.values) { for (line in stack.getLore()) { val matcher = pattern.matcher(line) @@ -53,55 +51,34 @@ class SkyMartBestProfit { name = stack.getLore()[0] } - NEUItems.getItemStackOrNull(internalName)?.let { - iconMap[name] = it - } - val advancedStats = if (config.skyMartCopperPriceAdvancedStats) { " §7(§6$priceFormat §7/ §c$amountFormat Copper§7)" } else "" - val pair = Pair(name, "§6§l$perFormat$advancedStats") - priceMap[pair] = factor + val pair = Pair("$name§f:", "§6§l$perFormat$advancedStats") + table[pair] = Pair(factor, internalName) } } - display = drawDisplay(priceMap, iconMap) - } - - private fun drawDisplay( - priceMap: MutableMap<Pair<String, String>, Double>, - iconMap: MutableMap<String, ItemStack>, - ): MutableList<List<Any>> { val newList = mutableListOf<List<Any>>() - - newList.addAsSingletonList("Coins per §cCopper§f:") - newList.addAsSingletonList("") - - val keys = priceMap.sortedDesc().keys - val renderer = Minecraft.getMinecraft().fontRendererObj - val longest = keys.map { it.first }.maxOfOrNull { renderer.getStringWidth(it.removeColor()) } ?: 0 - - for ((name, second) in keys) { - var displayName = "$name§f:" - while (renderer.getStringWidth(displayName.removeColor()) < longest) { - displayName += " " - } - iconMap[name]?.let { - newList.add(listOf(it, "$displayName $second")) - } - } - return newList + newList.addAsSingletonList("§eCoins per Copper§f:") + LorenzUtils.fillTable(newList, table) + display = newList } @SubscribeEvent fun onInventoryClose(event: InventoryCloseEvent) { - display = emptyList() + inInventory = false } @SubscribeEvent fun onBackgroundDraw(event: GuiRenderEvent.ChestBackgroundRenderEvent) { - if (isEnabled()) { - config.skyMartCopperPricePos.renderStringsAndItems(display, posLabel = "Sky Mart Copper Price") + if (inInventory) { + config.skyMartCopperPricePos.renderStringsAndItems( + display, + extraSpace = 5, + itemScale = 1.7, + posLabel = "Sky Mart Copper Price" + ) } } diff --git a/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt b/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt index 9f78e5452..02feac91c 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt @@ -52,8 +52,8 @@ class LorenzTest { // SoundUtils.createSound(name, pitch).playSound() -// a = args[0].toDouble() -// b = args[1].toDouble() + a = args[0].toDouble() + b = args[1].toDouble() // c = args[2].toDouble() // for (line in (Minecraft.getMinecraft().ingameGUI.tabList as AccessorGuiPlayerTabOverlay).footer.unformattedText diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt index 7378d6131..8e9b9de9e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt @@ -171,4 +171,23 @@ object LorenzUtils { fun <E> MutableList<List<E>>.addAsSingletonList(text: E) { add(Collections.singletonList(text)) } + + // (key -> value) -> (sorting value -> key item icon) + fun fillTable(list: MutableList<List<Any>>, data: MutableMap<Pair<String, String>, Pair<Double, String>>) { + val keys = data.mapValues { (_, v) -> v.first }.sortedDesc().keys + val renderer = Minecraft.getMinecraft().fontRendererObj + val longest = keys.map { it.first }.maxOfOrNull { renderer.getStringWidth(it.removeColor()) } ?: 0 + + for (pair in keys) { + val (name, second) = pair + var displayName = name + while (renderer.getStringWidth(displayName.removeColor()) < longest) { + displayName += " " + } + + NEUItems.getItemStackOrNull(data[pair]!!.second)?.let { + list.add(listOf(it, "$displayName $second")) + } + } + } }
\ No newline at end of file |