diff options
3 files changed, 113 insertions, 37 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt index f43042bca..474f0e814 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt @@ -16,21 +16,22 @@ import at.hannibal2.skyhanni.utils.APIUtil import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.OSUtils -import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings +import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables import at.hannibal2.skyhanni.utils.StringUtils import at.hannibal2.skyhanni.utils.TimeUtils +import at.hannibal2.skyhanni.utils.renderables.Renderable import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import java.util.Collections class FarmingWeightDisplay { @SubscribeEvent - fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) { - if (isEnabled() && config.eliteFarmingWeightIgnoreLow || weight >= 200) { - config.eliteFarmingWeightPos.renderStrings(display, posLabel = "Farming Weight Display") + fun onRenderOverlay(event: GuiRenderEvent) { + val shouldShow = apiError || (config.eliteFarmingWeightIgnoreLow || weight >= 200) + if (isEnabled() && shouldShow) { + config.eliteFarmingWeightPos.renderRenderables(display, posLabel = "Farming Weight Display") } } @@ -43,19 +44,7 @@ class FarmingWeightDisplay { @SubscribeEvent fun onWorldChange(event: LorenzWorldChangeEvent) { // We want to try to connect to the api again after a world switch. - apiError = false - // We ask both api endpoints after every world switch - weight = -1.0 - weightPerSecond = -1.0 - - leaderboardPosition = -1 - dirtyCropWeight = true - lastLeaderboardUpdate = 0 - - nextPlayers.clear() - rankGoal = -1 - - localCounter.clear() + resetData() } @SubscribeEvent @@ -89,7 +78,7 @@ class FarmingWeightDisplay { private val config get() = SkyHanniMod.feature.garden private val localCounter = mutableMapOf<CropType, Long>() - private var display = emptyList<String>() + private var display = emptyList<Renderable>() private var profileId = "" private var lastLeaderboardUpdate = 0L private var apiError = false @@ -105,18 +94,42 @@ class FarmingWeightDisplay { private var nextPlayers = mutableListOf<UpcomingPlayer>() private val nextPlayer get() = nextPlayers.firstOrNull() + private val recalculate by lazy { + ({ + resetData() + }) + } + + private val errorMessage by lazy { + listOf( + Renderable.clickAndHover( + "§cFarming Weight error: Cannot load", + listOf("§eClick here to reload the data right now!"), + onClick = recalculate + ), Renderable.clickAndHover( + "§cdata from Elite Farmers!", + listOf("§eClick here to reload the data right now!"), + onClick = recalculate + ), Renderable.clickAndHover( + "§eRejoin the garden or", + listOf("§eClick here to reload the data right now!"), + onClick = recalculate + ), Renderable.clickAndHover( + "§eclick here to fix it.", + listOf("§eClick here to reload the data right now!"), + onClick = recalculate + ) + ) + } + private fun update() { if (!GardenAPI.inGarden()) return if (apiError) { - display = listOf( - "§6Farming Weight§7: §cError!", - "§cCannot load data from Elite Farmers!", - "§eRejoin garden to try again." - ) + display = errorMessage return } if (weight == -2.0) { - display = Collections.singletonList("§6Farming Weight§7: §eLoading..") + display = Renderable.singeltonString("§6Farming Weight§7: §eLoading..") return } @@ -124,13 +137,13 @@ class FarmingWeightDisplay { if (!isLoadingWeight) { val localProfile = HypixelData.profileName if (localProfile == "") { - display = Collections.singletonList("§cError: profileName is empty!") + display = Renderable.singeltonString("§cError: profileName is empty!") return } isLoadingWeight = true if (display.isEmpty()) { - display = Collections.singletonList("§cLoading..") + display = Renderable.singeltonString("§6Farming Weight§7: §eLoading..") } SkyHanniMod.coroutineScope.launch { loadWeight(localProfile) @@ -145,11 +158,18 @@ class FarmingWeightDisplay { if (rankGoal == -1) rankGoal = getRankGoal() val leaderboard = getLeaderboard() - val list = mutableListOf<String>() - list.add("§6Farming Weight§7: $weight$leaderboard") + val list = mutableListOf<Renderable>() + list.add(Renderable.clickAndHover( + "§6Farming Weight§7: $weight$leaderboard", + listOf("§eClick to open the Farming Profile of you.") + ) { + openWebsite(LorenzUtils.getPlayerName()) + }) if (isEtaEnabled() && (weightPerSecond != -1.0 || config.eliteFarmingWeightOvertakeETAAlways)) { - list.add(getETA()) + getETA()?.let { + list.add(it) + } } display = list } @@ -205,10 +225,14 @@ class FarmingWeightDisplay { return goal } - private fun getETA(): String { - if (weight < 0) return "" + private fun getETA(): Renderable? { + if (weight < 0) return null - var nextPlayer = nextPlayer ?: return "" + val nextPlayer = nextPlayer ?: return Renderable.clickAndHover( + "§cWaiting for leaderboard update...", + listOf("§eClick here to load new data right now!"), + onClick = recalculate + ) var nextName = if (leaderboardPosition == -1 || leaderboardPosition > rankGoal) "#$rankGoal" else nextPlayer.name @@ -233,14 +257,17 @@ class FarmingWeightDisplay { nextPlayers.removeFirst() // Display waiting message if nextPlayers list is empty - nextPlayer = this.nextPlayer ?: return "§cWaiting for leaderboard update..." // Update values to next player nextName = nextPlayer.name weightUntilOvertake = nextPlayer.weight - totalWeight } if (nextPlayer.weight == 0.0) { - return "§cRejoin the garden to show ETA!" + return Renderable.clickAndHover( + "§cRejoin the garden to show ETA!", + listOf("Click here to calculate the data right now!"), + onClick = recalculate + ) } val timeFormat = if (weightPerSecond != -1.0) { @@ -250,7 +277,28 @@ class FarmingWeightDisplay { } else "" val weightFormat = LorenzUtils.formatDouble(weightUntilOvertake, 2) - return "§e$weightFormat$timeFormat §7behind §b$nextName" + return Renderable.clickAndHover( + "§e$weightFormat$timeFormat §7behind §b$nextName", + listOf("§eClick to open the Farming Profile of §b$nextName.") + ) { + openWebsite(nextName) + } + } + + private fun resetData() { + apiError = false + // We ask both api endpoints after every world switch + weight = -1.0 + weightPerSecond = -1.0 + + leaderboardPosition = -1 + dirtyCropWeight = true + lastLeaderboardUpdate = 0 + + nextPlayers.clear() + rankGoal = -1 + + localCounter.clear() } private fun farmingChatMessage(message: String) { @@ -426,6 +474,10 @@ class FarmingWeightDisplay { fun lookUpCommand(it: Array<String>) { val name = if (it.size == 1) it[0] else LorenzUtils.getPlayerName() + openWebsite(name) + } + + private fun openWebsite(name: String?) { OSUtils.openBrowser("https://elitebot.dev/@$name/") LorenzUtils.chat("§e[SkyHanni] Opening Farming Profile of player §b$name") } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index ce676656e..dce61bf03 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -5,6 +5,7 @@ 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.events.GuiRenderItemEvent +import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList import at.hannibal2.skyhanni.utils.renderables.Renderable import io.github.moulberry.moulconfig.internal.TextRenderUtils import io.github.moulberry.notenoughupdates.util.Utils @@ -402,6 +403,20 @@ object RenderUtils { GuiEditManager.add(this, posLabel, longestX, offsetY) } + fun Position.renderRenderables( + renderables: List<Renderable>, + extraSpace: Int = 0, + itemScale: Double = 1.0, + posLabel: String, + ) { + if (renderables.isEmpty()) return + val list = mutableListOf<List<Any>>() + for (line in renderables) { + list.addAsSingletonList(line) + } + renderStringsAndItems(list, extraSpace, itemScale, posLabel) + } + /** * Accepts a list of lines to print. * Each line is a list of things to print. Can print String or ItemStack objects. diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt index a4a3f1460..8884e5452 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt @@ -13,6 +13,7 @@ import net.minecraft.client.gui.inventory.GuiEditSign import net.minecraft.client.renderer.GlStateManager import net.minecraft.item.ItemStack import org.lwjgl.input.Mouse +import java.util.Collections import kotlin.math.max interface Renderable { @@ -105,7 +106,11 @@ interface Renderable { override fun render(posX: Int, posY: Int) { val isDown = Mouse.isButtonDown(button) - if (isDown > wasDown && isHovered(posX, posY) && condition() && shouldAllowLink(true, bypassChecks)) { + if (isDown > wasDown && isHovered(posX, posY) && condition() && shouldAllowLink( + true, + bypassChecks + ) + ) { onClick() } wasDown = isDown @@ -227,6 +232,10 @@ interface Renderable { } } + fun singeltonString(string: String): List<Renderable> { + return Collections.singletonList(string(string)) + } + fun string(string: String) = object : Renderable { override val width: Int get() = Minecraft.getMinecraft().fontRendererObj.getStringWidth(string) |