summaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features
diff options
context:
space:
mode:
authorJ10a1n15 <45315647+j10a1n15@users.noreply.github.com>2024-03-12 19:59:55 +0100
committerGitHub <noreply@github.com>2024-03-12 19:59:55 +0100
commit4352ffb08d4bfffc06adad2a068f375ab9874333 (patch)
treeb8ce745fca8ab82ffa04f6ab87334139a6b7192b /src/main/java/at/hannibal2/skyhanni/features
parenteb863d60e82b5541a9f42d2608f61cb97ada209b (diff)
downloadskyhanni-4352ffb08d4bfffc06adad2a068f375ab9874333.tar.gz
skyhanni-4352ffb08d4bfffc06adad2a068f375ab9874333.tar.bz2
skyhanni-4352ffb08d4bfffc06adad2a068f375ab9874333.zip
Feature: CustomScoreboard (#893)
Co-authored-by: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Co-authored-by: Thunderblade73 <gaidermarkus@gmail.com> Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaAPI.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/contest/FarmingContestAPI.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/CustomScoreboard.kt130
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/CustomScoreboardUtils.kt53
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/RenderBackground.kt87
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardElements.kt635
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardEvents.kt498
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardPattern.kt404
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/UnknownLinesHandler.kt156
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/inventory/MaxPurseItems.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/minion/MinionXp.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/ServerRestartTitle.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListReader.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/compacttablist/TabListRenderer.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt23
17 files changed, 2005 insertions, 32 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt
index fc884c91d..bee916507 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoAPI.kt
@@ -72,6 +72,8 @@ object BingoAPI {
fun getRankFromScoreboard(text: String) = if (detectionPattern.matches(text)) getRank(text) else null
+ fun getIconFromScoreboard(text: String) = getRankFromScoreboard(text)?.let { getIcon(it) }
+
fun getRank(text: String) = ranks.entries.find { text.contains(it.key) }?.value
fun getIcon(searchRank: Int) = ranks.entries.find { it.value == searchRank }?.key
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaAPI.kt
index 7a6fa1d17..e1e420ab4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/DianaAPI.kt
@@ -2,7 +2,7 @@ package at.hannibal2.skyhanni.features.event.diana
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.IslandType
-import at.hannibal2.skyhanni.data.MayorElection
+import at.hannibal2.skyhanni.data.Perk
import at.hannibal2.skyhanni.data.PetAPI
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
@@ -16,8 +16,8 @@ object DianaAPI {
fun hasSpadeInHand() = InventoryUtils.itemInHandId == spade
- private fun isRitualActive() = MayorElection.isPerkActive("Diana", "Mythological Ritual") ||
- MayorElection.isPerkActive("Jerry", "Perkpocalypse") || SkyHanniMod.feature.event.diana.alwaysDiana
+ private fun isRitualActive() = Perk.MYTHOLOGICAL_RITUAL.isActive ||
+ Perk.PERKPOCALYPSE.isActive || SkyHanniMod.feature.event.diana.alwaysDiana
fun hasGriffinPet() = PetAPI.isCurrentPet("Griffin")
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/FarmingContestAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/FarmingContestAPI.kt
index 399967809..f9999fe2c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/contest/FarmingContestAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/contest/FarmingContestAPI.kt
@@ -33,7 +33,7 @@ object FarmingContestAPI {
"crop",
"§8(?<crop>.*) Contest"
)
- private val sidebarCropPattern by patternGroup.pattern(
+ val sidebarCropPattern by patternGroup.pattern(
"sidebarcrop",
"(?:§e○|§6☘) §f(?<crop>.*) §a.*"
)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt
index 2da5a21eb..7dc92b8d9 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropSpeed.kt
@@ -4,7 +4,7 @@ import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.data.ClickType
import at.hannibal2.skyhanni.data.GardenCropMilestones.getCounter
import at.hannibal2.skyhanni.data.GardenCropMilestones.setCounter
-import at.hannibal2.skyhanni.data.MayorElection
+import at.hannibal2.skyhanni.data.Perk
import at.hannibal2.skyhanni.data.jsonobjects.repo.DicerDropsJson
import at.hannibal2.skyhanni.data.jsonobjects.repo.DicerDropsJson.DicerType
import at.hannibal2.skyhanni.events.CropClickEvent
@@ -175,7 +175,7 @@ object GardenCropSpeed {
fun finneganPerkActive(): Boolean {
val forcefullyEnabledAlwaysFinnegan = config.forcefullyEnabledAlwaysFinnegan
- val perkActive = MayorElection.isPerkActive("Finnegan", "Farming Simulator")
+ val perkActive = Perk.FARMING_SIMULATOR.isActive
return forcefullyEnabledAlwaysFinnegan || perkActive
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/CustomScoreboard.kt b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/CustomScoreboard.kt
new file mode 100644
index 000000000..5e15166c0
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/CustomScoreboard.kt
@@ -0,0 +1,130 @@
+//
+// TODO LIST
+// V2 RELEASE
+// - Soulflow API
+// - Bank API (actually maybe not, I like the current design)
+// - beacon power
+// - skyblock level
+// - more bg options (round, blurr, outline)
+// - countdown events like fishing festival + fiesta when its not on tablist
+// - CookieAPI https://discord.com/channels/997079228510117908/1162844830360146080/1195695210433351821
+// - Rng meter display
+// - shorten time till next mayor https://discord.com/channels/997079228510117908/1162844830360146080/1216440046320746596
+// - option to hide coins earned
+// - color options in the purse etc lines
+// - choose the amount of decimal places in shorten nums
+// - very important bug fix: duplex is weird :(
+//
+
+package at.hannibal2.skyhanni.features.gui.customscoreboard
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiPositionMovedEvent
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.LorenzTickEvent
+import at.hannibal2.skyhanni.utils.ChatUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.RenderUtils.HorizontalAlignment
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAlignedWidth
+import at.hannibal2.skyhanni.utils.TabListData
+import net.minecraftforge.client.GuiIngameForge
+import net.minecraftforge.client.event.RenderGameOverlayEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+typealias ScoreboardElementType = Pair<String, HorizontalAlignment>
+
+class CustomScoreboard {
+
+ private var display = emptyList<ScoreboardElementType>()
+ private var cache = emptyList<ScoreboardElementType>()
+ private val guiName = "Custom Scoreboard"
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) {
+ if (!isEnabled()) return
+ if (display.isEmpty()) return
+
+ RenderBackground().renderBackground()
+
+ val render =
+ if (!TabListData.fullyLoaded && config.displayConfig.cacheScoreboardOnIslandSwitch && cache.isNotEmpty()) {
+ cache
+ } else {
+ display
+ }
+ config.position.renderStringsAlignedWidth(render, posLabel = guiName)
+ }
+
+ @SubscribeEvent
+ fun onGuiPositionMoved(event: GuiPositionMovedEvent) {
+ if (event.guiName == guiName) {
+ val alignmentConfig = config.displayConfig.alignment
+ if (alignmentConfig.alignRight || alignmentConfig.alignCenterVertically) {
+ alignmentConfig.alignRight = false
+ alignmentConfig.alignCenterVertically = false
+ ChatUtils.chat("Disabled Custom Scoreboard auto-alignment.")
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onTick(event: LorenzTickEvent) {
+ if (!isEnabled()) return
+
+ // Creating the lines
+ if (event.isMod(5)) {
+ display = createLines()
+ if (TabListData.fullyLoaded) {
+ cache = display.toList()
+ }
+ }
+
+ // Remove Known Lines, so we can get the unknown ones
+ UnknownLinesHandler.handleUnknownLines()
+ }
+
+ companion object {
+ internal val config get() = SkyHanniMod.feature.gui.customScoreboard
+ internal val displayConfig get() = config.displayConfig
+ internal val informationFilteringConfig get() = config.informationFilteringConfig
+ internal val backgroundConfig get() = config.backgroundConfig
+ }
+
+ private fun createLines() = buildList<ScoreboardElementType> {
+ for (element in config.scoreboardEntries) {
+ val line = element.getVisiblePair()
+
+ // Hide consecutive empty lines
+ if (
+ config.informationFilteringConfig.hideConsecutiveEmptyLines &&
+ line.isNotEmpty() && line[0].first == "<empty>" && lastOrNull()?.first?.isEmpty() == true
+ ) {
+ continue
+ }
+
+ // Adds empty lines
+ if (line[0].first == "<empty>") {
+ add("" to HorizontalAlignment.LEFT)
+ continue
+ }
+
+ // Does not display this line
+ if (line.any { it.first == "<hidden>" }) {
+ continue
+ }
+
+ addAll(line)
+ }
+ }
+
+ // Thank you Apec for showing that the ElementType of the stupid scoreboard is FUCKING HELMET WTF
+ @SubscribeEvent
+ fun onRenderScoreboard(event: RenderGameOverlayEvent.Post) {
+ if (event.type == RenderGameOverlayEvent.ElementType.HELMET) {
+ GuiIngameForge.renderObjective = !isHideVanillaScoreboardEnabled()
+ }
+ }
+
+ private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled
+ private fun isHideVanillaScoreboardEnabled() = isEnabled() && config.displayConfig.hideVanillaScoreboard
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/CustomScoreboardUtils.kt b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/CustomScoreboardUtils.kt
new file mode 100644
index 000000000..74ba89dd6
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/CustomScoreboardUtils.kt
@@ -0,0 +1,53 @@
+package at.hannibal2.skyhanni.features.gui.customscoreboard
+
+import at.hannibal2.skyhanni.config.features.gui.customscoreboard.DisplayConfig
+import at.hannibal2.skyhanni.data.HypixelData
+import at.hannibal2.skyhanni.data.ScoreboardData
+import at.hannibal2.skyhanni.features.bingo.BingoAPI
+import at.hannibal2.skyhanni.features.gui.customscoreboard.CustomScoreboard.Companion.config
+import at.hannibal2.skyhanni.utils.NumberUtil
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.NumberUtil.formatDouble
+import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
+import at.hannibal2.skyhanni.utils.StringUtils.removeResets
+import at.hannibal2.skyhanni.utils.StringUtils.trimWhiteSpace
+import at.hannibal2.skyhanni.utils.TabListData
+import java.util.regex.Pattern
+
+object CustomScoreboardUtils {
+ private val numberFormat get() = config.displayConfig.numberFormat
+
+ internal fun getGroupFromPattern(list: List<String>, pattern: Pattern, group: String) = list.map {
+ it.removeResets().trimWhiteSpace()
+ }.firstNotNullOfOrNull { line ->
+ pattern.matchMatcher(line) {
+ group(group)
+ }
+ } ?: "0"
+
+ fun getProfileTypeSymbol() = when {
+ HypixelData.ironman -> "§7♲ "
+ HypixelData.stranded -> "§a☀ "
+ HypixelData.bingo -> ScoreboardData.sidebarLinesFormatted.firstNotNullOfOrNull {
+ BingoAPI.getIconFromScoreboard(it)?.plus(" ")
+ } ?: "§e❤ "
+
+ else -> "§e"
+ }
+
+ fun getTablistFooter(): String {
+ val tabList = TabListData.getPlayerTabOverlay()
+ if (tabList.footer_skyhanni == null) return ""
+ return tabList.footer_skyhanni.formattedText.replace("§r", "")
+ }
+
+ internal fun Number.formatNum(): String = when (numberFormat) {
+ DisplayConfig.NumberFormat.SHORT -> NumberUtil.format(this)
+ DisplayConfig.NumberFormat.LONG -> this.addSeparators()
+ else -> "0"
+ }
+
+ internal fun String.formatNum() = this.formatDouble().formatNum()
+
+ class UndetectedScoreboardLines(message: String) : Exception(message)
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/RenderBackground.kt b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/RenderBackground.kt
new file mode 100644
index 000000000..2a2f009ac
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/RenderBackground.kt
@@ -0,0 +1,87 @@
+package at.hannibal2.skyhanni.features.gui.customscoreboard
+
+import at.hannibal2.skyhanni.config.core.config.Position
+import at.hannibal2.skyhanni.data.GuiEditManager
+import at.hannibal2.skyhanni.data.GuiEditManager.Companion.getAbsX
+import at.hannibal2.skyhanni.data.GuiEditManager.Companion.getAbsY
+import at.hannibal2.skyhanni.data.GuiEditManager.Companion.getDummySize
+import at.hannibal2.skyhanni.features.gui.customscoreboard.CustomScoreboard.Companion.backgroundConfig
+import at.hannibal2.skyhanni.features.gui.customscoreboard.CustomScoreboard.Companion.config
+import at.hannibal2.skyhanni.utils.RenderUtils
+import at.hannibal2.skyhanni.utils.SpecialColour
+import io.github.moulberry.notenoughupdates.util.Utils
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.ScaledResolution
+import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.util.ResourceLocation
+import org.lwjgl.opengl.GL11
+
+class RenderBackground {
+ fun renderBackground() {
+ val position = config.position
+ val border = 5
+
+ val x = position.getAbsX()
+ val y = position.getAbsY()
+
+ val elementWidth = position.getDummySize().x
+ val elementHeight = position.getDummySize().y
+
+ val scaledWidth = ScaledResolution(Minecraft.getMinecraft()).scaledWidth
+ val scaledHeight = ScaledResolution(Minecraft.getMinecraft()).scaledHeight
+
+ // Update the position to the alignment options
+ if (
+ config.displayConfig.alignment.alignRight
+ || config.displayConfig.alignment.alignCenterVertically
+ ) {
+ position.set(
+ Position(
+ if (config.displayConfig.alignment.alignRight)
+ scaledWidth - elementWidth - (backgroundConfig.borderSize * 2)
+ else x,
+ if (config.displayConfig.alignment.alignCenterVertically)
+ scaledHeight / 2 - elementHeight / 2
+ else y,
+ position.getScale(),
+ position.isCenter
+ )
+ )
+ }
+
+ if (GuiEditManager.isInGui()) return
+
+ GlStateManager.pushMatrix()
+ GlStateManager.pushAttrib()
+
+ GlStateManager.color(1f, 1f, 1f, 1f)
+
+
+ if (backgroundConfig.enabled) {
+ if (backgroundConfig.useCustomBackgroundImage) {
+ val textureLocation = ResourceLocation("skyhanni", "scoreboard.png")
+ Minecraft.getMinecraft().textureManager.bindTexture(textureLocation)
+
+ Utils.drawTexturedRect(
+ (x - backgroundConfig.borderSize).toFloat(),
+ (y - backgroundConfig.borderSize).toFloat(),
+ (elementWidth + backgroundConfig.borderSize * 3).toFloat(),
+ (elementHeight + border * 2).toFloat(),
+ GL11.GL_NEAREST
+ )
+ } else {
+ RenderUtils.drawRoundRect(
+ x - backgroundConfig.borderSize,
+ y - backgroundConfig.borderSize,
+ elementWidth + backgroundConfig.borderSize * 3,
+ elementHeight + backgroundConfig.borderSize * 2,
+ SpecialColour.specialToChromaRGB(backgroundConfig.color),
+ backgroundConfig.roundedCornerSmoothness
+ )
+ }
+ }
+
+ GlStateManager.popMatrix()
+ GlStateManager.popAttrib()
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardElements.kt b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardElements.kt
new file mode 100644
index 000000000..801ba3249
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardElements.kt
@@ -0,0 +1,635 @@
+package at.hannibal2.skyhanni.features.gui.customscoreboard
+
+import at.hannibal2.skyhanni.config.features.gui.customscoreboard.DisplayConfig.ArrowAmountDisplay
+import at.hannibal2.skyhanni.data.BitsAPI
+import at.hannibal2.skyhanni.data.HypixelData
+import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.data.MaxwellAPI
+import at.hannibal2.skyhanni.data.MayorAPI
+import at.hannibal2.skyhanni.data.PartyAPI
+import at.hannibal2.skyhanni.data.PurseAPI
+import at.hannibal2.skyhanni.data.QuiverAPI
+import at.hannibal2.skyhanni.data.QuiverAPI.NONE_ARROW_TYPE
+import at.hannibal2.skyhanni.data.QuiverAPI.asArrowPercentage
+import at.hannibal2.skyhanni.data.ScoreboardData
+import at.hannibal2.skyhanni.data.SlayerAPI
+import at.hannibal2.skyhanni.features.gui.customscoreboard.CustomScoreboard.Companion.config
+import at.hannibal2.skyhanni.features.gui.customscoreboard.CustomScoreboard.Companion.displayConfig
+import at.hannibal2.skyhanni.features.gui.customscoreboard.CustomScoreboard.Companion.informationFilteringConfig
+import at.hannibal2.skyhanni.features.gui.customscoreboard.CustomScoreboardUtils.formatNum
+import at.hannibal2.skyhanni.features.gui.customscoreboard.CustomScoreboardUtils.getGroupFromPattern
+import at.hannibal2.skyhanni.mixins.hooks.tryToReplaceScoreboardLine
+import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.CollectionUtils.nextAfter
+import at.hannibal2.skyhanni.utils.LorenzUtils.inAdvancedMiningIsland
+import at.hannibal2.skyhanni.utils.LorenzUtils.inAnyIsland
+import at.hannibal2.skyhanni.utils.LorenzUtils.inDungeons
+import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
+import at.hannibal2.skyhanni.utils.NumberUtil.percentageColor
+import at.hannibal2.skyhanni.utils.RenderUtils.HorizontalAlignment
+import at.hannibal2.skyhanni.utils.StringUtils.firstLetterUppercase
+import at.hannibal2.skyhanni.utils.StringUtils.matches
+import at.hannibal2.skyhanni.utils.TabListData
+import at.hannibal2.skyhanni.utils.TimeUtils.format
+import at.hannibal2.skyhanni.utils.TimeUtils.formatted
+import io.github.moulberry.notenoughupdates.util.SkyBlockTime
+import java.util.function.Supplier
+
+internal var unknownLines = listOf<String>()
+internal var amountOfUnknownLines = 0
+
+enum class ScoreboardElement(
+ private val displayPair: Supplier<List<ScoreboardElementType>>,
+ private val showWhen: () -> Boolean,
+ private val configLine: String
+) {
+ TITLE(
+ ::getTitleDisplayPair,
+ { true },
+ "§6§lSKYBLOCK"
+ ),
+ PROFILE(
+ ::getProfileDisplayPair,
+ { true },
+ "§7♲ Blueberry"
+ ),
+ PURSE(
+ ::getPurseDisplayPair,
+ ::getPurseShowWhen,
+ "Purse: §652,763,737"
+ ),
+ MOTES(
+ ::getMotesDisplayPair,
+ ::getMotesShowWhen,
+ "Motes: §d64,647"
+ ),
+ BANK(
+ ::getBankDisplayPair,
+ ::getBankShowWhen,
+ "Bank: §6249M"
+ ),
+ BITS(
+ ::getBitsDisplayPair,
+ ::getBitsShowWhen,
+ "Bits: §b59,264"
+ ),
+ COPPER(
+ ::getCopperDisplayPair,
+ ::getCopperShowWhen,
+ "Copper: §c23,495"
+ ),
+ GEMS(
+ ::getGemsDisplayPair,
+ ::getGemsShowWhen,
+ "Gems: §a57,873"
+ ),
+ HEAT(
+ ::getHeatDisplayPair,
+ ::getHeatShowWhen,
+ "Heat: §c♨ 0"
+ ),
+ NORTH_STARS(
+ ::getNorthStarsDisplayPair,
+ ::getNorthStarsShowWhen,
+ "North Stars: §d756"
+ ),
+ EMPTY_LINE(
+ ::getEmptyLineDisplayPair,
+ { true }, ""
+ ),
+ ISLAND(
+ ::getIslandDisplayPair,
+ { true },
+ "§7㋖ §aHub"
+ ),
+ LOCATION(
+ ::getLocationDisplayPair,
+ { true },
+ "§7⏣ §bVillage"
+ ),
+ VISITING(
+ ::getVisitDisplayPair,
+ ::getVisitShowWhen,
+ " §a✌ §7(§a1§7/6)"
+ ),
+ DATE(
+ ::getDateDisplayPair,
+ { true },
+ "Late Summer 11th"
+ ),
+ TIME(
+ ::getTimeDisplayPair,
+ { true },
+ "§710:40pm §b☽"
+ ),
+ LOBBY_CODE(
+ ::getLobbyDisplayPair,
+ { true },
+ "§8m77CK"
+ ),
+ POWER(
+ ::getPowerDisplayPair,
+ ::getPowerShowWhen,
+ "Power: Sighted"
+ ),
+ COOKIE(
+ ::getCookieDisplayPair,
+ ::getCookieShowWhen,
+ "§d§lCookie Buff\n §f3days, 17hours"
+ ),
+ EMPTY_LINE2(
+ ::getEmptyLineDisplayPair,
+ { true }, ""
+ ),
+ OBJECTIVE(
+ ::getObjectiveDisplayPair,
+ ::getObjectiveShowWhen,
+ "Objective:\n§eStar SkyHanni on Github"
+ ),
+ SLAYER(
+ ::getSlayerDisplayPair,
+ ::getSlayerShowWhen,
+ "Slayer Quest\n §7- §cVoidgloom Seraph III\n §7- §e12§7/§c120 §7Kills"
+ ),
+ EMPTY_LINE3(
+ ::getEmptyLineDisplayPair,
+ { true },
+ ""
+ ),
+ QUIVER(
+ ::getQuiverDisplayPair,
+ ::getQuiverShowWhen,
+ "Flint Arrow: §f1,234"
+ ),
+ POWDER(
+ ::getPowderDisplayPair,
+ ::getPowderShowWhen,
+ "§9§lPowder\n §7- §fMithril: §254,646\n §7- §fGemstone: §d51,234"
+ ),
+ EVENTS(
+ ::getEventsDisplayPair,
+ ::getEventsShowWhen,
+ "§7Wide Range of Events\n§7(too much to show all)"
+ ),
+ MAYOR(
+ ::getMayorDisplayPair,
+ ::getMayorShowWhen,
+ "§2Diana:\n §7- §eLucky!\n §7- §eMythological Ritual\n §7- §ePet XP Buff"
+ ),
+ PARTY(
+ ::getPartyDisplayPair,
+ ::getPartyShowWhen,
+ "§9§lParty (4):\n §7- §fhannibal2\n §7- §fMoulberry\n §7- §fVahvl\n §7- §fJ10a1n15"
+ ),
+ FOOTER(
+ ::getFooterDisplayPair,
+ { true },
+ "§ewww.hypixel.net"
+ ),
+ EXTRA(
+ ::getExtraDisplayPair,
+ ::getExtraShowWhen,
+ "§cUnknown lines the mod is not detecting"
+ ),
+ ;
+
+ override fun toString(): String {
+ return configLine
+ }
+
+ fun getVisiblePair() = if (isVisible()) getPair() else listOf("<hidden>" to HorizontalAlignment.LEFT)
+
+ private fun getPair(): List<ScoreboardElementType> {
+ return try {
+ displayPair.get()
+ } catch (e: NoSuchElementException) {
+ listOf("<hidden>" to HorizontalAlignment.LEFT)
+ }
+ }
+
+ private fun isVisible(): Boolean {
+ if (!informationFilteringConfig.hideIrrelevantLines) return true
+ return showWhen()
+ }
+}
+
+
+private fun getTitleDisplayPair() = if (displayConfig.titleAndFooter.useHypixelTitleAnimation) {
+ listOf(ScoreboardData.objectiveTitle to displayConfig.titleAndFooter.alignTitleAndFooter)
+} else {
+ listOf(
+ displayConfig.titleAndFooter.customTitle.get().toString()
+ .replace("&", "§") to displayConfig.titleAndFooter.alignTitleAndFooter
+ )
+}
+
+private fun getProfileDisplayPair() =
+ listOf(CustomScoreboardUtils.getProfileTypeSymbol() + HypixelData.profileName.firstLetterUppercase() to HorizontalAlignment.LEFT)
+
+private fun getPurseDisplayPair(): List<ScoreboardElementType> {
+ var purse = PurseAPI.currentPurse.formatNum()
+
+ val earned = getGroupFromPattern(ScoreboardData.sidebarLinesFormatted, PurseAPI.coinsPattern, "earned")
+
+ if (earned != "0") {
+ purse += " §7(§e+$earned§7)§6"
+ }
+
+ return listOf(
+ when {
+ informationFilteringConfig.hideEmptyLines && purse == "0" -> "<hidden>"
+ displayConfig.displayNumbersFirst -> "§6$purse Purse"
+ else -> "Purse: §6$purse"
+ } to HorizontalAlignment.LEFT
+ )
+}
+
+private fun getPurseShowWhen() = !inAnyIsland(IslandType.THE_RIFT)
+
+private fun getMotesDisplayPair(): List<ScoreboardElementType> {
+ val motes = getGroupFromPattern(ScoreboardData.sidebarLinesFormatted, ScoreboardPattern.motesPattern, "motes")
+ .formatNum()
+
+ return listOf(
+ when {
+ informationFilteringConfig.hideEmptyLines && motes == "0" -> "<hidden>"
+ displayConfig.displayNumbersFirst -> "§d$motes Motes"
+ else -> "Motes: §d$motes"
+ } to HorizontalAlignment.LEFT
+ )
+}
+
+private fun getMotesShowWhen() = inAnyIsland(IslandType.THE_RIFT)
+
+private fun getBankDisplayPair(): List<ScoreboardElementType> {
+ val bank = getGroupFromPattern(TabListData.getTabList(), ScoreboardPattern.bankPattern, "bank")
+
+ return listOf(
+ when {
+ informationFilteringConfig.hideEmptyLines && bank == "0" -> "<hidden>"
+ displayConfig.displayNumbersFirst -> "§6$bank Bank"
+ else -> "Bank: §6$bank"
+ } to HorizontalAlignment.LEFT
+ )
+}
+
+private fun getBankShowWhen() = !inAnyIsland(IslandType.THE_RIFT)
+
+private fun getBitsDisplayPair(): List<ScoreboardElementType> {
+ val bits = BitsAPI.bits.coerceAtLeast(0).formatNum()
+ val bitsToClaim = if (BitsAPI.bitsToClaim == -1) {
+ "§cOpen Sbmenu§b"
+ } else {
+ BitsAPI.bitsToClaim.coerceAtLeast(0).formatNum()
+ }
+
+ return listOf(
+ when {
+ informationFilteringConfig.hideEmptyLines && bits == "0" && bitsToClaim == "0" -> "<hidden>"
+ displayConfig.displayNumbersFirst -> {
+ if (displayConfig.showUnclaimedBits) {
+ "§b$bits§7/${if (bitsToClaim == "0") "§30" else "§b${bitsToClaim}"} §bBits"
+ } else {
+ "§b$bits Bits"
+ }
+ }
+
+ else -> {
+ if (displayConfig.showUnclaimedBits) {
+ "Bits: §b$bits§7/${if (bitsToClaim == "0") "§30" else "§b${bitsToClaim}"}"
+ } else {
+ "Bits: §b$bits"
+ }
+ }
+ } to HorizontalAlignment.LEFT
+ )
+}
+
+private fun getBitsShowWhen() = !HypixelData.bingo && !inAnyIsland(IslandType.CATACOMBS, IslandType.KUUDRA_ARENA)
+
+private fun getCopperDisplayPair(): List<ScoreboardElementType> {
+ val copper = getGroupFromPattern(ScoreboardData.sidebarLinesFormatted, ScoreboardPattern.copperPattern, "copper")
+ .formatNum()
+
+ return listOf(
+ when {
+ informationFilteringConfig.hideEmptyLines && copper == "0" -> "<hidden>"
+ displayConfig.displayNumbersFirst -> "§c$copper Copper"
+ else -> "Copper: §c$copper"
+ } to HorizontalAlignment.LEFT
+ )
+}
+
+private fun getCopperShowWhen() = inAnyIsland(IslandType.GARDEN)
+
+private fun getGemsDisplayPair(): List<ScoreboardElementType> {
+ val gems = getGroupFromPattern(TabListData.getTabList(), ScoreboardPattern.gemsPattern, "gems")
+
+ return listOf(
+ when {
+ informationFilteringConfig.hideEmptyLines && gems == "0" -> "<hidden>"
+ displayConfig.displayNumbersFirst -> "§a$gems Gems"
+ else -> "Gems: §a$gems"
+ } to HorizontalAlignment.LEFT
+ )
+}
+
+private fun getGemsShowWhen() = !inAnyIsland(IslandType.THE_RIFT, IslandType.CATACOMBS, IslandType.KUUDRA_ARENA)
+
+private fun getHeatDisplayPair(): List<ScoreboardElementType> {
+ val heat = getGroupFromPattern(ScoreboardData.sidebarLinesFormatted, ScoreboardPattern.heatPattern, "heat")
+
+ return listOf(
+ when {
+ informationFilteringConfig.hideEmptyLines && heat == "§c♨ 0" -> "<hidden>"
+ displayConfig.displayNumbersFirst -> if (heat == "0") "§c♨ 0 Heat" else "$heat Heat"
+ else -> if (heat == "0") "Heat: §c♨ 0" else "Heat: $heat"
+ } to HorizontalAlignment.LEFT
+ )
+}
+
+private fun getHeatShowWhen() = inAnyIsland(IslandType.CRYSTAL_HOLLOWS)
+ && ScoreboardData.sidebarLinesFormatted.any { ScoreboardPattern.heatPattern.matches(it) }
+
+private fun getNorthStarsDisplayPair(): List<ScoreboardElementType> {
+ val northStars =
+ getGroupFromPattern(ScoreboardData.sidebarLinesFormatted, ScoreboardPattern.northstarsPattern, "northstars")
+ .formatNum()
+
+ return listOf(
+ when {
+ informationFilteringConfig.hideEmptyLines && northStars == "0" -> "<hidden>"
+ displayConfig.displayNumbersFirst -> "§d$northStars North Stars"
+ else -> "North Stars: §d$northStars"
+ } to HorizontalAlignment.LEFT
+ )
+}
+
+private fun getNorthStarsShowWhen() = inAnyIsland(IslandType.WINTER)
+
+private fun getEmptyLineDisplayPair() = listOf("<empty>" to HorizontalAlignment.LEFT)
+
+private fun getIslandDisplayPair() =
+ listOf("§7㋖ §a" + HypixelData.skyBlockIsland.displayName to HorizontalAlignment.LEFT)
+
+private fun getLocationDisplayPair() = buildList {
+ add(
+ (tryToReplaceScoreboardLine(
+ getGroupFromPattern(
+ ScoreboardData.sidebarLinesFormatted,
+ ScoreboardPattern.locationPattern,
+ "location"
+ )
+ )?.trim()
+ ?: "<hidden>") to HorizontalAlignment.LEFT
+ )
+
+ val plotLine = ScoreboardData.sidebarLinesFormatted.firstOrNull { ScoreboardPattern.plotPattern.matches(it) }
+ if (plotLine != null) add(plotLine to HorizontalAlignment.LEFT)
+}
+
+private fun getVisitDisplayPair() =
+ listOf(
+ ScoreboardData.sidebarLinesFormatted.first { ScoreboardPattern.visitingPattern.matches(it) } to H