From fcfad35d6f8b42c963914c7e83a1fe219095c59c Mon Sep 17 00:00:00 2001 From: Appability Date: Thu, 21 Dec 2023 19:40:35 -0800 Subject: [PATCH] improve composter empty time precision --- .../features/garden/composter/ComposterAPI.kt | 37 +++++++++++++++++++ .../garden/composter/ComposterDisplay.kt | 25 +------------ .../hannibal2/skyhanni/utils/StringUtils.kt | 6 +++ 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt index 50efa9e42e30..c9a362e437f5 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterAPI.kt @@ -4,6 +4,8 @@ import at.hannibal2.skyhanni.data.model.ComposterUpgrade import at.hannibal2.skyhanni.features.garden.GardenAPI import at.hannibal2.skyhanni.utils.NumberUtil.formatNumber import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import at.hannibal2.skyhanni.utils.TimeUtils +import kotlin.math.floor import kotlin.time.Duration import kotlin.time.Duration.Companion.minutes @@ -14,6 +16,41 @@ object ComposterAPI { fun ComposterUpgrade.getLevel(addOne: ComposterUpgrade?) = (composterUpgrades?.get(this) ?: 0) + if (addOne == this) 1 else 0 + fun estimateEmptyTimeFromTab(): Duration? { + if (composterUpgrades.isNullOrEmpty()) { + return null + } + + val nextCompostTime = tabListData[ComposterDisplay.DataType.TIME_LEFT]?.removeColor()?.let { + if (it != "INACTIVE") TimeUtils.getDuration(it) else null + } ?: Duration.ZERO + + val timePerCompost = timePerCompost(null) + val fractionRemaining = nextCompostTime / timePerCompost + + val remainingTimeByOrganicMatter = getDurationUntilEndOfResource( + getOrganicMatter(), fractionRemaining, organicMatterRequiredPer(null), timePerCompost + ) + + val remainingTimeByFuel = getDurationUntilEndOfResource( + getFuel(), fractionRemaining, fuelRequiredPer(null), timePerCompost + ) + + return nextCompostTime + minOf(remainingTimeByOrganicMatter, remainingTimeByFuel) + } + + private fun getDurationUntilEndOfResource( + amount: Long, + fractionOfCompostRemaining: Double, + requiredPer: Double, + timePerCompost: Duration + ): Duration { + val resourceConsumedByNextCompost = fractionOfCompostRemaining * requiredPer + val resourceRemainingAfterNextCompostFinishes = amount - resourceConsumedByNextCompost + val compostRemainingAfterNextCompostFinishes = floor(resourceRemainingAfterNextCompostFinishes / requiredPer) + return timePerCompost * compostRemainingAfterNextCompostFinishes + } + fun getFuel() = tabListData[ComposterDisplay.DataType.FUEL]?.removeColor()?.formatNumber() ?: 0 fun getOrganicMatter() = tabListData[ComposterDisplay.DataType.ORGANIC_MATTER]?.removeColor()?.formatNumber() ?: 0 diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt index cf06da7f6c6c..04e2bee61444 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/composter/ComposterDisplay.kt @@ -12,7 +12,6 @@ import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.TimeUtils import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import java.util.Collections -import kotlin.math.floor import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds import kotlin.time.DurationUnit @@ -49,34 +48,12 @@ class ComposterDisplay { readData(event.tabList) if (tabListData.isNotEmpty()) { - calculateEmptyTime() + composterEmptyTime = ComposterAPI.estimateEmptyTimeFromTab() updateDisplay() sendNotify() } } - private fun calculateEmptyTime() { - val organicMatter = ComposterAPI.getOrganicMatter() - val fuel = ComposterAPI.getFuel() - - if (ComposterAPI.composterUpgrades.isNullOrEmpty()) { - composterEmptyTime = null - return - } - - val timePerCompost = ComposterAPI.timePerCompost(null) - - val organicMatterRequired = ComposterAPI.organicMatterRequiredPer(null) - val fuelRequired = ComposterAPI.fuelRequiredPer(null) - - val organicMatterRemaining = floor(organicMatter / organicMatterRequired) - val fuelRemaining = floor(fuel / fuelRequired) - - val endOfOrganicMatter = timePerCompost * organicMatterRemaining - val endOfFuel = timePerCompost * fuelRemaining - composterEmptyTime = if (endOfOrganicMatter > endOfFuel) endOfFuel else endOfOrganicMatter - } - private fun updateDisplay() { val newDisplay = mutableListOf>() newDisplay.addAsSingletonList("§bComposter") diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt index a9ac0ca82d74..9ac80f7f3bbe 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt @@ -38,6 +38,12 @@ object StringUtils { private val formattingChars by lazy { "kmolnr".toCharArray() + "kmolnr".uppercase().toCharArray() } + /** + * Removes color and optionally formatting codes from the given string, leaving plain text. + * + * @param keepFormatting Boolean indicating whether to retain non-color formatting codes (default: false). + * @return A string with color codes removed (and optionally formatting codes if specified). + */ fun String.removeColor(keepFormatting: Boolean = false): String { val builder = StringBuilder(this.length)