Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement: Option to show Change in Counts in HoppityEventSummary #3145

Open
wants to merge 30 commits into
base: beta
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
df8315e
Done
DavidArthurCole Dec 22, 2024
32e09db
Revert "Done"
DavidArthurCole Dec 22, 2024
652b65a
Done, again
DavidArthurCole Dec 22, 2024
715f587
Deal with migrations, todos
DavidArthurCole Dec 23, 2024
f3f1599
Fix
DavidArthurCole Jan 1, 2025
3a3ae28
Done
DavidArthurCole Jan 2, 2025
01042ca
Fix
DavidArthurCole Jan 2, 2025
a3181fc
Fix
DavidArthurCole Jan 2, 2025
6cc8060
Fix formatting
DavidArthurCole Jan 2, 2025
cfa0929
Merge
DavidArthurCole Jan 2, 2025
47ba1c1
Cleanup
DavidArthurCole Jan 2, 2025
8cdfa25
Future proofing
DavidArthurCole Jan 2, 2025
0eb6691
Formatting
DavidArthurCole Jan 2, 2025
ed03023
Fix config
DavidArthurCole Jan 2, 2025
7bcc8a7
Fix index
DavidArthurCole Jan 2, 2025
43379e2
Merge
DavidArthurCole Jan 4, 2025
2a0b9f0
Merge remote-tracking branch 'upstream/beta' into HoppityUnDupCounter
DavidArthurCole Jan 6, 2025
cffdc7e
Fix overdisplay
DavidArthurCole Jan 6, 2025
0bafc99
Merge branch 'beta' into HoppityUnDupCounter
DavidArthurCole Jan 14, 2025
a9c5aea
Merge branch 'beta' into HoppityUnDupCounter
CalMWolfs Jan 16, 2025
14b1583
Merge
DavidArthurCole Jan 20, 2025
a5747d3
Fixes
DavidArthurCole Jan 20, 2025
20684f6
Merge
DavidArthurCole Jan 23, 2025
e3d9c8a
Merge branch 'beta' into HoppityUnDupCounter
DavidArthurCole Jan 24, 2025
272a4fb
Merge branch 'beta' into HoppityUnDupCounter
CalMWolfs Jan 24, 2025
2d59031
Merge branch 'beta' into HoppityUnDupCounter
DavidArthurCole Jan 24, 2025
a88be7d
Merge
DavidArthurCole Jan 24, 2025
4a756b0
Merge branch 'beta' into HoppityUnDupCounter
DavidArthurCole Jan 24, 2025
e84c262
Merge
DavidArthurCole Jan 25, 2025
3b0f170
Merge
DavidArthurCole Jan 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import io.github.notenoughupdates.moulconfig.annotations.Accordion;
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorBoolean;
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorDraggableList;
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorInfoText;
import io.github.notenoughupdates.moulconfig.annotations.ConfigLink;
import io.github.notenoughupdates.moulconfig.annotations.ConfigOption;
import io.github.notenoughupdates.moulconfig.observer.Property;
Expand Down Expand Up @@ -65,9 +64,9 @@ public enum HoppityStat {
SIDE_DISH_EGGS("§7You found §b4 §6§lSide Dish Eggs §r§7in the §6Chocolate Factory§7."),
MILESTONE_RABBITS("§7You claimed §b2 §6§lMilestone Rabbits§7."),
EMPTY_1(""),
NEW_RABBITS("§7Unique Rabbits: §b7\n §f1 §7- §a1 §7- §91 §7- §51 §7- §61 §7- §d1 §7- §b1"),
NEW_RABBITS("§7Unique Rabbits: §f7\n §f1 §7- §a1 §7- §91 §7- §51 §7- §61 §7- §d1 §7- §b1"),
EMPTY_2(""),
DUPLICATE_RABBITS("§7Duplicate Rabbits: §c10\n §f4 §7- §a3 §7- §92 §7- §51 §7- §60 §7- §d0 §7- §b0\n §6+250,000,000 Chocolate"),
DUPLICATE_RABBITS("§7Duplicate Rabbits: §f10\n §f4 §7- §a3 §7- §92 §7- §51 §7- §60 §7- §d0 §7- §b0\n §6+250,000,000 Chocolate"),
EMPTY_3(""),
STRAY_RABBITS("§7Stray Rabbits: §f20\n §f10 §7- §a6 §7- §93 §7- §51 §7- §60 §7- §d0 §7- §b0\n §6+8,000,000 Chocolate\n §4* §c§oRequires Stray Tracker being enabled to work§4§o."),
EMPTY_4(""),
Expand All @@ -87,4 +86,13 @@ public String toString() {
return display;
}
}

