diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/anniversary/Year300RaffleEvent.kt b/src/main/java/at/hannibal2/skyhanni/features/event/anniversary/Year300RaffleEvent.kt index 134e09d09b21..fe60f02fc771 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/anniversary/Year300RaffleEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/anniversary/Year300RaffleEvent.kt @@ -6,7 +6,7 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NEUItems -import at.hannibal2.skyhanni.utils.RenderUtils.renderSingleLineWithItems +import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderable import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.SkyBlockTime import at.hannibal2.skyhanni.utils.SoundUtils @@ -29,7 +29,7 @@ object Year300RaffleEvent { private var lastTimerReceived = SimpleTimeMark.farPast() private var lastTimeAlerted = SimpleTimeMark.farPast() - private var overlay: List? = null + private var overlay: Renderable? = null @SubscribeEvent fun onChat(event: LorenzChatEvent) { @@ -43,10 +43,7 @@ object Year300RaffleEvent { @SubscribeEvent fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { - config.activeTimerPosition.renderSingleLineWithItems( - overlay ?: return, - posLabel = "300þ Anniversary Active Timer" - ) + config.activeTimerPosition.renderRenderable(overlay, posLabel = "300þ Anniversary Active Timer") } @SubscribeEvent @@ -65,9 +62,11 @@ object Year300RaffleEvent { SoundUtils.centuryActiveTimerAlert.playSound() lastTimeAlerted = SimpleTimeMark.now() } - overlay = listOf( - Renderable.itemStack(displayItem), - Renderable.string("§eTime Left: ${timeLeft.format()}") + overlay = Renderable.verticalContainer( + listOf( + Renderable.itemStack(displayItem), + Renderable.string("§eTime Left: ${timeLeft.format()}") + ) ) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/winter/JyrreTimer.kt b/src/main/java/at/hannibal2/skyhanni/features/event/winter/JyrreTimer.kt index 513753f2c383..8403f5336d45 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/winter/JyrreTimer.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/winter/JyrreTimer.kt @@ -7,13 +7,15 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.ProfileJoinEvent import at.hannibal2.skyhanni.events.SecondPassedEvent import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.CollectionUtils.addItemStack +import at.hannibal2.skyhanni.utils.CollectionUtils.addString import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.toInternalName import at.hannibal2.skyhanni.utils.NEUItems.getItemStack import at.hannibal2.skyhanni.utils.RegexUtils.matches -import at.hannibal2.skyhanni.utils.RenderUtils.addItemIcon -import at.hannibal2.skyhanni.utils.RenderUtils.renderSingleLineWithItems +import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderable import at.hannibal2.skyhanni.utils.TimeUtils.format +import at.hannibal2.skyhanni.utils.renderables.Renderable import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.time.Duration.Companion.minutes @@ -25,9 +27,9 @@ object JyrreTimer { private val config get() = SkyHanniMod.feature.event.winter.jyrreTimer private val drankBottlePattern by RepoPattern.pattern( "event.winter.drank.jyrre", - "§aYou drank a §r§6Refined Bottle of Jyrre §r§aand gained §r§b\\+300✎ Intelligence §r§afor §r§b60 minutes§r§a!" + "§aYou drank a §r§6Refined Bottle of Jyrre §r§aand gained §r§b\\+300✎ Intelligence §r§afor §r§b60 minutes§r§a!", ) - private var display = emptyList() + private var display: Renderable? = null private var duration = 0.seconds @HandleEvent @@ -36,8 +38,8 @@ object JyrreTimer { } private fun resetDisplay() { - if (display.isEmpty()) return - display = if (config.showInactive) drawDisplay() else emptyList() + if (display == null) return + display = if (config.showInactive) drawDisplay() else null duration = 0.seconds } @@ -50,14 +52,14 @@ object JyrreTimer { @SubscribeEvent fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { if (!isEnabled()) return - config.pos.renderSingleLineWithItems(display, posLabel = "Refined Jyrre Timer") + config.pos.renderRenderable(display, posLabel = "Refined Jyrre Timer") } @SubscribeEvent fun onSecondPassed(event: SecondPassedEvent) { if (!isEnabled()) return - if (display.isNotEmpty() && !config.showInactive && duration <= 0.seconds) { + if (display != null && !config.showInactive && duration <= 0.seconds) { resetDisplay() return } @@ -67,20 +69,21 @@ object JyrreTimer { private val displayIcon by lazy { "REFINED_BOTTLE_OF_JYRRE".toInternalName().getItemStack() } - fun drawDisplay(): MutableList { + fun drawDisplay(): Renderable { duration -= 1.seconds - return mutableListOf().apply { - addItemIcon(displayIcon) - add("§aJyrre Boost: ") + return Renderable.horizontalContainer( + buildList { + addItemStack(displayIcon) + addString("§aJyrre Boost: ") - if (duration <= 0.seconds && config.showInactive) { - add("§cInactive!") - } else { - val format = duration.format() - add("§b$format") - } - } + if (duration <= 0.seconds && config.showInactive) { + addString("§cInactive!") + } else { + addString("§b${duration.format()}") + } + }, + ) } private fun isEnabled() = LorenzUtils.inSkyBlock && config.enabled diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt index 2753c95616d5..04f720a2c2a5 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt @@ -41,7 +41,6 @@ import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.NEUItems -import at.hannibal2.skyhanni.utils.RenderUtils.addItemIcon import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getCultivatingCounter import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHoeCounter import at.hannibal2.skyhanni.utils.renderables.Renderable @@ -172,16 +171,7 @@ object GardenAPI { fun readCounter(itemStack: ItemStack): Long = itemStack.getHoeCounter() ?: itemStack.getCultivatingCounter() ?: -1L - @Deprecated("use renderable list instead", ReplaceWith("")) - fun MutableList.addCropIcon( - crop: CropType, - scale: Double = NEUItems.itemFontSize, - highlight: Boolean = false, - ) = - addItemIcon(crop.icon.copy(), highlight, scale = scale) - - // TODO rename to addCropIcon - fun MutableList.addCropIconRenderable( + fun MutableList.addCropIcon( crop: CropType, scale: Double = NEUItems.itemFontSize, highlight: Boolean = false, diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt index ebbdd8907c75..ba65aab79a74 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt @@ -18,13 +18,14 @@ import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.APIUtils import at.hannibal2.skyhanni.utils.ChatUtils +import at.hannibal2.skyhanni.utils.CollectionUtils.addString import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.HypixelCommands import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher -import at.hannibal2.skyhanni.utils.RenderUtils.renderSingleLineWithItems +import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderable import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark @@ -34,6 +35,7 @@ import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.TabListData import at.hannibal2.skyhanni.utils.TimeUtils.format import at.hannibal2.skyhanni.utils.json.toJsonArray +import at.hannibal2.skyhanni.utils.renderables.Renderable import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import com.google.gson.Gson import com.google.gson.JsonPrimitive @@ -59,7 +61,7 @@ import kotlin.time.Duration.Companion.seconds object GardenNextJacobContest { private val dispatcher = Dispatchers.IO - private var display = emptyList() + private var display: Renderable? = null private var simpleDisplay = emptyList() var contests = mutableMapOf() private var inCalendar = false @@ -67,7 +69,7 @@ object GardenNextJacobContest { private val patternGroup = RepoPattern.group("garden.nextcontest") val dayPattern by patternGroup.pattern( "day", - "§aDay (?.*)" + "§aDay (?.*)", ) /** @@ -77,11 +79,11 @@ object GardenNextJacobContest { */ val monthPattern by patternGroup.pattern( "month", - "(?(?:\\w+ )?(?:Summer|Spring|Winter|Autumn)), Year (?\\d+)" + "(?(?:\\w+ )?(?:Summer|Spring|Winter|Autumn)), Year (?\\d+)", ) private val cropPattern by patternGroup.pattern( "crop", - "§(?:e○|6☘) §7(?.*)" + "§(?:e○|6☘) §7(?.*)", ) private const val CLOSE_TO_NEW_YEAR_TEXT = "§7Close to new SB year!" @@ -111,7 +113,7 @@ object GardenNextJacobContest { add("Current time: ${SimpleTimeMark.now()}") add("") - val display = display.filterIsInstance().joinToString("") + // TODO Renderable.toString() add("Display: '$display'") add("") @@ -254,7 +256,7 @@ object GardenNextJacobContest { "§2Click here to submit this year's farming contests. Thank you for helping everyone out!", onClick = { shareContests() }, "§eClick to submit!", - oneTimeClick = true + oneTimeClick = true, ) } } @@ -310,7 +312,7 @@ object GardenNextJacobContest { ChatUtils.chat("§2Enabled automatic sharing of future contests!") }, "§eClick to enable autosharing!", - oneTimeClick = true + oneTimeClick = true, ) } } @@ -328,82 +330,76 @@ object GardenNextJacobContest { } display = if (isFetchingContests) { - listOf("§cFetching this years jacob contests...") + Renderable.string("§cFetching this years jacob contests...") } else { fetchContestsIfAble() // Will only run when needed/enabled drawDisplay() } } - private fun drawDisplay(): List { - val list = mutableListOf() + private fun drawDisplay() = Renderable.horizontalContainer( + buildList { + if (inCalendar) { + val size = contests.size + val percentage = size.toDouble() / MAX_CONTESTS_PER_YEAR + val formatted = LorenzUtils.formatPercentage(percentage) + addString("§eDetected $formatted of farming contests this year") + return@buildList + } - if (inCalendar) { - val size = contests.size - val percentage = size.toDouble() / MAX_CONTESTS_PER_YEAR - val formatted = LorenzUtils.formatPercentage(percentage) - list.add("§eDetected $formatted of farming contests this year") + if (contests.isEmpty()) { + if (isCloseToNewYear()) { + addString(CLOSE_TO_NEW_YEAR_TEXT) + } else { + addString("§cOpen calendar to read Jacob contest times!") + } + return@buildList + } - return list - } + val nextContest = contests.values.filterNot { it.endTime.isInPast() }.minByOrNull { it.endTime } + + // Show next contest + if (nextContest != null) { + addAll(drawNextContest(nextContest)) + return@buildList + } - if (contests.isEmpty()) { if (isCloseToNewYear()) { - list.add(CLOSE_TO_NEW_YEAR_TEXT) + addString(CLOSE_TO_NEW_YEAR_TEXT) } else { - list.add("§cOpen calendar to read Jacob contest times!") + addString("§cOpen calendar to read Jacob contest times!") } - return list - } - val nextContest = - contests.filter { !it.value.endTime.isInPast() }.toSortedMap() - .firstNotNullOfOrNull { it.value } - // Show next contest - if (nextContest != null) return drawNextContest(nextContest, list) - - if (isCloseToNewYear()) { - list.add(CLOSE_TO_NEW_YEAR_TEXT) - } else { - list.add("§cOpen calendar to read Jacob contest times!") - } - - fetchedFromElite = false - contests.clear() + fetchedFromElite = false + contests.clear() + }, + ) - return list - } - private fun drawNextContest( - nextContest: FarmingContest, - list: MutableList, - ): MutableList { + private fun drawNextContest(nextContest: FarmingContest) = buildList { var duration = nextContest.endTime.timeUntil() if (duration > 4.days) { - list.add(CLOSE_TO_NEW_YEAR_TEXT) - return list + addString(CLOSE_TO_NEW_YEAR_TEXT) + return@buildList } val boostedCrop = calculateBoostedCrop(nextContest) val activeContest = duration < contestDuration if (activeContest) { - list.add("§aActive: ") + addString("§aActive: ") } else { - list.add("§eNext: ") + addString("§eNext: ") duration -= contestDuration } for (crop in nextContest.crops) { - list.addCropIcon(crop, 1.0, highlight = (crop == boostedCrop)) + addCropIcon(crop, 1.0, highlight = (crop == boostedCrop)) nextContestCrops.add(crop) } if (!activeContest) { warn(duration, nextContest.crops, boostedCrop) } - val format = duration.format() - list.add("§7(§b$format§7)") - - return list + addString("§7(§b${duration.format()}§7)") } private fun calculateBoostedCrop(nextContest: FarmingContest): CropType? { @@ -439,10 +435,7 @@ object GardenNextJacobContest { } if (config.warnPopup && !Display.isActive()) { SkyHanniMod.coroutineScope.launch { - openPopupWindow( - "Farming Contest soon!
" + - "Crops: $cropTextNoColor" - ) + openPopupWindow("Farming Contest soon!
Crops: $cropTextNoColor") } } } @@ -456,7 +449,7 @@ object GardenNextJacobContest { } catch (e: java.lang.Exception) { ErrorManager.logErrorWithData( e, "Failed to open a popup window", - "message" to message + "message" to message, ) } @@ -468,11 +461,13 @@ object GardenNextJacobContest { val buttons = mutableListOf() val close = JButton("Ok") - close.addMouseListener(object : MouseAdapter() { - override fun mouseClicked(event: MouseEvent) { - frame.isVisible = false - } - }) + close.addMouseListener( + object : MouseAdapter() { + override fun mouseClicked(event: MouseEvent) { + frame.isVisible = false + } + }, + ) buttons.add(close) val allOptions = buttons.toTypedArray() @@ -484,7 +479,7 @@ object GardenNextJacobContest { JOptionPane.INFORMATION_MESSAGE, null, allOptions, - allOptions[0] + allOptions[0], ) } @@ -494,10 +489,10 @@ object GardenNextJacobContest { fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { if (!isEnabled()) return - if (display.isEmpty()) { + if (display == null) { config.pos.renderStrings(simpleDisplay, posLabel = "Next Jacob Contest") } else { - config.pos.renderSingleLineWithItems(display, posLabel = "Next Jacob Contest") + config.pos.renderRenderable(display, posLabel = "Next Jacob Contest") } } @@ -506,10 +501,10 @@ object GardenNextJacobContest { if (!config.display) return if (!inCalendar) return - if (display.isNotEmpty()) { - SkyHanniMod.feature.misc.inventoryLoadPos.renderSingleLineWithItems( + if (display != null) { + SkyHanniMod.feature.misc.inventoryLoadPos.renderRenderable( display, - posLabel = "Load SkyBlock Calendar" + posLabel = "Load SkyBlock Calendar", ) } } @@ -567,12 +562,12 @@ object GardenNextJacobContest { } else { ChatUtils.chat( "This year's contests aren't available to fetch automatically yet, " + - "please load them from your calendar or wait 10 minutes." + "please load them from your calendar or wait 10 minutes.", ) ChatUtils.clickableChat( "Click here to open your calendar!", onClick = { HypixelCommands.calendar() }, - "§eClick to run /calendar!" + "§eClick to run /calendar!", ) } @@ -589,7 +584,7 @@ object GardenNextJacobContest { } catch (e: Exception) { ErrorManager.logErrorWithData( e, - "Failed to fetch upcoming contests. Please report this error if it continues to occur" + "Failed to fetch upcoming contests. Please report this error if it continues to occur", ) } @@ -625,13 +620,13 @@ object GardenNextJacobContest { } else { ErrorManager.logErrorStateWithData( "Something went wrong submitting upcoming contests!", - "submitContestsToElite not successful" + "submitContestsToElite not successful", ) } } catch (e: Exception) { ErrorManager.logErrorWithData( e, "Failed to submit upcoming contests. Please report this error if it continues to occur.", - "contests" to contests + "contests" to contests, ) null } diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt index d441fab1015e..8c008df43065 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenBestCropTime.kt @@ -13,17 +13,18 @@ import at.hannibal2.skyhanni.features.garden.GardenAPI.addCropIcon import at.hannibal2.skyhanni.features.garden.GardenNextJacobContest import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule -import at.hannibal2.skyhanni.utils.CollectionUtils.addAsSingletonList +import at.hannibal2.skyhanni.utils.CollectionUtils.addString import at.hannibal2.skyhanni.utils.CollectionUtils.sorted import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.TimeUnit import at.hannibal2.skyhanni.utils.TimeUtils.format +import at.hannibal2.skyhanni.utils.renderables.Renderable import kotlin.time.Duration.Companion.milliseconds @SkyHanniModule object GardenBestCropTime { - var display = emptyList>() + var display: Renderable? = null private val config get() = GardenAPI.config.cropMilestones val timeTillNextCrop = mutableMapOf() @@ -56,82 +57,86 @@ object GardenBestCropTime { } } - fun drawBestDisplay(currentCrop: CropType?): List> { - val newList = mutableListOf>() - if (timeTillNextCrop.size < CropType.entries.size) { - updateTimeTillNextCrop() - } - - val gardenExp = config.next.bestType == NextConfig.BestTypeEntry.GARDEN_EXP - val useOverflow = config.overflow.bestCropTime - val sorted = if (gardenExp) { - val helpMap = mutableMapOf() - for ((crop, time) in timeTillNextCrop) { - if (crop.isMaxed(useOverflow)) continue - val currentTier = - GardenCropMilestones.getTierForCropCount(crop.getCounter(), crop, allowOverflow = true) - val gardenExpForTier = getGardenExpForTier(currentTier + 1) - val fakeTime = time / gardenExpForTier - helpMap[crop] = fakeTime + fun drawBestDisplay(currentCrop: CropType?) = Renderable.verticalContainer( + buildList { + if (timeTillNextCrop.size < CropType.entries.size) { + updateTimeTillNextCrop() } - helpMap.sorted() - } else { - timeTillNextCrop.sorted() - } - - if (!config.next.bestHideTitle) { - val title = if (gardenExp) "§2Garden Experience" else "§bSkyBlock Level" - if (config.next.bestCompact) { - newList.addAsSingletonList("§eBest Crop Time") + val gardenExp = config.next.bestType == NextConfig.BestTypeEntry.GARDEN_EXP + val useOverflow = config.overflow.bestCropTime + val sorted = if (gardenExp) { + val helpMap = mutableMapOf() + for ((crop, time) in timeTillNextCrop) { + if (crop.isMaxed(useOverflow)) continue + val currentTier = + GardenCropMilestones.getTierForCropCount(crop.getCounter(), crop, allowOverflow = true) + val gardenExpForTier = getGardenExpForTier(currentTier + 1) + val fakeTime = time / gardenExpForTier + helpMap[crop] = fakeTime + } + helpMap.sorted() } else { - newList.addAsSingletonList("§eBest Crop Time §7($title§7)") + timeTillNextCrop.sorted() } - } - - if (!config.progress) { - newList.addAsSingletonList("§cCrop Milestone Progress Display is disabled!") - return newList - } - if (sorted.isEmpty()) { - newList.addAsSingletonList("§cFarm crops to add them to this list!") - return newList - } - var number = 0 - for (crop in sorted.keys) { - if (crop.isMaxed(useOverflow)) continue - val millis = timeTillNextCrop[crop]?.milliseconds ?: continue - // TODO, change functionality to use enum rather than ordinals - val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get().ordinal] - val duration = millis.format(biggestUnit, maxUnits = 2) - val isCurrent = crop == currentCrop - number++ - if (number > config.next.showOnlyBest && (!config.next.showCurrent || !isCurrent)) continue - - val list = mutableListOf() - if (!config.next.bestCompact) { - list.add("§7$number# ") + if (!config.next.bestHideTitle) { + val title = if (gardenExp) "§2Garden Experience" else "§bSkyBlock Level" + if (config.next.bestCompact) { + addString("§eBest Crop Time") + } else { + addString("§eBest Crop Time §7($title§7)") + } } - list.addCropIcon(crop) - val color = if (isCurrent) "§e" else "§7" - val contestFormat = if (GardenNextJacobContest.isNextCrop(crop)) "§n" else "" - val currentTier = GardenCropMilestones.getTierForCropCount(crop.getCounter(), crop, allowOverflow = true) - val nextTier = if (config.bestShowMaxedNeeded.get()) 46 else currentTier + 1 + if (!config.progress) { + addString("§cCrop Milestone Progress Display is disabled!") + return@buildList + } - val cropName = if (!config.next.bestCompact) crop.cropName + " " else "" - val tier = if (!config.next.bestCompact) "$currentTier➜$nextTier§r " else "" - list.add("$color$contestFormat$cropName$tier§b$duration") + if (sorted.isEmpty()) { + addString("§cFarm crops to add them to this list!") + return@buildList + } - if (gardenExp && !config.next.bestCompact) { - val gardenExpForTier = getGardenExpForTier(nextTier) - list.add(" §7(§2$gardenExpForTier §7Exp)") + sorted.keys.withIndex().forEach { (index, crop) -> + createCropEntry(crop, index + 1, useOverflow, gardenExp, currentCrop)?.let(::add) } - newList.add(list) - } - return newList + }, + ) + + private fun createCropEntry(crop: CropType, index: Int, useOverflow: Boolean, gardenExp: Boolean, currentCrop: CropType?): Renderable? { + if (crop.isMaxed(useOverflow)) return null + val millis = timeTillNextCrop[crop]?.milliseconds ?: return null + // TODO, change functionality to use enum rather than ordinals + val biggestUnit = TimeUnit.entries[config.highestTimeFormat.get().ordinal] + val duration = millis.format(biggestUnit, maxUnits = 2) + val isCurrent = crop == currentCrop + if (index > config.next.showOnlyBest && (!config.next.showCurrent || !isCurrent)) return null + + return Renderable.horizontalContainer( + buildList { + if (!config.next.bestCompact) { + addString("§7$index# ") + } + addCropIcon(crop) + + val color = if (isCurrent) "§e" else "§7" + val contestFormat = if (GardenNextJacobContest.isNextCrop(crop)) "§n" else "" + val currentTier = GardenCropMilestones.getTierForCropCount(crop.getCounter(), crop, allowOverflow = true) + val nextTier = if (config.bestShowMaxedNeeded.get()) 46 else currentTier + 1 + + val cropName = if (!config.next.bestCompact) crop.cropName + " " else "" + val tier = if (!config.next.bestCompact) "$currentTier➜$nextTier§r " else "" + addString("$color$contestFormat$cropName$tier§b$duration") + + if (gardenExp && !config.next.bestCompact) { + val gardenExpForTier = getGardenExpForTier(nextTier) + addString(" §7(§2$gardenExpForTier §7Exp)") + } + }, + ) } private fun getGardenExpForTier(gardenLevel: Int) = if (gardenLevel > 30) 300 else gardenLevel * 10 diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt index fbf9a4cf18dd..81c4b340f5a7 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/GardenCropMilestoneDisplay.kt @@ -18,7 +18,7 @@ import at.hannibal2.skyhanni.events.garden.farming.CropMilestoneUpdateEvent import at.hannibal2.skyhanni.features.garden.CropType import at.hannibal2.skyhanni.features.garden.FarmingFortuneDisplay import at.hannibal2.skyhanni.features.garden.GardenAPI -import at.hannibal2.skyhanni.features.garden.GardenAPI.addCropIconRenderable +import at.hannibal2.skyhanni.features.garden.GardenAPI.addCropIcon import at.hannibal2.skyhanni.features.garden.GardenAPI.getCropType import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.setSpeed import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule @@ -29,8 +29,8 @@ import at.hannibal2.skyhanni.utils.ConfigUtils import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.NumberUtil.roundTo +import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderable import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables -import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.SoundUtils import at.hannibal2.skyhanni.utils.TimeUnit @@ -76,17 +76,17 @@ object GardenCropMilestoneDisplay { if (GardenAPI.hideExtraGuis()) return config.progressDisplayPos.renderRenderables( - progressDisplay, posLabel = "Crop Milestone Progress" + progressDisplay, posLabel = "Crop Milestone Progress", ) if (config.mushroomPetPerk.enabled) { config.mushroomPetPerk.pos.renderRenderables( - mushroomCowPerkDisplay, posLabel = "Mushroom Cow Perk" + mushroomCowPerkDisplay, posLabel = "Mushroom Cow Perk", ) } if (config.next.bestDisplay) { - config.next.displayPos.renderStringsAndItems(GardenBestCropTime.display, posLabel = "Best Crop Time") + config.next.displayPos.renderRenderable(GardenBestCropTime.display, posLabel = "Best Crop Time") } } @@ -131,7 +131,7 @@ object GardenCropMilestoneDisplay { fun update() { progressDisplay = emptyList() mushroomCowPerkDisplay = emptyList() - GardenBestCropTime.display = emptyList() + GardenBestCropTime.display = null val currentCrop = GardenAPI.getCurrentlyFarmedCrop() currentCrop?.let { progressDisplay = drawProgressDisplay(it) @@ -158,13 +158,13 @@ object GardenCropMilestoneDisplay { lineMap[MilestoneTextEntry.MILESTONE_TIER] = Renderable.horizontalContainer( buildList { - addCropIconRenderable(crop) + addCropIcon(crop) if (crop.isMaxed(overflowDisplay) && !overflowDisplay) { addString("§7" + crop.cropName + " §eMAXED") } else { addString("§7" + crop.cropName + " §8$currentTier➜§3$nextTier") } - } + }, ) val allowOverflowOrCustom = overflowDisplay || useCustomGoal @@ -306,9 +306,9 @@ object GardenCropMilestoneDisplay { lineMap[MushroomTextEntry.TITLE] = Renderable.string("§6Mooshroom Cow Perk") lineMap[MushroomTextEntry.MUSHROOM_TIER] = Renderable.horizontalContainer( buildList { - addCropIconRenderable(mushroom) + addCropIcon(mushroom) addString("§7Mushroom Milestone $nextTier") - } + }, ) lineMap[MushroomTextEntry.NUMBER_OUT_OF_TOTAL] = Renderable.string("§e$haveFormat§8/§e$needFormat") @@ -356,21 +356,21 @@ object GardenCropMilestoneDisplay { event.move( 11, "garden.cropMilestones.highestTimeFormat", - "garden.cropMilestones.highestTimeFormat" + "garden.cropMilestones.highestTimeFormat", ) { element -> ConfigUtils.migrateIntToEnum(element, TimeFormatEntry::class.java) } event.move( 11, "garden.cropMilestones.text", - "garden.cropMilestones.text" + "garden.cropMilestones.text", ) { element -> ConfigUtils.migrateIntArrayListToEnumArrayList(element, MilestoneTextEntry::class.java) } event.move( 11, "garden.cropMilestones.mushroomPetPerk.text", - "garden.cropMilestones.mushroomPetPerk.text" + "garden.cropMilestones.mushroomPetPerk.text", ) { element -> ConfigUtils.migrateIntArrayListToEnumArrayList(element, MushroomTextEntry::class.java) } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt index 3e3b6e394a06..18bc0b7f670f 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt @@ -312,15 +312,15 @@ object CollectionUtils { add(Renderable.itemStack(itemStack, scale = scale)) } + fun MutableList.addItemStack(internalName: NEUInternalName) { + addItemStack(internalName.getItemStack()) + } + fun takeColumn(start: Int, end: Int, startColumn: Int, endColumn: Int, rowSize: Int = 9) = generateSequence(start) { it + 1 }.map { (it / (endColumn - startColumn)) * rowSize + (it % (endColumn - startColumn)) + startColumn }.takeWhile { it <= end } - fun MutableList.addItemStack(internalName: NEUInternalName) { - addItemStack(internalName.getItemStack()) - } - // TODO move to RenderableUtils inline fun > MutableList.addSelector( prefix: String, diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index a6f92fb10932..cfefe74581ea 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -13,12 +13,11 @@ import at.hannibal2.skyhanni.features.misc.PatcherFixes import at.hannibal2.skyhanni.features.misc.RoundedRectangleOutlineShader import at.hannibal2.skyhanni.features.misc.RoundedRectangleShader import at.hannibal2.skyhanni.features.misc.RoundedTextureShader -import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.CollectionUtils.zipWithNext3 import at.hannibal2.skyhanni.utils.ColorUtils.getFirstColorCode import at.hannibal2.skyhanni.utils.LorenzColor.Companion.toLorenzColor import at.hannibal2.skyhanni.utils.LorenzUtils.getCorners -import at.hannibal2.skyhanni.utils.compat.EnchantmentsCompat +import at.hannibal2.skyhanni.utils.RenderUtils.drawRoundRect import at.hannibal2.skyhanni.utils.compat.GuiScreenUtils import at.hannibal2.skyhanni.utils.renderables.Renderable import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXAligned @@ -36,7 +35,6 @@ import net.minecraft.client.renderer.WorldRenderer import net.minecraft.client.renderer.vertex.DefaultVertexFormats import net.minecraft.entity.Entity import net.minecraft.inventory.Slot -import net.minecraft.item.ItemStack import net.minecraft.util.AxisAlignedBB import net.minecraft.util.MathHelper import net.minecraft.util.ResourceLocation @@ -649,64 +647,6 @@ object RenderUtils { this.renderRenderablesDouble(render, extraSpace, posLabel, true) } - /** - * Accepts a single line to print. - * This line is a list of things to print. Can print String or ItemStack objects. - */ - @Deprecated("use List", ReplaceWith("")) - fun Position.renderSingleLineWithItems( - list: List, - posLabel: String, - ) { - if (list.isEmpty()) return - renderRenderable( - Renderable.horizontalContainer( - list.mapNotNull { Renderable.fromAny(it) }, - ), - posLabel = posLabel, - ) - // TODO Future write that better - } - - private fun Position.renderLine(line: List, offsetY: Int, itemScale: Double = NEUItems.itemFontSize): Int { - GlStateManager.pushMatrix() - val (x, y) = transform() - GlStateManager.translate(0f, offsetY.toFloat(), 0F) - var offsetX = 0 - Renderable.withMousePosition(x, y) { - for (any in line) { - val renderable = Renderable.fromAny(any, itemScale = itemScale) - ?: throw RuntimeException("Unknown render object: $any") - renderable.render(offsetX, offsetY) - offsetX += renderable.width - GlStateManager.translate(renderable.width.toFloat(), 0F, 0F) - } - } - GlStateManager.popMatrix() - return offsetX - } - - @Deprecated("use renderable item list", ReplaceWith("")) - fun MutableList.addItemIcon( - item: ItemStack, - highlight: Boolean = false, - scale: Double = NEUItems.itemFontSize, - ) { - try { - if (highlight) { - // Hack to add enchant glint, like Hypixel does it - item.addEnchantment(EnchantmentsCompat.PROTECTION.enchantment, 0) - } - add(Renderable.itemStack(item, scale)) - } catch (e: NullPointerException) { - ErrorManager.logErrorWithData( - e, - "Add item icon to renderable list", - "item" to item, - ) - } - } - // totally not modified Autumn Client's TargetStrafe fun drawCircle(entity: Entity, partialTicks: Float, rad: Double, color: Color) { GlStateManager.pushMatrix() diff --git a/versions/1.8.9/detekt/baseline.xml b/versions/1.8.9/detekt/baseline.xml index c9ef245f4622..c555f80234ba 100644 --- a/versions/1.8.9/detekt/baseline.xml +++ b/versions/1.8.9/detekt/baseline.xml @@ -168,8 +168,8 @@ RepoPatternRegexTest:GardenLevelDisplay.kt$GardenLevelDisplay$by patternGroup.pattern( "inventory.name", "Garden (?:Desk|Level (?<currentLevel>.*))" ) RepoPatternRegexTest:GardenLevelDisplay.kt$GardenLevelDisplay$by patternGroup.pattern( "inventory.nextxp", ".* §e(?<nextLevelExp>.*)§6/.*" ) RepoPatternRegexTest:GardenLevelDisplay.kt$GardenLevelDisplay$by patternGroup.pattern( "inventory.overflow", ".*§r §6(?<overflow>.*)" ) - RepoPatternRegexTest:GardenNextJacobContest.kt$GardenNextJacobContest$by patternGroup.pattern( "crop", "§(?:e○|6☘) §7(?<crop>.*)" ) - RepoPatternRegexTest:GardenNextJacobContest.kt$GardenNextJacobContest$by patternGroup.pattern( "day", "§aDay (?<day>.*)" ) + RepoPatternRegexTest:GardenNextJacobContest.kt$GardenNextJacobContest$by patternGroup.pattern( "crop", "§(?:e○|6☘) §7(?<crop>.*)", ) + RepoPatternRegexTest:GardenNextJacobContest.kt$GardenNextJacobContest$by patternGroup.pattern( "day", "§aDay (?<day>.*)", ) RepoPatternRegexTest:GardenPlotAPI.kt$GardenPlotAPI$by patternGroup.pattern( "spray.target", "§a§lSPRAYONATOR! §r§7You sprayed §r§aPlot §r§7- §r§b(?<plot>.*) §r§7with §r§a(?<spray>.*)§r§7!" ) RepoPatternRegexTest:GlacitePowderFeatures.kt$GlacitePowderFeatures$by patternGroup.pattern( "glacitepowder", "Glacite Powder x(?<amount>.*)" ) RepoPatternRegexTest:HighlightPlaceableNpcs.kt$HighlightPlaceableNpcs$by patternGroup.pattern( "location", "§7Location: §f\\[§e\\d+§f, §e\\d+§f, §e\\d+§f]", )