aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorCalMWolfs <94038482+CalMWolfs@users.noreply.github.com>2024-04-29 23:57:59 +1000
committerGitHub <noreply@github.com>2024-04-29 15:57:59 +0200
commita5a77b601c7d82661206b0b3437fe2d09e660587 (patch)
treef257203d48ebb4e03de357ca8b6d8d08fb1bfd88 /src/main/java
parentf6d67a178a84a151a434120f1005306b98e957b9 (diff)
downloadskyhanni-a5a77b601c7d82661206b0b3437fe2d09e660587.tar.gz
skyhanni-a5a77b601c7d82661206b0b3437fe2d09e660587.tar.bz2
skyhanni-a5a77b601c7d82661206b0b3437fe2d09e660587.zip
Improvement: Add time until next prestige (#1514)
Co-authored-by: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Co-authored-by: SeRaid <77941535+SeRaid743@users.noreply.github.com>
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/event/ChocolateFactoryConfig.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java27
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateAmount.kt40
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryAPI.kt54
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryInventory.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryStats.kt34
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryTimeTowerManager.kt17
8 files changed, 172 insertions, 33 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt
index 1e8a576e2..9a08a2385 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt
@@ -12,7 +12,7 @@ import com.google.gson.JsonPrimitive
object ConfigUpdaterMigrator {
val logger = LorenzLogger("ConfigMigration")
- const val CONFIG_VERSION = 41
+ const val CONFIG_VERSION = 42
fun JsonElement.at(chain: List<String>, init: Boolean): JsonElement? {
if (chain.isEmpty()) return this
if (this !is JsonObject) return null
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/ChocolateFactoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/ChocolateFactoryConfig.java
index f2ca55a55..d67838532 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/event/ChocolateFactoryConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/ChocolateFactoryConfig.java
@@ -45,6 +45,7 @@ public class ChocolateFactoryConfig {
ChocolateFactoryStat.CURRENT,
ChocolateFactoryStat.THIS_PRESTIGE,
ChocolateFactoryStat.ALL_TIME,
+ ChocolateFactoryStat.TIME_TO_PRESTIGE,
ChocolateFactoryStat.EMPTY,
ChocolateFactoryStat.PER_SECOND,
ChocolateFactoryStat.PER_MINUTE,
@@ -106,11 +107,11 @@ public class ChocolateFactoryConfig {
@Expose
@ConfigLink(owner = ChocolateFactoryConfig.class, field = "statsDisplay")
- public Position position = new Position(183, 160, false, true);
+ public Position position = new Position(163, 160, false, true);
@Expose
@ConfigLink(owner = ChocolateFactoryConfig.class, field = "hoppityCollectionStats")
- public Position hoppityStatsPosition = new Position(183, 160, false, true);
+ public Position hoppityStatsPosition = new Position(163, 160, false, true);
@Expose
@ConfigOption(name = "Compact On Click", desc = "Compact the item toolip when clicking on the chocolate.")
diff --git a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java
index 12861986e..a353bd88a 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java
@@ -57,6 +57,30 @@ public class ProfileSpecificStorage {
public int maxRabbits = -1;
@Expose
+ public long currentChocolate = 0;
+
+ @Expose
+ public long chocolateThisPrestige = 0;
+
+ @Expose
+ public long chocolateAllTime = 0;
+
+ @Expose
+ public int rawChocPerSecond = 0;
+
+ @Expose
+ public double chocolateMultiplier = 1.0;
+
+ @Expose
+ public double rawChocolateMultiplier = 1.0;
+
+ @Expose
+ public int timeTowerLevel = 0;
+
+ @Expose
+ public long currentTimeTowerEnds = 0;
+
+ @Expose
public long nextTimeTower = 0;
@Expose
@@ -64,6 +88,9 @@ public class ProfileSpecificStorage {
@Expose
public int maxTimeTowerUses = 3;
+
+ @Expose
+ public long lastDataSave = 0;
}
@Expose
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateAmount.kt b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateAmount.kt
new file mode 100644
index 000000000..230799df0
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateAmount.kt
@@ -0,0 +1,40 @@
+package at.hannibal2.skyhanni.features.event.chocolatefactory
+
+import at.hannibal2.skyhanni.features.event.chocolatefactory.ChocolateFactoryAPI.profileStorage
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.seconds
+
+enum class ChocolateAmount(val chocolate: () -> Long) {
+ CURRENT({ profileStorage?.currentChocolate ?: 0 }),
+ PRESTIGE({ profileStorage?.chocolateThisPrestige ?: 0 }),
+ ALL_TIME({ profileStorage?.chocolateAllTime ?: 0 }),
+ ;
+
+ val formatted get(): String = chocolate().addSeparators()
+
+ fun timeUntilGoal(goal: Long): Duration {
+ val profileStorage = ChocolateFactoryAPI.profileStorage ?: return Duration.ZERO
+
+ val updatedAgo = SimpleTimeMark(profileStorage.lastDataSave).passedSince().inWholeSeconds
+
+ val baseMultiplier = profileStorage.rawChocolateMultiplier
+ val baseChocolatePerSecond = profileStorage.rawChocPerSecond
+ val timeTowerMultiplier = baseMultiplier + profileStorage.timeTowerLevel * 0.1
+
+ var needed = goal - chocolate()
+ val secondsUntilTowerExpires = ChocolateFactoryTimeTowerManager.timeTowerActiveDuration().inWholeSeconds
+
+ val timeTowerChocPerSecond = baseChocolatePerSecond * timeTowerMultiplier
+
+ val secondsAtRate = needed / timeTowerChocPerSecond
+ if (secondsAtRate < secondsUntilTowerExpires) {
+ return secondsAtRate.seconds - updatedAgo.seconds
+ }
+
+ needed -= (secondsUntilTowerExpires * timeTowerChocPerSecond).toLong()
+ val chocPerSecond = baseChocolatePerSecond * baseMultiplier
+ return (needed / chocPerSecond + secondsUntilTowerExpires).seconds - updatedAgo.seconds
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryAPI.kt
index 53c003663..84bce4b3d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryAPI.kt
@@ -68,6 +68,10 @@ object ChocolateFactoryAPI {
"prestige.level",
"§6Chocolate Factory (?<prestige>[IVX]+)"
)
+ private val chocolateForPrestigePattern by patternGroup.pattern(
+ "chocolate.forprestige",
+ "§7§cRequires (?<amount>\\w+) Chocolate this.*"
+ )
private val clickMeRabbitPattern by patternGroup.pattern(
"rabbit.clickme",
"§e§lCLICK ME!"
@@ -86,7 +90,7 @@ object ChocolateFactoryAPI {
)
private val timeTowerStatusPattern by patternGroup.pattern(
"timetower.status",
- "§7Status: §.§l(?<status>INACTIVE|ACTIVE).*"
+ "§7Status: §.§l(?<status>INACTIVE|ACTIVE)(?: §f)?(?<acitveTime>\\w*)"
)
private val timeTowerRechargePattern by patternGroup.pattern(
"timetower.recharge",
@@ -102,20 +106,16 @@ object ChocolateFactoryAPI {
private var prestigeIndex = 28
var milestoneIndex = 53
private var leaderboardIndex = 51
- private var timeTowerIndex = 39
+ var timeTowerIndex = 39
var maxRabbits = 395
var inChocolateFactory = false
- var currentPrestige = 0
- var chocolateCurrent = 0L
- var chocolateAllTime = 0L
+ var currentPrestige = 1
var chocolatePerSecond = 0.0
- var chocolateThisPrestige = 0L
- var chocolateMultiplier = 1.0
var leaderboardPosition: Int? = null
var leaderboardPercentile: Double? = null
- var timeTowerActive = false
+ var chocolateForPrestige = 150_000_000L
val upgradeableSlots: MutableSet<Int> = mutableSetOf()
var bestUpgrade: Int? = null
@@ -165,7 +165,7 @@ object ChocolateFactoryAPI {
val lore = item.getLore()
val upgradeCost = lore.getUpgradeCost() ?: continue
- val canAfford = upgradeCost <= chocolateCurrent
+ val canAfford = upgradeCost <= ChocolateAmount.CURRENT.chocolate()
if (canAfford) upgradeableSlots.add(slotIndex)
if (slotIndex in rabbitSlots) {
@@ -194,30 +194,40 @@ object ChocolateFactoryAPI {
) {
val profileStorage = profileStorage ?: return
- chocolateMultiplier = 1.0
- timeTowerActive = false
leaderboardPosition = null
leaderboardPercentile = null
chocolateAmountPattern.matchMatcher(chocolateItem.name.removeColor()) {
- chocolateCurrent = group("amount").formatLong()
+ profileStorage.currentChocolate = group("amount").formatLong()
}
for (line in chocolateItem.getLore()) {
chocolatePerSecondPattern.matchMatcher(line) {
chocolatePerSecond = group("amount").formatDouble()
}
chocolateAllTimePattern.matchMatcher(line) {
- chocolateAllTime = group("amount").formatLong()
+ profileStorage.chocolateAllTime = group("amount").formatLong()
}
}
prestigeLevelPattern.matchMatcher(prestigeItem.name) {
currentPrestige = group("prestige").romanToDecimal()
}
- prestigeItem.getLore().matchFirst(chocolateThisPrestigePattern) {
- chocolateThisPrestige = group("amount").formatLong()
+ for (line in prestigeItem.getLore()) {
+ chocolateThisPrestigePattern.matchMatcher(line) {
+ profileStorage.chocolateThisPrestige = group("amount").formatLong()
+ }
+ chocolateForPrestigePattern.matchMatcher(line) {
+ chocolateForPrestige = group("amount").formatLong()
+ }
}
productionItem.getLore().matchFirst(chocolateMultiplierPattern) {
- chocolateMultiplier = group("amount").formatDouble()
+ val currentMultiplier = group("amount").formatDouble()
+ profileStorage.chocolateMultiplier = currentMultiplier
+
+ if (ChocolateFactoryTimeTowerManager.timeTowerActive()) {
+ profileStorage.rawChocolateMultiplier = currentMultiplier - profileStorage.timeTowerLevel * 0.1
+ } else {
+ profileStorage.rawChocolateMultiplier = currentMultiplier
+ }
}
for (line in leaderboardItem.getLore()) {
leaderboardPlacePattern.matchMatcher(line) {
@@ -239,7 +249,15 @@ object ChocolateFactoryAPI {
ChocolateFactoryTimeTowerManager.checkTimeTowerWarning(true)
}
timeTowerStatusPattern.matchMatcher(line) {
- timeTowerActive = group("status") == "ACTIVE"
+ val activeTime = group("acitveTime")
+ if (activeTime.isNotEmpty()) {
+ // todo in future fix this issue with TimeUtils.getDuration
+ val formattedGroup = activeTime.replace("h", "h ").replace("m", "m ")
+
+ val activeDuration = TimeUtils.getDuration(formattedGroup)
+ val activeUntil = SimpleTimeMark.now() + activeDuration
+ profileStorage.currentTimeTowerEnds = activeUntil.toMillis()
+ }
}
timeTowerRechargePattern.matchMatcher(line) {
// todo in future fix this issue with TimeUtils.getDuration
@@ -250,6 +268,8 @@ object ChocolateFactoryAPI {
profileStorage.nextTimeTower = nextTimeTower.toMillis()
}
}
+ profileStorage.rawChocPerSecond = (chocolatePerSecond / profileStorage.chocolateMultiplier).toInt()
+ profileStorage.lastDataSave = SimpleTimeMark.now().toMillis()
if (!config.statsDisplay) return
ChocolateFactoryStats.updateDisplay()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryInventory.kt b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryInventory.kt
index bad268f96..b62d437ad 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryInventory.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryInventory.kt
@@ -19,6 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object ChocolateFactoryInventory {
private val config get() = ChocolateFactoryAPI.config
+ private val profileStorage get() = ChocolateFactoryAPI.profileStorage
private val rabbitAmountPattern by ChocolateFactoryAPI.patternGroup.pattern(
"rabbit.amount",
@@ -64,6 +65,19 @@ object ChocolateFactoryInventory {
if (slot.slotIndex == ChocolateFactoryAPI.clickRabbitSlot) {
slot highlight LorenzColor.RED
}
+ if (slot.slotIndex == ChocolateFactoryAPI.milestoneIndex) {
+ slot.stack?.getLore()?.matchFirst(unclaimedRewardsPattern) {
+ slot highlight LorenzColor.RED
+ }
+ }
+ if (slot.slotIndex == ChocolateFactoryAPI.timeTowerIndex) {
+ if (ChocolateFactoryTimeTowerManager.timeTowerActive()) {
+ slot highlight LorenzColor.LIGHT_PURPLE
+ }
+ if (ChocolateFactoryTimeTowerManager.timeTowerFull()) {
+ slot highlight LorenzColor.RED
+ }
+ }
}
}
@@ -71,6 +85,7 @@ object ChocolateFactoryInventory {
fun onRenderItemTip(event: RenderInventoryItemTipEvent) {
if (!ChocolateFactoryAPI.inChocolateFactory) return
if (!config.showStackSizes) return
+ val profileStorage = profileStorage ?: return
val item = event.stack
val itemName = item.name.removeColor()
@@ -93,12 +108,11 @@ object ChocolateFactoryInventory {
}
if (slotNumber in ChocolateFactoryAPI.otherUpgradeSlots) {
upgradeTierPattern.matchMatcher(itemName) {
- event.stackTip = group("tier").romanToDecimal().toString()
- }
- }
- if (slotNumber == ChocolateFactoryAPI.milestoneIndex) {
- item.getLore().matchFirst(unclaimedRewardsPattern) {
- event.stackTip = "§c!!!"
+ val level = group("tier").romanToDecimal()
+
+ if (slotNumber == ChocolateFactoryAPI.timeTowerIndex) profileStorage.timeTowerLevel = level
+
+ event.stackTip = level.toString()
}
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryStats.kt b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryStats.kt
index ac16b7b14..08de9fbf6 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryStats.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryStats.kt
@@ -1,13 +1,17 @@
package at.hannibal2.skyhanni.features.event.chocolatefactory
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
+import at.hannibal2.skyhanni.utils.TimeUtils.format
+import com.google.gson.JsonPrimitive
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object ChocolateFactoryStats {
private val config get() = ChocolateFactoryAPI.config
+ private val profileStorage get() = ChocolateFactoryAPI.profileStorage
private var displayList = listOf<String>()
@@ -20,31 +24,35 @@ object ChocolateFactoryStats {
}
fun updateDisplay() {
+ val profileStorage = profileStorage ?: return
+
val perSecond = ChocolateFactoryAPI.chocolatePerSecond
val perMinute = perSecond * 60
val perHour = perMinute * 60
val perDay = perHour * 24
val position = ChocolateFactoryAPI.leaderboardPosition?.addSeparators() ?: "???"
val percentile = ChocolateFactoryAPI.leaderboardPercentile?.let { "§7Top §a$it%" } ?: ""
- val timeTowerInfo = if (ChocolateFactoryAPI.timeTowerActive) {
+ val timeTowerInfo = if (ChocolateFactoryTimeTowerManager.timeTowerActive()) {
"§d§lActive"
} else {
"§6${ChocolateFactoryTimeTowerManager.timeTowerCharges()}"
}
+ val timeUntilPrestige = ChocolateAmount.PRESTIGE.timeUntilGoal(ChocolateFactoryAPI.chocolateForPrestige)
+
displayList = formatList(buildList {
add("§6§lChocolate Factory Stats")
- add("§eCurrent Chocolate: §6${ChocolateFactoryAPI.chocolateCurrent.addSeparators()}")
- add("§eThis Prestige: §6${ChocolateFactoryAPI.chocolateThisPrestige.addSeparators()}")
- add("§eAll-time: §6${ChocolateFactoryAPI.chocolateAllTime.addSeparators()}")
+ add("§eCurrent Chocolate: §6${ChocolateAmount.CURRENT.formatted}")
+ add("§eThis Prestige: §6${ChocolateAmount.PRESTIGE.formatted}")
+ add("§eAll-time: §6${ChocolateAmount.ALL_TIME.formatted}")
add("§ePer Second: §6${perSecond.addSeparators()}")
add("§ePer Minute: §6${perMinute.addSeparators()}")
add("§ePer Hour: §6${perHour.addSeparators()}")
add("§ePer Day: §6${perDay.addSeparators()}")
- add("§eChocolate Multiplier: §6${ChocolateFactoryAPI.chocolateMultiplier}")
+ add("§eChocolate Multiplier: §6${profileStorage.chocolateMultiplier}")
add("§eBarn: §6${ChocolateFactoryBarnManager.barnStatus()}")
add("§ePosition: §7#§b$position $percentile")
@@ -54,6 +62,8 @@ object ChocolateFactoryStats {
add("")
add("§eTime Tower: §6$timeTowerInfo")
+ add("§eTime To Prestige: §6${timeUntilPrestige.format()}")
+ add("§eRaw Per Second: §6${profileStorage.rawChocPerSecond.addSeparators()}")
})
}
@@ -63,6 +73,18 @@ object ChocolateFactoryStats {
.map { list[it.ordinal] }
}
+ @SubscribeEvent
+ fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.transform(42, "event.chocolateFactory.statsDisplayList") { element ->
+ val jsonArray = element.asJsonArray
+
+ jsonArray.add(JsonPrimitive("TIME_TOWER"))
+ jsonArray.add(JsonPrimitive("TIME_TO_PRESTIGE"))
+
+ jsonArray
+ }
+ }
+
enum class ChocolateFactoryStat(private val display: String, val shouldDisplay: () -> Boolean = { true }) {
HEADER("§6§lChocolate Factory Stats"),
CURRENT("§eCurrent Chocolate: §65,272,230"),
@@ -79,6 +101,8 @@ object ChocolateFactoryStats {
EMPTY_2(""),
EMPTY_3(""),
TIME_TOWER("§eTime Tower: §62/3 Charges", { ChocolateFactoryTimeTowerManager.currentCharges() != -1 }),
+ TIME_TO_PRESTIGE("§eTime To Prestige: §61d 13h 59m 4s", { ChocolateFactoryAPI.currentPrestige != 5 }),
+ RAW_PER_SECOND("§eRaw Per Second: §62,136"),
;
override fun toString(): String {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryTimeTowerManager.kt b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryTimeTowerManager.kt
index 28f601b66..55390605d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryTimeTowerManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryTimeTowerManager.kt
@@ -9,6 +9,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.SoundUtils
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import kotlin.time.Duration
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
@@ -23,9 +24,14 @@ object ChocolateFactoryTimeTowerManager {
@SubscribeEvent
fun onSecondPassed(event: SecondPassedEvent) {
if (!LorenzUtils.inSkyBlock) return
- if (ChocolateFactoryAPI.inChocolateFactory) return
val profileStorage = profileStorage ?: return
+ if (SimpleTimeMark(profileStorage.currentTimeTowerEnds).isInPast()) {
+ profileStorage.currentTimeTowerEnds = SimpleTimeMark.farPast().toMillis()
+ }
+
+ if (ChocolateFactoryAPI.inChocolateFactory) return
+
val nextCharge = SimpleTimeMark(profileStorage.nextTimeTower)
if (nextCharge.isInPast() && !nextCharge.isFarPast() && currentCharges() < maxCharges()) {
@@ -82,7 +88,14 @@ object ChocolateFactoryTimeTowerManager {
return profileStorage?.maxTimeTowerUses ?: 3
}
- private fun timeTowerFull() = currentCharges() >= maxCharges()
+ fun timeTowerFull() = currentCharges() >= maxCharges()
+
+ fun timeTowerActive() = profileStorage?.currentTimeTowerEnds != 0L
+
+ fun timeTowerActiveDuration(): Duration {
+ if (!timeTowerActive()) return Duration.ZERO
+ return SimpleTimeMark(profileStorage?.currentTimeTowerEnds ?: 0).timeUntil()
+ }
@SubscribeEvent
fun onProfileChange(event: ProfileJoinEvent) {