diff options
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features')
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 HorizontalAlignment.LEFT + ) + +private fun getVisitShowWhen() = + ScoreboardData.sidebarLinesFormatted.any { ScoreboardPattern.visitingPattern.matches(it) } + +private fun getDateDisplayPair() = + listOf( + SkyBlockTime.now().formatted(yearElement = false, hoursAndMinutesElement = false) to HorizontalAlignment.LEFT + ) + + +private fun getTimeDisplayPair(): List<ScoreboardElementType> { + var symbol = getGroupFromPattern(ScoreboardData.sidebarLinesFormatted, ScoreboardPattern.timePattern, "symbol") + if (symbol == "0") symbol = "" + return listOf( + "§7" + SkyBlockTime.now() + .formatted(dayAndMonthElement = false, yearElement = false) + " $symbol" to HorizontalAlignment.LEFT + ) +} + +private fun getLobbyDisplayPair(): List<ScoreboardElementType> { + val lobbyCode = getGroupFromPattern( + ScoreboardData.sidebarLinesFormatted, + ScoreboardPattern.lobbyCodePattern, + "code" + ) + + val displayValue = if (lobbyCode == "0") "<hidden>" else "§8$lobbyCode" + return listOf(displayValue to HorizontalAlignment.LEFT) +} + +private fun getPowerDisplayPair() = listOf( + when (MaxwellAPI.currentPower) { + null -> "§cOpen \"Your Bags\"!" + else -> + if (displayConfig.displayNumbersFirst) { + "${MaxwellAPI.currentPower?.replace("Power", "")} Power " + + "§7(§6${MaxwellAPI.magicalPower}§7)" + } else { + |
