aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-01-15 00:32:43 +0100
committerLinnea Gräf <nea@nea.moe>2024-01-17 21:10:51 +0100
commitac151c8ebc4c5546795cdbf5b0c179183e2c71d1 (patch)
tree52141110008ba6809d0dde5bc4456fc37e6a665a /src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt
parentc49b65835d37266508561e60782bda36275fb8ae (diff)
downloadFirmament-ac151c8ebc4c5546795cdbf5b0c179183e2c71d1.tar.gz
Firmament-ac151c8ebc4c5546795cdbf5b0c179183e2c71d1.tar.bz2
Firmament-ac151c8ebc4c5546795cdbf5b0c179183e2c71d1.zip
Add Pristine Profit Tracker
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt')
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt b/src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt
new file mode 100644
index 0000000..294c835
--- /dev/null
+++ b/src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt
@@ -0,0 +1,140 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package moe.nea.firmament.features.mining
+
+import io.github.moulberry.moulconfig.xml.Bind
+import moe.nea.jarvis.api.Point
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.serializer
+import kotlin.time.Duration.Companion.seconds
+import net.minecraft.text.Text
+import moe.nea.firmament.events.ProcessChatEvent
+import moe.nea.firmament.features.FirmamentFeature
+import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.gui.hud.MoulConfigHud
+import moe.nea.firmament.util.BazaarPriceStrategy
+import moe.nea.firmament.util.FirmFormatters.formatCurrency
+import moe.nea.firmament.util.SkyblockId
+import moe.nea.firmament.util.data.ProfileSpecificDataHolder
+import moe.nea.firmament.util.formattedString
+import moe.nea.firmament.util.parseIntWithComma
+import moe.nea.firmament.util.useMatch
+
+object PristineProfitTracker : FirmamentFeature {
+ override val identifier: String
+ get() = "pristine-profit"
+
+ enum class GemstoneKind(
+ val label: String,
+ val flawedId: SkyblockId,
+ ) {
+ SAPPHIRE("Sapphire", SkyblockId("FLAWED_SAPPHIRE_GEM")),
+ RUBY("Ruby", SkyblockId("FLAWED_RUBY_GEM")),
+ AMETHYST("Amethyst", SkyblockId("FLAWED_AMETHYST_GEM")),
+ AMBER("Amber", SkyblockId("FLAWED_AMBER_GEM")),
+ TOPAZ("Topaz", SkyblockId("FLAWED_TOPAZ_GEM")),
+ JADE("Jade", SkyblockId("FLAWED_JADE_GEM")),
+ JASPER("Jasper", SkyblockId("FLAWED_JASPER_GEM")),
+ OPAL("Opal", SkyblockId("FLAWED_OPAL_GEM")),
+ }
+
+ @Serializable
+ data class Data(
+ var maxMoneyPerSecond: Double = 1.0,
+ var maxCollectionPerSecond: Double = 1.0,
+ )
+
+ object DConfig : ProfileSpecificDataHolder<Data>(serializer(), identifier, ::Data)
+
+ override val config: ManagedConfig?
+ get() = TConfig
+
+ object TConfig : ManagedConfig(identifier) {
+ val timeout by duration("timeout", 0.seconds, 120.seconds) { 30.seconds }
+ val gui by position("position", 80, 30) { Point(0.05, 0.2) }
+ }
+
+ val sellingStrategy = BazaarPriceStrategy.SELL_ORDER
+
+ val pristineRegex =
+ "PRISTINE! You found . Flawed (?<kind>${
+ GemstoneKind.values().joinToString("|") { it.label }
+ }) Gemstone x(?<count>[0-9,]+)!".toPattern()
+
+ val collectionHistogram = Histogram<Double>(10000, 180.seconds)
+ val moneyHistogram = Histogram<Double>(10000, 180.seconds)
+
+ object ProfitHud : MoulConfigHud("pristine_profit", TConfig.gui) {
+ @field:Bind
+ var moneyCurrent: Double = 0.0
+
+ @field:Bind
+ var moneyMax: Double = 1.0
+
+ @field:Bind
+ var moneyText = ""
+
+ @field:Bind
+ var collectionCurrent = 0.0
+
+ @field:Bind
+ var collectionMax = 1.0
+
+ @field:Bind
+ var collectionText = ""
+ override fun shouldRender(): Boolean = collectionHistogram.latestUpdate().passedTime() < TConfig.timeout
+ }
+
+ val SECONDS_PER_HOUR = 3600
+ val ROUGHS_PER_FLAWED = 80
+
+ fun updateUi() {
+ val collectionPerSecond = collectionHistogram.averagePer({ it }, 1.seconds)
+ val moneyPerSecond = moneyHistogram.averagePer({ it }, 1.seconds)
+ if (collectionPerSecond == null || moneyPerSecond == null) return
+ ProfitHud.collectionCurrent = collectionPerSecond
+ ProfitHud.collectionText = Text.translatable(
+ "firmament.pristine-profit.collection",
+ formatCurrency(collectionPerSecond * SECONDS_PER_HOUR, 1)
+ ).formattedString()
+ ProfitHud.moneyCurrent = moneyPerSecond
+ ProfitHud.moneyText = Text.translatable(
+ "firmament.pristine-profit.money",
+ formatCurrency(moneyPerSecond * SECONDS_PER_HOUR, 1)
+ ).formattedString()
+ val data = DConfig.data
+ if (data != null) {
+ if (data.maxCollectionPerSecond < collectionPerSecond && collectionHistogram.oldestUpdate()
+ .passedTime() > 30.seconds
+ ) {
+ data.maxCollectionPerSecond = collectionPerSecond
+ DConfig.markDirty()
+ }
+ if (data.maxMoneyPerSecond < moneyPerSecond && moneyHistogram.oldestUpdate().passedTime() > 30.seconds) {
+ data.maxMoneyPerSecond = moneyPerSecond
+ DConfig.markDirty()
+ }
+ ProfitHud.collectionMax = maxOf(data.maxCollectionPerSecond, collectionPerSecond)
+ ProfitHud.moneyMax = maxOf(data.maxMoneyPerSecond, moneyPerSecond)
+ }
+ }
+
+
+ override fun onLoad() {
+ ProcessChatEvent.subscribe {
+ pristineRegex.useMatch(it.unformattedString) {
+ val gemstoneKind = GemstoneKind.valueOf(group("kind").uppercase())
+ val flawedCount = parseIntWithComma(group("count"))
+ val moneyAmount = sellingStrategy.getSellPrice(gemstoneKind.flawedId) * flawedCount
+ moneyHistogram.record(moneyAmount)
+ val collectionAmount = flawedCount * ROUGHS_PER_FLAWED
+ collectionHistogram.record(collectionAmount.toDouble())
+ updateUi()
+ }
+ }
+ }
+}