From 3708ea6a83c39badad3486143572949d1933dfe6 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Tue, 10 Sep 2024 20:40:01 +0200 Subject: Improvement: Add per election year diana trackers (#2487) Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> --- .../config/storage/ProfileSpecificStorage.java | 6 +++ .../java/at/hannibal2/skyhanni/data/MayorAPI.kt | 20 ++++++---- .../features/event/diana/DianaProfitTracker.kt | 8 ++++ .../event/diana/MythologicalCreatureTracker.kt | 12 +++++- .../at/hannibal2/skyhanni/utils/CollectionUtils.kt | 43 ++++++++++----------- .../skyhanni/utils/tracker/SkyHanniItemTracker.kt | 8 ++-- .../skyhanni/utils/tracker/SkyHanniTracker.kt | 45 ++++++++++++++-------- 7 files changed, 90 insertions(+), 52 deletions(-) (limited to 'src/main/java') 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 bb023f230..d622d317a 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java @@ -646,9 +646,15 @@ public class ProfileSpecificStorage { // TODO rename to 'profitTracker' public DianaProfitTracker.Data dianaProfitTracker = new DianaProfitTracker.Data(); + @Expose + public Map dianaProfitTrackerPerElectionSeason = new HashMap<>(); + @Expose // TODO rename public MythologicalCreatureTracker.Data mythologicalMobTracker = new MythologicalCreatureTracker.Data(); + + @Expose + public Map mythologicalMobTrackerPerElectionSeason = new HashMap<>(); } @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/data/MayorAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/MayorAPI.kt index 2f89b340b..b4fb7eaa2 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/MayorAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/MayorAPI.kt @@ -186,17 +186,21 @@ object MayorAPI { jerryExtraMayor = jerryMayor to expireTime } - private fun calculateNextMayorTime(): SimpleTimeMark { - val now = SkyBlockTime.now() - var mayorYear = now.year + fun SkyBlockTime.getElectionYear(): Int { + var mayorYear = year - // Check if either the month is already over or the day after 27th in the third month - if (now.month > ELECTION_END_MONTH || (now.day >= ELECTION_END_DAY && now.month == ELECTION_END_MONTH)) { - // If so, the next mayor will be in the next year - mayorYear++ + // Check if this year's election has not happened yet + if (month < ELECTION_END_MONTH || (day < ELECTION_END_DAY && month == ELECTION_END_MONTH)) { + // If so, the current mayor is still from last year's election + mayorYear-- } + return mayorYear + } + + private fun calculateNextMayorTime(): SimpleTimeMark { + val now = SkyBlockTime.now() - return SkyBlockTime(mayorYear, ELECTION_END_MONTH, day = ELECTION_END_DAY).asTimeMark() + return SkyBlockTime(now.getElectionYear() + 1, ELECTION_END_MONTH, day = ELECTION_END_DAY).asTimeMark() } private fun getTimeTillNextMayor() { diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaProfitTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaProfitTracker.kt index ade5966ea..b6ec4d0a6 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaProfitTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaProfitTracker.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.event.diana import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.data.ItemAddManager +import at.hannibal2.skyhanni.data.MayorAPI.getElectionYear import at.hannibal2.skyhanni.data.jsonobjects.repo.DianaDropsJson import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.ItemAddEvent @@ -18,12 +19,14 @@ import at.hannibal2.skyhanni.utils.NumberUtil.shortFormat import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher import at.hannibal2.skyhanni.utils.RegexUtils.matches import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.SkyBlockTime import at.hannibal2.skyhanni.utils.renderables.Renderable import at.hannibal2.skyhanni.utils.renderables.Searchable import at.hannibal2.skyhanni.utils.renderables.toSearchable import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import at.hannibal2.skyhanni.utils.tracker.ItemTrackerData import at.hannibal2.skyhanni.utils.tracker.SkyHanniItemTracker +import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker import com.google.gson.annotations.Expose import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -47,6 +50,11 @@ object DianaProfitTracker { "Diana Profit Tracker", { Data() }, { it.diana.dianaProfitTracker }, + SkyHanniTracker.DisplayMode.MAYOR to { + it.diana.dianaProfitTrackerPerElectionSeason.getOrPut( + SkyBlockTime.now().getElectionYear(), ::Data, + ) + }, ) { drawDisplay(it) } class Data : ItemTrackerData() { diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/MythologicalCreatureTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/MythologicalCreatureTracker.kt index ec882d6ec..3c512d4c4 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/MythologicalCreatureTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/MythologicalCreatureTracker.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.features.event.diana import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.MayorAPI.getElectionYear import at.hannibal2.skyhanni.events.ConfigLoadEvent import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.LorenzChatEvent @@ -13,6 +14,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.RegexUtils.matches import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.SkyBlockTime import at.hannibal2.skyhanni.utils.renderables.Searchable import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker @@ -53,8 +55,14 @@ object MythologicalCreatureTracker { ".* §r§eYou dug out a §r§2Minos Inquisitor§r§e!", ) - private val tracker = - SkyHanniTracker("Mythological Creature Tracker", { Data() }, { it.diana.mythologicalMobTracker }) { drawDisplay(it) } + private val tracker = SkyHanniTracker( + "Mythological Creature Tracker", { Data() }, { it.diana.mythologicalMobTracker }, + SkyHanniTracker.DisplayMode.MAYOR to { + it.diana.mythologicalMobTrackerPerElectionSeason.getOrPut( + SkyBlockTime.now().getElectionYear(), ::Data, + ) + }, + ) { drawDisplay(it) } class Data : TrackerData() { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt index 41560553e..991b1a53e 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt @@ -15,28 +15,22 @@ import kotlin.math.ceil object CollectionUtils { inline fun , reified E> T.drainForEach(action: (E) -> Unit): T { - while (true) - action(this.poll() ?: break) + while (true) action(this.poll() ?: break) return this } inline fun , reified E> T.drain(amount: Int): T { - for (i in 1..amount) - this.poll() ?: break + for (i in 1..amount) this.poll() ?: break return this } - inline fun > - Queue.drainTo(list: L, action: (E) -> K): L { - while (true) - list.add(action(this.poll() ?: break)) + inline fun > Queue.drainTo(list: L, action: (E) -> K): L { + while (true) list.add(action(this.poll() ?: break)) return list } - inline fun > - Queue.drainTo(list: L): L { - while (true) - list.add(this.poll() ?: break) + inline fun > Queue.drainTo(list: L): L { + while (true) list.add(this.poll() ?: break) return list } @@ -155,11 +149,9 @@ object CollectionUtils { */ fun List.addIfNotNull(element: String?) = element?.let { plus(it) } ?: this - fun Map.editCopy(function: MutableMap.() -> Unit) = - toMutableMap().also { function(it) }.toMap() + fun Map.editCopy(function: MutableMap.() -> Unit) = toMutableMap().also { function(it) }.toMap() - fun List.editCopy(function: MutableList.() -> Unit) = - toMutableList().also { function(it) }.toList() + fun List.editCopy(function: MutableList.() -> Unit) = toMutableList().also { function(it) }.toList() fun Map.moveEntryToTop(matcher: (Map.Entry) -> Boolean): Map { val entry = entries.find(matcher) @@ -171,8 +163,7 @@ object CollectionUtils { return this } - operator fun IntRange.contains(range: IntRange): Boolean = - range.first in this && range.last in this + operator fun IntRange.contains(range: IntRange): Boolean = range.first in this && range.last in this fun MutableList>.addAsSingletonList(text: E) { add(Collections.singletonList(text)) @@ -262,12 +253,10 @@ object CollectionUtils { } else false @Suppress("UNCHECKED_CAST") - fun Iterable.takeIfAllNotNull(): Iterable? = - takeIf { null !in this } as? Iterable + fun Iterable.takeIfAllNotNull(): Iterable? = takeIf { null !in this } as? Iterable @Suppress("UNCHECKED_CAST") - fun List.takeIfAllNotNull(): List? = - takeIf { null !in this } as? List + fun List.takeIfAllNotNull(): List? = takeIf { null !in this } as? List // TODO add cache fun MutableList.addString( @@ -334,9 +323,17 @@ object CollectionUtils { getName: (T) -> String, isCurrent: (T) -> Boolean, crossinline onChange: (T) -> Unit, + ) = buildSelector(prefix, getName, isCurrent, onChange, enumValues()) + + inline fun buildSelector( + prefix: String, + getName: (T) -> String, + isCurrent: (T) -> Boolean, + crossinline onChange: (T) -> Unit, + universe: Array, ) = buildList { addString(prefix) - for (entry in enumValues()) { + for (entry in universe) { val display = getName(entry) if (isCurrent(entry)) { addString("§a[$display]") diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt index 8d6f98d69..3cadd767b 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniItemTracker.kt @@ -25,8 +25,9 @@ class SkyHanniItemTracker( name: String, createNewSession: () -> Data, getStorage: (ProfileSpecificStorage) -> Data, + vararg extraStorage: Pair Data>, drawDisplay: (Data) -> List, -) : SkyHanniTracker(name, createNewSession, getStorage, drawDisplay) { +) : SkyHanniTracker(name, createNewSession, getStorage, *extraStorage, drawDisplay = drawDisplay) { companion object { val SKYBLOCK_COIN = NEUInternalName.SKYBLOCK_COIN @@ -37,9 +38,8 @@ class SkyHanniItemTracker( it.addItem(internalName, amount, command) } getSharedTracker()?.let { sharedData -> - sharedData.get(DisplayMode.TOTAL).items[internalName]?.let { data -> - sharedData.get(DisplayMode.SESSION).items[internalName]!!.hidden = data.hidden - } + val isHidden = sharedData.get(DisplayMode.TOTAL).items[internalName]?.hidden + if (isHidden != null) sharedData.modify { it.items[internalName]?.hidden = isHidden } } if (command) { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt index 5b07c9906..7810c1ee6 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/tracker/SkyHanniTracker.kt @@ -6,6 +6,7 @@ import at.hannibal2.skyhanni.config.storage.ProfileSpecificStorage import at.hannibal2.skyhanni.data.ProfileStorageData import at.hannibal2.skyhanni.data.TrackerManager import at.hannibal2.skyhanni.features.misc.items.EstimatedItemValue +import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.ChatUtils import at.hannibal2.skyhanni.utils.CollectionUtils import at.hannibal2.skyhanni.utils.NEUInternalName @@ -24,9 +25,11 @@ open class SkyHanniTracker( val name: String, private val createNewSession: () -> Data, private val getStorage: (ProfileSpecificStorage) -> Data, + vararg extraStorage: Pair Data>, private val drawDisplay: (Data) -> List, ) { + private val extraDisplayModes = extraStorage.toMap() private var inventoryOpen = false private var displayMode: DisplayMode? = null private val currentSessions = mutableMapOf() @@ -61,12 +64,8 @@ open class SkyHanniTracker( } fun modify(mode: DisplayMode, modifyFunction: (Data) -> Unit) { - val storage = ProfileStorageData.profileSpecific ?: return - val data: Data = when (mode) { - DisplayMode.TOTAL -> storage.getTotal() - DisplayMode.SESSION -> storage.getCurrentSession() - } - modifyFunction(data) + val sharedTracker = getSharedTracker() ?: return + sharedTracker.modify(mode, modifyFunction) update() } @@ -124,6 +123,8 @@ open class SkyHanniTracker( }, ) + private val availableTrackers = arrayOf(DisplayMode.TOTAL, DisplayMode.SESSION) + extraDisplayModes.keys + private fun buildDisplayModeView() = Renderable.horizontalContainer( CollectionUtils.buildSelector( "§7Display Mode: ", @@ -134,11 +135,17 @@ open class SkyHanniTracker( storedTrackers[name] = it update() }, + universe = availableTrackers, ), ) - protected fun getSharedTracker() = ProfileStorageData.profileSpecific?.let { - SharedTracker(it.getTotal(), it.getCurrentSession()) + protected fun getSharedTracker() = ProfileStorageData.profileSpecific?.let { ps -> + SharedTracker( + mapOf( + DisplayMode.TOTAL to ps.getTotal(), + DisplayMode.SESSION to ps.getCurrentSession(), + ) + extraDisplayModes.mapValues { it.value(ps) }, + ) } private fun ProfileSpecificStorage.getCurrentSession() = currentSessions.getOrPut(this) { createNewSession() } @@ -165,22 +172,30 @@ open class SkyHanniTracker( } } - class SharedTracker(private val total: Data, private val currentSession: Data) { + inner class SharedTracker( + private val entries: Map, + ) { - fun modify(modifyFunction: (Data) -> Unit) { - modifyFunction(total) - modifyFunction(currentSession) + fun modify(mode: DisplayMode, modifyFunction: (Data) -> Unit) { + get(mode).let(modifyFunction) } - fun get(displayMode: DisplayMode) = when (displayMode) { - DisplayMode.TOTAL -> total - DisplayMode.SESSION -> currentSession + fun modify(modifyFunction: (Data) -> Unit) { + entries.values.forEach(modifyFunction) } + + fun get(displayMode: DisplayMode) = entries[displayMode] ?: ErrorManager.skyHanniError( + "Unregistered display mode accessed on tracker", + "tracker" to name, + "displayMode" to displayMode, + "availableModes" to entries.keys, + ) } enum class DisplayMode(val displayName: String) { TOTAL("Total"), SESSION("This Session"), + MAYOR("This Mayor"), ; } -- cgit