@Expose
@ConfigOption(
name = "Show Count Diff",
desc = "Store and display the count of Uniques/Duplicates next to their respective rabbit count.\n" +
".e.g. §7Unique Rabbits: §f5 §7(270 -> 275)"
)
@ConfigEditorBoolean
public boolean showCountDiff = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -748,14 +748,26 @@ class ProfileSpecificStorage {

@Expose
var summarized: Boolean = false,

@Expose
var typeCountSnapshot: RabbitData = RabbitData(),

@Expose
var typeCountsSince: RabbitData = RabbitData(),
) {
companion object {
data class RabbitData(
@Expose var uniques: Int = 0,
@Expose var dupes: Int = 0,
@Expose var strays: Int = 0,
)

) {
fun getByIndex(index: Int): Int = when (index) {
0 -> uniques
1 -> dupes
2 -> strays
else -> throw IllegalArgumentException("Invalid index: $index")
}
}
data class LeaderboardPosition(@Expose var position: Int, @Expose var percentile: Double)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.features.event.hoppity

import at.hannibal2.skyhanni.api.event.HandleEvent
import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.config.storage.ProfileSpecificStorage
import at.hannibal2.skyhanni.config.storage.ProfileSpecificStorage.ChocolateFactoryStorage.HotspotRabbitStorage
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.ProfileStorageData
Expand All @@ -23,6 +24,8 @@ import at.hannibal2.skyhanni.utils.CollectionUtils.addOrPut
import at.hannibal2.skyhanni.utils.CollectionUtils.addString
import at.hannibal2.skyhanni.utils.CollectionUtils.collectWhile
import at.hannibal2.skyhanni.utils.CollectionUtils.consumeWhile
import at.hannibal2.skyhanni.utils.CollectionUtils.sumAllValues
import at.hannibal2.skyhanni.utils.CollectionUtils.sumOfPair
import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.DisplayTableEntry
import at.hannibal2.skyhanni.utils.InventoryUtils
Expand Down Expand Up @@ -184,12 +187,13 @@ object HoppityCollectionStats {
)
// </editor-fold>

private val profileStorage get() = ProfileStorageData.profileSpecific?.chocolateFactory
private var shCountData: HoppityEggLocationsJson? = null
private var neuCountData: HoppityInfo? = null
private var hotspotRabbitCount = 0
private var display = emptyList<Renderable>()
private val loggedRabbits
get() = ProfileStorageData.profileSpecific?.chocolateFactory?.rabbitCounts ?: mutableMapOf()
get() = profileStorage?.rabbitCounts ?: mutableMapOf()

enum class HighlightRabbitTypes(
private val displayName: String,
Expand Down Expand Up @@ -228,17 +232,17 @@ object HoppityCollectionStats {
}

private val locationRabbitRequirements: MutableMap<String, LocationRabbit>
get() = ProfileStorageData.profileSpecific?.chocolateFactory?.locationRabbitRequirements ?: mutableMapOf()
get() = profileStorage?.locationRabbitRequirements ?: mutableMapOf()

private val residentRabbitData: MutableMap<IslandType, MutableMap<String, Boolean?>>
get() = ProfileStorageData.profileSpecific?.chocolateFactory?.residentRabbits ?: mutableMapOf()
get() = profileStorage?.residentRabbits ?: mutableMapOf()

private val hotspotRabbitData: HotspotRabbitStorage?
get() = ProfileStorageData.profileSpecific?.chocolateFactory?.hotspotRabbitStorage?.let { storage ->
get() = profileStorage?.hotspotRabbitStorage?.let { storage ->
val yearNow = SkyBlockTime.now().year
if (storage.skyblockYear != yearNow) {
HotspotRabbitStorage(yearNow).also {
ProfileStorageData.profileSpecific?.chocolateFactory?.hotspotRabbitStorage = it
profileStorage?.hotspotRabbitStorage = it
}
} else storage
}
Expand Down Expand Up @@ -601,7 +605,7 @@ object HoppityCollectionStats {

val newList = mutableListOf<Renderable>()
newList.add(Renderable.string("§eHoppity Rabbit Collection§f:"))
newList.add(LorenzUtils.fillTable(getRabbitStats(), padding = 5))
newList.add(LorenzUtils.fillTable(getRabbitStatsFormat(), padding = 5))

addLocationRequirementRabbitsToHud(newList)
addResidentRabbitsInformationToHud(newList)
Expand All @@ -622,7 +626,27 @@ object HoppityCollectionStats {
return newList
}

private fun getRabbitStats(): MutableList<DisplayTableEntry> {
fun getTypeCountSnapshot(): ProfileSpecificStorage.HoppityEventStats.Companion.RabbitData {
val (uniqueCount, duplicateCount) = RabbitCollectionRarity.entries.sumOfPair(
selector = { rarity ->
val foundOfRarity = loggedRabbits.filterKeys {
HoppityCollectionData.getRarity(it) == rarity
}
val uniquesFound = foundOfRarity.size
val duplicates = foundOfRarity.values.sum() - uniquesFound
uniquesFound to duplicates
},
resultConverter = Double::toInt
)

return ProfileSpecificStorage.HoppityEventStats.Companion.RabbitData(
uniques = uniqueCount,
dupes = duplicateCount,
strays = profileStorage?.strayTracker?.straysCaught?.sumAllValues()?.toInt() ?: 0,
)
}

private fun getRabbitStatsFormat(): MutableList<DisplayTableEntry> {
var totalUniquesFound = 0
var totalDuplicates = 0
var totalChocolatePerSecond = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import at.hannibal2.skyhanni.utils.CollectionUtils.addOrPut
import at.hannibal2.skyhanni.utils.CollectionUtils.addString
import at.hannibal2.skyhanni.utils.CollectionUtils.sumAllValues
import at.hannibal2.skyhanni.utils.ConditionalUtils.afterChange
import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.LorenzRarity
import at.hannibal2.skyhanni.utils.LorenzUtils
Expand Down Expand Up @@ -69,7 +70,9 @@ import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds

// TODO: Split into two classes, one for event summary in general, and one for live display
@SkyHanniModule
@Suppress("LargeClass")
object HoppityEventSummary {
/**
* REGEX-TEST: §d§lHOPPITY'S HUNT §r§7You found §r§cRabbit the Fish§r§7!
Expand Down Expand Up @@ -182,15 +185,26 @@ object HoppityEventSummary {

@HandleEvent
fun onRabbitFound(event: RabbitFoundEvent) {
if (!HoppityApi.isHoppityEvent()) return

val stats = getYearStats() ?: return
if (!HoppityApi.isHoppityEvent()) {
DelayedRun.runDelayed(5.seconds) {
stats.typeCountsSince = HoppityCollectionStats.getTypeCountSnapshot()
}
return
}

stats.mealsFound.addOrPut(event.eggType, 1)
val rarity = HoppityApi.rarityByRabbit(event.rabbitName) ?: return
val rarityMap = stats.rabbitsFound.getOrPut(rarity) { RabbitData() }
if (event.duplicate) rarityMap.dupes++
else rarityMap.uniques++
if (event.chocGained > 0) stats.dupeChocolateGained += event.chocGained

// Make sure we account for event priority, since HoppityCollectionStats has a statically set lower priority
DelayedRun.runDelayed(5.seconds) {
stats.typeCountSnapshot = HoppityCollectionStats.getTypeCountSnapshot()
}
}

@HandleEvent(onlyOnSkyblock = true)
Expand Down Expand Up @@ -262,6 +276,7 @@ object HoppityEventSummary {

@HandleEvent(onlyOnSkyblock = true)
fun onSecondPassed(event: SecondPassedEvent) {
checkStatsTypeCountInit()
checkLbUpdateWarning()
reCheckInventoryState()
checkEnded()
Expand Down Expand Up @@ -313,6 +328,14 @@ object HoppityEventSummary {
} ?: ErrorManager.skyHanniError("Could not reset Hoppity Event stats.")
}

private fun checkStatsTypeCountInit() {
val stats = getYearStats() ?: return
for (i in 0..2) {
if (stats.typeCountSnapshot.getByIndex(i) != 0) return
}
stats.typeCountSnapshot = HoppityCollectionStats.getTypeCountSnapshot()
}

private fun checkLbUpdateWarning() {
if (!LorenzUtils.inSkyBlock || !HoppityApi.isHoppityEvent() || !updateCfConfig.enabled) return

Expand Down Expand Up @@ -537,6 +560,9 @@ object HoppityEventSummary {
add(StatString(chocFormatLine))
}

private fun getPreviousStats(year: Int): HoppityEventStats? =
storage?.hoppityEventStats?.get(year - 1)

private fun HoppityEventStats.getMilestoneCount(): Int =
(mealsFound[HoppityEggType.CHOCOLATE_FACTORY_MILESTONE] ?: 0) +
(mealsFound[HoppityEggType.CHOCOLATE_SHOP_MILESTONE] ?: 0)
Expand Down Expand Up @@ -588,21 +614,33 @@ object HoppityEventSummary {
}
}

put(HoppityStat.NEW_RABBITS) { statList, stats, _ ->
getRabbitsFormat(stats.rabbitsFound.mapValues { m -> m.value.uniques }, "Unique").forEach {
put(HoppityStat.NEW_RABBITS) { statList, stats, year ->
getRabbitsFormat(
rarityMap = stats.rabbitsFound.mapValues { m -> m.value.uniques },
name = "Unique",
countTriple = stats.getPairTriple(year, 0),
).forEach {
statList.addStr(it)
}
}

put(HoppityStat.DUPLICATE_RABBITS) { statList, stats, _ ->
getRabbitsFormat(stats.rabbitsFound.mapValues { m -> m.value.dupes }, "Duplicate").forEach {
put(HoppityStat.DUPLICATE_RABBITS) { statList, stats, year ->
getRabbitsFormat(
rarityMap = stats.rabbitsFound.mapValues { m -> m.value.dupes },
name = "Duplicate",
countTriple = stats.getPairTriple(year, 1),
).forEach {
statList.addStr(it)
}
statList.addExtraChocFormatLine(stats.dupeChocolateGained)
}

put(HoppityStat.STRAY_RABBITS) { statList, stats, _ ->
getRabbitsFormat(stats.rabbitsFound.mapValues { m -> m.value.strays }, "Stray").forEach {
put(HoppityStat.STRAY_RABBITS) { statList, stats, year ->
getRabbitsFormat(
rarityMap = stats.rabbitsFound.mapValues { m -> m.value.strays },
name = "Stray",
countTriple = stats.getPairTriple(year, 2),
).forEach {
statList.addStr(it)
}
statList.addExtraChocFormatLine(stats.strayChocolateGained)
Expand Down Expand Up @@ -744,12 +782,37 @@ object HoppityEventSummary {
return previousEggs + currentEggs
}

private fun getRabbitsFormat(rarityMap: Map<LorenzRarity, Int>, name: String): List<String> {
private fun HoppityEventStats.getPairTriple(
year: Int,
index: Int
): Triple<Int, Int, Int> = getPreviousStats(year)?.let {
val currentValue = this.typeCountSnapshot.getByIndex(index)
val previousValue = it.typeCountSnapshot.getByIndex(index)
val sinceValue = it.typeCountsSince.getByIndex(index) - previousValue
val validData = previousValue != 0 && previousValue != currentValue
Triple(
if (validData) previousValue else 0,
if (validData) currentValue else 0,
if (validData) sinceValue else 0,
)
} ?: Triple(0, 0, 0)

fun getRabbitsFormat(
rarityMap: Map<LorenzRarity, Int>,
name: String,
countTriple: Triple<Int, Int, Int> = Triple(0, 0, 0),
): List<String> {
val (prevCount, currCount, sinceCount) = countTriple
val rabbitsSum = rarityMap.values.sum()
if (rabbitsSum == 0) return emptyList()

val sinceFormat = if (sinceCount != 0) " §8+$sinceCount§7" else ""
val countFormat = if (config.eventSummary.showCountDiff && prevCount != 0 && currCount != 0) {
" §7($prevCount$sinceFormat -> $currCount)"
} else ""

return mutableListOf(
"§7$name Rabbits: §f$rabbitsSum",
"§7$name Rabbits: §f$rabbitsSum$countFormat",
HoppityApi.hoppityRarities.joinToString(" §7-") {
" ${it.chatColorCode}${rarityMap[it] ?: 0}"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ enum class FortuneStats(

companion object {

fun getTotal(): Pair<Double, Double> = entries.filter { it.isActive() }.sumOfPair { it.current to it.max }
fun getTotal(): Pair<Double, Double> = entries.filter { it.isActive() }.sumOfPair(
selector = { it.current to it.max },
resultConverter = { it }
)

fun reset() = entries.forEach { it.reset() }
}
Expand Down
17 changes: 12 additions & 5 deletions src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -463,13 +463,20 @@ object CollectionUtils {
return destination
}

inline fun <T, C : Number, D : Number> Iterable<T>.sumOfPair(selector: (T) -> Pair<C, D>): Pair<Double, Double> {
var sum = Pair(0.0, 0.0)
inline fun <T, C : Number, D : Number, R : Number> Iterable<T>.sumOfPair(
crossinline selector: (T) -> Pair<C, D>,
crossinline resultConverter: (Double) -> R
): Pair<R, R> {
var sumFirst = 0.0
var sumSecond = 0.0

for (element in this) {
val add = selector(element)
sum = sum.first + add.first.toDouble() to sum.second + add.second.toDouble()
val (c, d) = selector(element)
sumFirst += c.toDouble()
sumSecond += d.toDouble()
}
return sum

return resultConverter(sumFirst) to resultConverter(sumSecond)
}

inline fun <T, R> Iterable<T>.zipWithNext3(transform: (a: T, b: T, c: T) -> R): List<R> {
Expand Down
Loading