diff --git a/.idea/dictionaries/default_user.xml b/.idea/dictionaries/default_user.xml
index 29903e6587fb..b166e60d38fd 100644
--- a/.idea/dictionaries/default_user.xml
+++ b/.idea/dictionaries/default_user.xml
@@ -243,6 +243,7 @@
statspocalypse
stillgore
stonk
+ stonks
superboom
supercraft
supercrafting
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java
index a3f88fca6473..0c7556c30719 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/inventory/InventoryConfig.java
@@ -257,4 +257,10 @@ public String toString() {
@ConfigEditorBoolean
@FeatureToggle
public boolean timeHeldInLore = false;
+
+ @Expose
+ @ConfigOption(name = "Stonk of Stonk Price", desc = "Show Price per Stonk when taking the minimum bid in Stonks Auction (Richard).")
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean stonkOfStonkPrice = true;
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/StockOfStonkFeature.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/StockOfStonkFeature.kt
new file mode 100644
index 000000000000..4bc8af1e3e56
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/StockOfStonkFeature.kt
@@ -0,0 +1,100 @@
+package at.hannibal2.skyhanni.features.inventory
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.InventoryCloseEvent
+import at.hannibal2.skyhanni.events.InventoryOpenEvent
+import at.hannibal2.skyhanni.events.LorenzToolTipEvent
+import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
+import at.hannibal2.skyhanni.utils.CollectionUtils.transformAt
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.RegexUtils.matches
+import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+@SkyHanniModule
+object StockOfStonkFeature {
+
+ private val config get() = SkyHanniMod.feature.inventory
+
+ private val repoGroup = RepoPattern.group("inventory.stockofstonks")
+
+
+ /**
+ * REGEX-TEST: Stonks Auction
+ */
+ private val inventoryPattern by repoGroup.pattern(
+ "inventory",
+ "Stonks Auction",
+ )
+
+ /**
+ * REGEX-TEST: §dStonks Auction
+ */
+ private val itemPattern by repoGroup.pattern(
+ "item",
+ "§dStonks Auction",
+ )
+
+ /**
+ * REGEX-TEST: §5§o§7§7▶ §c§lTOP 5,000§7 - §5Stock of Stonks §8x2
+ */
+ private val topPattern by repoGroup.pattern(
+ "top",
+ "§5§o§7§7▶ §c§lTOP (?[\\d,]+)§7 - §5Stock of Stonks §8x(?\\d+)",
+ )
+
+ /**
+ * REGEX-TEST: §5§o§7 Minimum Bid: §62,400,002 Coins
+ */
+ private val bidPattern by repoGroup.pattern(
+ "bid",
+ "§5§o§7 Minimum Bid: §6(?[\\d,]+) Coins",
+ )
+
+ var inInventory = false
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryOpenEvent) {
+ if (isEnabled()) {
+ inInventory = inventoryPattern.matches(event.inventoryName)
+ }
+ }
+
+ @SubscribeEvent
+ fun onInventoryClose(event: InventoryCloseEvent) {
+ inInventory = false
+ }
+
+ @SubscribeEvent
+ fun onLorenzToolTip(event: LorenzToolTipEvent) {
+ if (!isEnabled()) return
+ if (!inInventory) return
+ if (!itemPattern.matches(event.itemStack.displayName)) return
+ var stonksReward = 0
+ var index = 0
+ var bestValueIndex = 0
+ var bestRatio = Long.MAX_VALUE
+ loop@ while (index < event.toolTip.size) {
+ val line = event.toolTip[index]
+ index++
+ topPattern.matchMatcher(line) {
+ stonksReward = group("amount").toInt()
+ continue@loop
+ }
+ bidPattern.matchMatcher(line) {
+ val cost = group("amount").replace(",", "").toLong()
+ val ratio = cost / stonksReward
+ event.toolTip[index - 1] = line + " §7(§6§6${ratio.addSeparators()} §7per)" // double §6 for the replacement at the end
+ if (ratio < bestRatio) {
+ bestValueIndex = index - 1
+ bestRatio = ratio
+ }
+ }
+ }
+ event.toolTip.transformAt(bestValueIndex) { replace("§6§6", "§a") }
+ }
+
+ private fun isEnabled() = LorenzUtils.inSkyBlock && config.stonkOfStonkPrice
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
index 80aa131b2b78..33e85e2fe019 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
@@ -143,6 +143,11 @@ object CollectionUtils {
return newList
}
+ inline fun > K.transformAt(index: Int, transform: T.() -> T): K {
+ this[index] = transform(this[index])
+ return this
+ }
+
/**
* This does not work inside a [buildList] block
*/