aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--FEATURES.md1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Garden.java20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt141
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextPlotPrice.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt7
-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.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt19
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