diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/chat/notifications/ChatNotifications.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/chat/notifications/ChatNotifications.kt index cd025b81..342f3908 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/chat/notifications/ChatNotifications.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/chat/notifications/ChatNotifications.kt @@ -51,7 +51,7 @@ object ChatNotifications { if(display == null) display = it.colorFormattedDisplay SoundUtils.dingHighSound.play() - RenderUtils.drawTitle(display, NobaColor.WHITE, 2.75f, duration = 2.seconds, id = "chat_notification") + RenderUtils.drawTitle(display, color = NobaColor.WHITE, scale = 2.75f, duration = 2.seconds, id = "chat_notification") return } } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/chocolatefactory/ChocolateFactoryFeatures.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/chocolatefactory/ChocolateFactoryFeatures.kt index b4235a33..7d67e27b 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/chocolatefactory/ChocolateFactoryFeatures.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/chocolatefactory/ChocolateFactoryFeatures.kt @@ -41,7 +41,7 @@ object ChocolateFactoryFeatures { if(event.itemInHand.skyBlockId != HoppityAPI.LOCATOR) return if(hasMythicRabbitSpawned) return - RenderUtils.drawTitle(tr("nobaaddons.chocolateFactory.spawnMythicRabbit", "Spawn Mythic Rabbit!"), NobaColor.RED) + RenderUtils.drawTitle(tr("nobaaddons.chocolateFactory.spawnMythicRabbit", "Spawn Mythic Rabbit!"), color = NobaColor.RED) } private fun onSendCommand(event: SendMessageEvents.SendCommand) { diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/dungeons/HighlightStarredMobs.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/dungeons/HighlightStarredMobs.kt index 8d179c5c..31c17e69 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/dungeons/HighlightStarredMobs.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/dungeons/HighlightStarredMobs.kt @@ -2,66 +2,62 @@ package me.nobaboy.nobaaddons.features.dungeons import me.nobaboy.nobaaddons.api.skyblock.DungeonsAPI import me.nobaboy.nobaaddons.config.NobaConfig -import me.nobaboy.nobaaddons.events.impl.client.TickEvents +import me.nobaboy.nobaaddons.events.impl.client.EntityEvents import me.nobaboy.nobaaddons.events.impl.skyblock.SkyBlockEvents import me.nobaboy.nobaaddons.utils.EntityUtils import me.nobaboy.nobaaddons.utils.MCUtils -import me.nobaboy.nobaaddons.utils.StringUtils.cleanFormatting -import me.nobaboy.nobaaddons.utils.getNobaVec import me.nobaboy.nobaaddons.utils.render.HighlightMode -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderFilled +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderFullBox +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderOutline import me.owdding.ktmodules.Module import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents +import net.minecraft.entity.LivingEntity import net.minecraft.entity.decoration.ArmorStandEntity -// TODO Rework and implement Entity outlines @Module object HighlightStarredMobs { private val config get() = NobaConfig.dungeons.highlightStarredMobs private val enabled: Boolean get() = config.enabled && !DungeonsAPI.inBoss() - private val starredMobs = mutableListOf() + private val starredMobs = mutableListOf() init { SkyBlockEvents.ISLAND_CHANGE.register { starredMobs.clear() } - TickEvents.TICK.register { getStarredMobs() } - WorldRenderEvents.AFTER_TRANSLUCENT.register(this::renderHighlights) + EntityEvents.POST_RENDER.register(this::onEntityRender) + WorldRenderEvents.AFTER_TRANSLUCENT.register(this::onWorldRender) } - private fun getStarredMobs() { + private fun onEntityRender(event: EntityEvents.Render) { if(!enabled) return - EntityUtils.getEntities().filter { - it !in starredMobs && - it.hasCustomName() && - it.shouldRenderName() && - it.customName!!.string.cleanFormatting().startsWith("✯ ") && - it.customName!!.string.cleanFormatting().endsWith("❤") - }.forEach { starredMobs.add(it) } + val entity = event.entity as? LivingEntity ?: return + if(entity in starredMobs) return + + val armorStand = EntityUtils.getNextEntity(entity, 1) as? ArmorStandEntity ?: return + if(MCUtils.player?.canSee(armorStand) != true) return + if(!armorStand.shouldRenderName() || !armorStand.hasCustomName()) return + + val armorStandName = armorStand.name.string + if(!armorStandName.startsWith("✯") || !armorStandName.endsWith("❤")) return + + starredMobs.add(entity) } - private fun renderHighlights(context: WorldRenderContext) { + private fun onWorldRender(context: WorldRenderContext) { if(!enabled) return - val player = MCUtils.player ?: return + starredMobs.removeIf { !it.isAlive } val color = config.highlightColor val mode = config.highlightMode - starredMobs.removeIf { !it.isAlive } - for(starredMob in starredMobs) { - if(!player.canSee(starredMob)) continue - - val name = starredMob.customName!!.string.cleanFormatting() - val extraHeight = if("Fels" in name) 2.0 else if("Spider" in name) -0.25 else 1.0 - - val vec = starredMob.getNobaVec() - + starredMobs.forEach { mob -> when(mode) { - HighlightMode.OUTLINE -> RenderUtils.renderOutline(context, vec.add(x = -0.5, y = -1.0, z = -0.5), color, extraSizeBottomY = extraHeight) - HighlightMode.FILLED -> RenderUtils.renderFilledBox(context, vec.add(x = -0.5, y = -1.0, z = -0.5), color, extraSizeBottomY = extraHeight) - HighlightMode.FILLED_OUTLINE -> RenderUtils.renderOutlinedFilledBox(context, vec.add(x = -0.5, y = -1.0, z = -0.5), color, extraSizeBottomY = extraHeight) + HighlightMode.OUTLINE -> context.renderOutline(mob.boundingBox, color) + HighlightMode.FILLED -> context.renderFilled(mob.boundingBox, color) + HighlightMode.FILLED_OUTLINE -> context.renderFullBox(mob.boundingBox, color) } } } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/events/hoppity/HoppityEggGuess.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/events/hoppity/HoppityEggGuess.kt index 2dff1625..4ed1d959 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/events/hoppity/HoppityEggGuess.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/events/hoppity/HoppityEggGuess.kt @@ -15,7 +15,8 @@ import me.nobaboy.nobaaddons.utils.NumberUtils.addSeparators import me.nobaboy.nobaaddons.utils.Timestamp import me.nobaboy.nobaaddons.utils.items.ItemUtils.skyBlockId import me.nobaboy.nobaaddons.utils.math.ParticlePathFitter -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderText +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderWaypoint import me.nobaboy.nobaaddons.utils.tr import me.owdding.ktmodules.Module import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext @@ -38,7 +39,7 @@ object HoppityEggGuess { ParticleEvents.PARTICLE.register(this::onParticle) ItemUseEvent.EVENT.register(this::onItemUse) ChatMessageEvents.CHAT.register(this::onChatMessage) - WorldRenderEvents.AFTER_TRANSLUCENT.register(this::renderWaypoints) + WorldRenderEvents.AFTER_TRANSLUCENT.register(this::onWorldRender) } private fun onParticle(event: ParticleEvents.Particle) { @@ -69,24 +70,22 @@ object HoppityEggGuess { if(event.cleaned.startsWith("HOPPITY'S HUNT You found a Chocolate")) guessLocation = null } - private fun renderWaypoints(context: WorldRenderContext) { + private fun onWorldRender(context: WorldRenderContext) { if(!enabled) return guessLocation?.let { val distance = it.distanceToPlayer() val formattedDistance = distance.toInt().addSeparators() - RenderUtils.renderWaypoint(context, it, NobaColor.AQUA, throughBlocks = true) - RenderUtils.renderText( - context, + context.renderWaypoint(it, NobaColor.AQUA, throughBlocks = true) + context.renderText( it.center().raise(), tr("nobaaddons.events.hoppity.eggGuessWaypoint", "Egg Guess"), color = NobaColor.AQUA, yOffset = -10f, throughBlocks = true ) - RenderUtils.renderText( - context, + context.renderText( it.center().raise(), "${formattedDistance}m", color = NobaColor.GRAY, diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/events/mythological/BurrowWaypoints.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/events/mythological/BurrowWaypoints.kt index 2a421f16..b51dcb37 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/events/mythological/BurrowWaypoints.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/events/mythological/BurrowWaypoints.kt @@ -15,6 +15,8 @@ import me.nobaboy.nobaaddons.utils.TextUtils.toText import me.nobaboy.nobaaddons.utils.Timestamp import me.nobaboy.nobaaddons.utils.chat.ChatUtils import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderText +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderWaypoint import me.nobaboy.nobaaddons.utils.sound.SoundUtils import me.nobaboy.nobaaddons.utils.tr import me.owdding.ktmodules.Module @@ -107,9 +109,8 @@ object BurrowWaypoints { val distance = location.distance(LocationUtils.playerLocation, center = true) - RenderUtils.renderWaypoint(context, location, NobaColor.DARK_RED, throughBlocks = true) - RenderUtils.renderText( - context, + context.renderWaypoint(location, NobaColor.DARK_RED, throughBlocks = true) + context.renderText( adjustedLocation, tr("nobaaddons.events.mythological.inquisitor", "Inquisitor"), color = NobaColor.DARK_RED, @@ -117,8 +118,7 @@ object BurrowWaypoints { hideThreshold = 5.0, throughBlocks = true, ) - RenderUtils.renderText( - context, + context.renderText( adjustedLocation, inquisitor.spawner, color = NobaColor.GOLD, @@ -128,8 +128,7 @@ object BurrowWaypoints { ) if(config.showInquisitorDespawnTime) { - RenderUtils.renderText( - context, + context.renderText( adjustedLocation, tr("nobaaddons.events.mythological.inquisitorDespawnsIn", "Despawns in ${inquisitor.remainingTime}"), color = NobaColor.GRAY, @@ -150,9 +149,8 @@ object BurrowWaypoints { type.displayName } - RenderUtils.renderWaypoint(context, location, type.color, throughBlocks = true) - RenderUtils.renderText( - context, + context.renderWaypoint(location, type.color, throughBlocks = true) + context.renderText( location.center().raise(), text, color = type.color, @@ -171,9 +169,8 @@ object BurrowWaypoints { val distance = it.distance(LocationUtils.playerLocation, center = true) val formattedDistance = distance.toInt().addSeparators() - RenderUtils.renderWaypoint(context, it, NobaColor.AQUA, throughBlocks = distance > 10) - RenderUtils.renderText( - context, + context.renderWaypoint(it, NobaColor.AQUA, throughBlocks = distance > 10) + context.renderText( adjustedLocation, tr("nobaaddons.events.mythological.burrowGuessWaypoint", "Burrow Guess"), color = NobaColor.AQUA, @@ -181,8 +178,7 @@ object BurrowWaypoints { hideThreshold = 5.0, throughBlocks = true, ) - RenderUtils.renderText( - context, + context.renderText( adjustedLocation, "${formattedDistance}m", color = NobaColor.GRAY, @@ -200,7 +196,13 @@ object BurrowWaypoints { nearestWarp = BurrowWarpLocations.getNearestWarp(targetLocation) ?: return lastWarpSuggestTime = Timestamp.now() - RenderUtils.drawTitle(tr("nobaaddons.events.mythological.warpToPoint", "Warp to ${nearestWarp!!.warpPoint}"), NobaColor.GRAY, 2f, 30, 1.seconds) + RenderUtils.drawTitle( + tr("nobaaddons.events.mythological.warpToPoint", "Warp to ${nearestWarp!!.warpPoint}"), + color = NobaColor.GRAY, + scale = 2f, + offset = 30, + duration = 1.seconds + ) } private fun getTargetLocation(): NobaVec? = InquisitorWaypoints.inquisitors.firstOrNull()?.location ?: guessLocation diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/events/mythological/InquisitorWaypoints.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/events/mythological/InquisitorWaypoints.kt index 5fb8d88f..3309f9d9 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/events/mythological/InquisitorWaypoints.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/events/mythological/InquisitorWaypoints.kt @@ -94,7 +94,7 @@ object InquisitorWaypoints { val location = NobaVec(x, y, z) inquisitors.add(Inquisitor(username, location)) - RenderUtils.drawTitle("INQUISITOR!", NobaColor.DARK_RED, subtext = username.toText().gold()) + RenderUtils.drawTitle("INQUISITOR!", subtext = username.toText().gold(), color = NobaColor.DARK_RED) config.notificationSound.play() } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/HotspotWaypoints.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/HotspotWaypoints.kt index a4d7c8f2..7ba158f2 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/HotspotWaypoints.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/HotspotWaypoints.kt @@ -19,7 +19,8 @@ import me.nobaboy.nobaaddons.utils.Timestamp.Companion.toShortString import me.nobaboy.nobaaddons.utils.chat.ChatUtils import me.nobaboy.nobaaddons.utils.chat.ChatUtils.clickAction import me.nobaboy.nobaaddons.utils.chat.HypixelCommands -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderBeacon +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderText import me.nobaboy.nobaaddons.utils.toNobaVec import me.owdding.ktmodules.Module import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext @@ -39,7 +40,7 @@ object HotspotWaypoints { init { SkyBlockEvents.ISLAND_CHANGE.register { hotspots.clear() } EntityEvents.POST_RENDER.register(this::onEntityRender) - WorldRenderEvents.AFTER_TRANSLUCENT.register(this::renderWaypoints) + WorldRenderEvents.AFTER_TRANSLUCENT.register(this::onWorldRender) } private fun onEntityRender(event: EntityEvents.Render) { @@ -63,15 +64,15 @@ object HotspotWaypoints { hotspots.add(hotspot) } - private fun renderWaypoints(context: WorldRenderContext) { + private fun onWorldRender(context: WorldRenderContext) { if(!enabled) return hotspots.removeIf { !it.armorStand.isAlive } hotspots.forEach { val time = it.remainingTime.ifEmpty { "Soon" } - RenderUtils.renderBeaconBeam(context, it.location, it.stat.color) - RenderUtils.renderText(context, it.location.center().raise(1.5), time, throughBlocks = true) + context.renderBeacon(it.location, it.stat.color) + context.renderText(it.location.center().raise(1.5), time, throughBlocks = true) } } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/SeaCreatureAlert.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/SeaCreatureAlert.kt index c1df9345..61dae282 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/SeaCreatureAlert.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/SeaCreatureAlert.kt @@ -43,7 +43,7 @@ object SeaCreatureAlert { val color = seaCreature.rarity.color ?: NobaColor.RED - RenderUtils.drawTitle(text, color, subtext = subtext, id = "sea_creature_alert") + RenderUtils.drawTitle(text, subtext = subtext, color = color, id = "sea_creature_alert") config.notificationSound.play() } } \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/crimsonisle/HighlightThunderSparks.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/crimsonisle/HighlightThunderSparks.kt index 4b89ee2d..644833ee 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/crimsonisle/HighlightThunderSparks.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/crimsonisle/HighlightThunderSparks.kt @@ -10,7 +10,9 @@ import me.nobaboy.nobaaddons.utils.BlockUtils.getBlockStateAt import me.nobaboy.nobaaddons.utils.LocationUtils.distanceToPlayer import me.nobaboy.nobaaddons.utils.getNobaVec import me.nobaboy.nobaaddons.utils.items.ItemUtils.getSkullTexture -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderFullBox +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderText +import me.nobaboy.nobaaddons.utils.tr import me.owdding.ktmodules.Module import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents @@ -28,7 +30,7 @@ object HighlightThunderSparks { init { SkyBlockEvents.ISLAND_CHANGE.register { thunderSparks.clear() } EntityEvents.POST_RENDER.register(this::onEntityRender) - WorldRenderEvents.AFTER_TRANSLUCENT.register(this::renderHighlights) + WorldRenderEvents.AFTER_TRANSLUCENT.register(this::onWorldRender) } private fun onEntityRender(event: EntityEvents.Render) { @@ -41,30 +43,32 @@ object HighlightThunderSparks { thunderSparks.add(entity) } - private fun renderHighlights(context: WorldRenderContext) { + private fun onWorldRender(context: WorldRenderContext) { if(!enabled) return thunderSparks.removeIf { !it.isAlive } + thunderSparks.forEach { - val vec = it.getNobaVec() - val distance = vec.distanceToPlayer() - val block = vec.roundToBlock().add(y = 1).getBlockStateAt() + val location = it.getNobaVec() + val distance = location.distanceToPlayer() + val block = location.roundToBlock().raise().getBlockStateAt() - val throughBlocks = distance < 6 && block.fluidState != null && block.fluidState.fluid is LavaFluid + val throughBlocks = distance < 6 && block.fluidState?.fluid is LavaFluid - RenderUtils.renderOutlinedFilledBox( - context, - vec.add(x = -0.5, z = -0.5), + context.renderFullBox( + location.add(x = -0.5, z = -0.5), config.highlightColor, extraSize = -0.25, throughBlocks = throughBlocks ) - if(config.showText && distance < 10) RenderUtils.renderText( - context, - vec.raise(1.25), - "Thunder Spark", - throughBlocks = throughBlocks - ) + + if(config.showText && distance < 10) { + context.renderText( + location.raise(1.25), + tr("nobaaddons.fishing.thunderSpark", "Thunder Spark"), + throughBlocks = throughBlocks + ) + } } } } \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/inventory/slotinfo/ISlotInfo.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/inventory/slotinfo/ISlotInfo.kt index 790d2b83..089111e1 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/inventory/slotinfo/ISlotInfo.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/inventory/slotinfo/ISlotInfo.kt @@ -6,7 +6,7 @@ import me.nobaboy.nobaaddons.events.impl.render.ScreenRenderEvents import me.nobaboy.nobaaddons.features.inventory.slotinfo.items.* import me.nobaboy.nobaaddons.features.inventory.slotinfo.uielements.* import me.nobaboy.nobaaddons.utils.NobaColor -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawText import me.owdding.ktmodules.Module import net.minecraft.client.font.TextRenderer import net.minecraft.client.gui.DrawContext @@ -86,7 +86,7 @@ interface ISlotInfo { Position.BOTTOM_RIGHT -> context.matrices.translate(16f - width + 1f, textRenderer.fontHeight.toFloat(), 200f) } - RenderUtils.drawText(context, text, x, y, scale) + context.drawText(text, x, y, scale) context.matrices.pop() } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/WormAlert.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/WormAlert.kt index 82143213..16fc8721 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/WormAlert.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/WormAlert.kt @@ -22,7 +22,7 @@ object WormAlert { if(!enabled) return if(event.cleaned == "You hear the sound of something approaching...") { - RenderUtils.drawTitle(tr("nobaaddons.mining.wormAlert.spawned", "Worm Spawned!"), config.alertColor) + RenderUtils.drawTitle(tr("nobaaddons.mining.wormAlert.spawned", "Worm Spawned!"), color = config.alertColor) config.notificationSound.play() } } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/glacitemineshaft/MineshaftWaypoints.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/glacitemineshaft/MineshaftWaypoints.kt index f7494b32..58781d08 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/glacitemineshaft/MineshaftWaypoints.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/glacitemineshaft/MineshaftWaypoints.kt @@ -7,7 +7,8 @@ import me.nobaboy.nobaaddons.utils.LocationUtils import me.nobaboy.nobaaddons.utils.MCUtils import me.nobaboy.nobaaddons.utils.NobaColor import me.nobaboy.nobaaddons.utils.NobaVec -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderText +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderWaypoint import me.nobaboy.nobaaddons.utils.toNobaVec import me.nobaboy.nobaaddons.utils.tr import me.owdding.ktmodules.Module @@ -23,7 +24,7 @@ object MineshaftWaypoints { init { SkyBlockEvents.ISLAND_CHANGE.register(this::onIslandChange) - WorldRenderEvents.AFTER_TRANSLUCENT.register(this::renderWaypoints) + WorldRenderEvents.AFTER_TRANSLUCENT.register(this::onWorldRender) } private fun onIslandChange(event: SkyBlockEvents.IslandChange) { @@ -47,7 +48,7 @@ object MineshaftWaypoints { } } - private fun renderWaypoints(context: WorldRenderContext) { + private fun onWorldRender(context: WorldRenderContext) { if(waypoints.isEmpty()) return waypoints.forEach { @@ -58,9 +59,8 @@ object MineshaftWaypoints { } if(!shouldRender) return - RenderUtils.renderWaypoint(context, it.location, it.color, throughBlocks = true) - RenderUtils.renderText( - context, + context.renderWaypoint(it.location, it.color, throughBlocks = true) + context.renderText( it.location.center(), it.text, yOffset = -5f, diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/MiniBossFeatures.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/MiniBossFeatures.kt index b4033b8b..007c4328 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/MiniBossFeatures.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/MiniBossFeatures.kt @@ -33,7 +33,7 @@ object MiniBossFeatures { if(lastAlert.elapsedSince() < 1.seconds) return if(event.id != EXPLODE || event.volume != 0.6f || event.pitch != 9 / 7f) return - RenderUtils.drawTitle(tr("nobaaddons.slayers.miniBossAlert.spawned", "MiniBoss Spawned!"), config.miniBossAlert.alertColor, duration = 1.5.seconds, id = "slayer_alert") + RenderUtils.drawTitle(tr("nobaaddons.slayers.miniBossAlert.spawned", "MiniBoss Spawned!"), color = config.miniBossAlert.alertColor, duration = 1.5.seconds, id = "slayer_alert") SoundUtils.dingLowSound.play() lastAlert = Timestamp.now() } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/SlayerBossFeatures.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/SlayerBossFeatures.kt index b65b9178..cdebd2a2 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/SlayerBossFeatures.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/SlayerBossFeatures.kt @@ -31,7 +31,7 @@ object SlayerBossFeatures { if(config.bossKillTime.enabled) bossSpawnTime = Timestamp.now() if(config.bossAlert.enabled) { - RenderUtils.drawTitle(tr("nobaaddons.slayers.bossAlert.spawned", "Boss Spawned!"), config.bossAlert.alertColor, duration = 1.5.seconds, id = "slayer_alert") + RenderUtils.drawTitle(tr("nobaaddons.slayers.bossAlert.spawned", "Boss Spawned!"), color = config.bossAlert.alertColor, duration = 1.5.seconds, id = "slayer_alert") SoundUtils.dingLowSound.play() } } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/voidgloom/VoidgloomSeraphFeatures.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/voidgloom/VoidgloomSeraphFeatures.kt index 4937fbe7..5e6c105a 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/voidgloom/VoidgloomSeraphFeatures.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/slayers/voidgloom/VoidgloomSeraphFeatures.kt @@ -21,6 +21,9 @@ import me.nobaboy.nobaaddons.utils.getNobaVec import me.nobaboy.nobaaddons.utils.items.ItemUtils.getSkullTexture import me.nobaboy.nobaaddons.utils.render.EntityOverlay.highlight import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderFullBox +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderOutline +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderText import me.nobaboy.nobaaddons.utils.sound.SoundUtils import me.nobaboy.nobaaddons.utils.toNobaVec import me.nobaboy.nobaaddons.utils.tr @@ -121,7 +124,7 @@ object VoidgloomSeraphFeatures { yangGlyphs[location] = Timestamp.now() + 5.seconds if(config.yangGlyphAlert) { - RenderUtils.drawTitle(tr("nobaaddons.slayers.yangGlyph.placed", "Yang Glyph!"), config.yangGlyphAlertColor, duration = 1.5.seconds) + RenderUtils.drawTitle(tr("nobaaddons.slayers.yangGlyph.placed", "Yang Glyph!"), color = config.yangGlyphAlertColor, duration = 1.5.seconds) SoundUtils.plingSound.play() } } @@ -136,7 +139,7 @@ object VoidgloomSeraphFeatures { if(!currentQuest.spawned || currentQuest.entity == null) return if(config.brokenHeartRadiationTimer) brokenHeartRadiation?.takeIf { it.isValid }?.let { - RenderUtils.renderText(context, it.entity.getNobaVec().raise(1.5), it.remainingTime, color = NobaColor.GOLD, throughBlocks = true) + context.renderText(it.entity.getNobaVec().raise(1.5), it.remainingTime, color = NobaColor.GOLD, throughBlocks = true) } ?: run { brokenHeartRadiation = null } @@ -147,16 +150,15 @@ object VoidgloomSeraphFeatures { val textLocation = location.center() val seconds = timestamp.timeRemaining().toString(DurationUnit.SECONDS, 1) - RenderUtils.renderOutlinedFilledBox(context, location, config.yangGlyphHighlightColor, throughBlocks = true) - RenderUtils.renderText( - context, + context.renderFullBox(location, config.yangGlyphHighlightColor, throughBlocks = true) + context.renderText( textLocation, tr("nobaaddons.slayers.yangGlyph.name", "Yang Glyph"), color = config.yangGlyphHighlightColor, yOffset = -10f, throughBlocks = true ) - RenderUtils.renderText(context, textLocation, seconds, NobaColor.WHITE, throughBlocks = true) + context.renderText(textLocation, seconds, NobaColor.WHITE, throughBlocks = true) } if(config.highlightNukekubiFixations) { @@ -164,8 +166,7 @@ object VoidgloomSeraphFeatures { nukekubiFixations.forEach { armorStand -> val location = armorStand.pos.toNobaVec() if(location.distanceToPlayer() > 24) return@forEach - - RenderUtils.renderOutline(context, location.add(x = -0.5, y = 0.65, z = -0.5), config.nukekubiFixationHighlightColor, throughBlocks = true) + context.renderOutline(location.add(x = -0.5, y = 0.65, z = -0.5), config.nukekubiFixationHighlightColor, throughBlocks = true) } } } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/EtherwarpOverlay.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/EtherwarpOverlay.kt index 0fd3fd59..3653b357 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/EtherwarpOverlay.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/EtherwarpOverlay.kt @@ -7,7 +7,8 @@ import me.nobaboy.nobaaddons.utils.LocationUtils.rayCast import me.nobaboy.nobaaddons.utils.MCUtils import me.nobaboy.nobaaddons.utils.NobaColor import me.nobaboy.nobaaddons.utils.items.ItemUtils.asSkyBlockItem -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawCenteredText +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderFullBox import me.nobaboy.nobaaddons.utils.toNobaVec import me.nobaboy.nobaaddons.utils.tr import me.owdding.ktmodules.Module @@ -38,7 +39,7 @@ object EtherwarpOverlay { private fun renderFailText(context: DrawContext) { targetBlock.takeIf { config.showFailText }?.let { val (x, y) = MCUtils.window.let { it.scaledWidth / 2 to it.scaledHeight / 2 + 10 } - RenderUtils.drawCenteredText(context, it.displayName, x, y, color = NobaColor.RED) + context.drawCenteredText(it.displayName, x, y, color = NobaColor.RED) } } @@ -78,7 +79,7 @@ object EtherwarpOverlay { if(targetBlock == ValidationType.TOO_FAR && !config.allowOverlayOnAir) return val color = targetBlock?.let { config.failHighlightColor } ?: config.highlightColor - RenderUtils.renderOutlinedFilledBox(context, target.blockPos.toNobaVec(), color, throughBlocks = true) + context.renderFullBox(target.blockPos.toNobaVec(), color, throughBlocks = true) } private fun validateTargetBlock(world: World, target: BlockHitResult): ValidationType? { diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/TemporaryWaypoints.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/TemporaryWaypoints.kt index d6b5eb35..d2995ea4 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/TemporaryWaypoints.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/TemporaryWaypoints.kt @@ -14,7 +14,8 @@ import me.nobaboy.nobaaddons.utils.NumberUtils.addSeparators import me.nobaboy.nobaaddons.utils.RegexUtils.onPartialMatch import me.nobaboy.nobaaddons.utils.Timestamp import me.nobaboy.nobaaddons.utils.chat.ChatUtils -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderText +import me.nobaboy.nobaaddons.utils.render.RenderUtils.renderWaypoint import me.nobaboy.nobaaddons.utils.toNobaVec import me.nobaboy.nobaaddons.utils.tr import me.owdding.ktmodules.Module @@ -72,9 +73,8 @@ object TemporaryWaypoints { val distance = location.distanceToPlayer() val formattedDistance = distance.toInt().addSeparators() - RenderUtils.renderWaypoint(context, location, color, throughBlocks = true) - RenderUtils.renderText( - context, + context.renderWaypoint(location, color, throughBlocks = true) + context.renderText( adjustedLocation, waypoint.text, color = color, @@ -82,8 +82,7 @@ object TemporaryWaypoints { hideThreshold = 5.0, throughBlocks = true ) - RenderUtils.renderText( - context, + context.renderText( adjustedLocation, "${formattedDistance}m", color = NobaColor.GRAY, diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaHudScreen.kt b/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaHudScreen.kt index 249ef81a..bcd7dd32 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaHudScreen.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaHudScreen.kt @@ -5,6 +5,7 @@ import me.nobaboy.nobaaddons.ui.HudElement import me.nobaboy.nobaaddons.ui.UIManager import me.nobaboy.nobaaddons.utils.MCUtils import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawCenteredText import me.nobaboy.nobaaddons.utils.tr import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.screen.Screen @@ -60,7 +61,7 @@ class NobaHudScreen(private val parent: Screen?) : Screen(tr("nobaaddons.screen. private fun renderIdleText(context: DrawContext, scaledWidth: Int, scaledHeight: Int) { usageTexts.forEachIndexed { i, text -> - RenderUtils.drawCenteredText(context, text, scaledWidth / 2, scaledHeight / 2 - 20 + i * 10) + context.drawCenteredText(text, scaledWidth / 2, scaledHeight / 2 - 20 + i * 10) } } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaMainScreen.kt b/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaMainScreen.kt index 7c94574b..3b2372b1 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaMainScreen.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaMainScreen.kt @@ -8,7 +8,7 @@ import me.nobaboy.nobaaddons.screens.notifications.ChatNotificationsScreen import me.nobaboy.nobaaddons.utils.CommonText import me.nobaboy.nobaaddons.utils.MCUtils import me.nobaboy.nobaaddons.utils.NobaColor -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawCenteredText import me.nobaboy.nobaaddons.utils.tr import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.screen.ConfirmLinkScreen @@ -74,8 +74,8 @@ class NobaMainScreen(private val parent: Screen? = null) : Screen(CommonText.NOB val centerX = MCUtils.window.scaledWidth / 2 - RenderUtils.drawCenteredText(context, TITLE_TEXT, centerX, height / 6 - 10, 4f, NobaColor.BLUE, true) - RenderUtils.drawCenteredText(context, VERSION_TEXT, centerX, height / 6 + 25, 1.5f, NobaColor.WHITE, true) + context.drawCenteredText(TITLE_TEXT, centerX, height / 6 - 10, scale = 4f, color = NobaColor.BLUE) + context.drawCenteredText(VERSION_TEXT, centerX, height / 6 + 25, scale = 1.5f) } override fun close() { diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/screens/infoboxes/InfoBoxesScreen.kt b/src/main/kotlin/me/nobaboy/nobaaddons/screens/infoboxes/InfoBoxesScreen.kt index 59bbed50..6c353ad9 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/screens/infoboxes/InfoBoxesScreen.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/screens/infoboxes/InfoBoxesScreen.kt @@ -2,7 +2,7 @@ package me.nobaboy.nobaaddons.screens.infoboxes import me.nobaboy.nobaaddons.features.ui.infobox.InfoBoxesManager import me.nobaboy.nobaaddons.utils.ScreenUtils -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawCenteredText import me.nobaboy.nobaaddons.utils.tr import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.screen.Screen @@ -50,7 +50,7 @@ class InfoBoxesScreen(private val parent: Screen?) : Screen(tr("nobaaddons.scree override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { super.render(context, mouseX, mouseY, delta) - RenderUtils.drawCenteredText(context, this.title.copy().append(" (${infoBoxesList.size}/20)"), this.width / 2, 12) + context.drawCenteredText(title.copy().append(" (${infoBoxesList.size}/20)"), width / 2, 12) } private fun actuallyClose() { diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/screens/keybinds/KeyBindsScreen.kt b/src/main/kotlin/me/nobaboy/nobaaddons/screens/keybinds/KeyBindsScreen.kt index 02753d04..aefbd518 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/screens/keybinds/KeyBindsScreen.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/screens/keybinds/KeyBindsScreen.kt @@ -2,7 +2,7 @@ package me.nobaboy.nobaaddons.screens.keybinds import me.nobaboy.nobaaddons.features.keybinds.impl.KeyBind import me.nobaboy.nobaaddons.utils.ScreenUtils -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawCenteredText import me.nobaboy.nobaaddons.utils.tr import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.screen.Screen @@ -12,6 +12,7 @@ import net.minecraft.client.gui.widget.SimplePositioningWidget import net.minecraft.screen.ScreenTexts import org.lwjgl.glfw.GLFW +// TODO abstract this class KeyBindsScreen(private val parent: Screen?) : Screen(tr("nobaaddons.screen.keybinds", "Key Binds")) { private lateinit var keyBindsList: KeyBindsListWidget private var initialized = false @@ -87,7 +88,7 @@ class KeyBindsScreen(private val parent: Screen?) : Screen(tr("nobaaddons.screen override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { super.render(context, mouseX, mouseY, delta) - RenderUtils.drawCenteredText(context, this.title, this.width / 2, 12) + context.drawCenteredText(title, width / 2, 12) } override fun close() { diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/screens/notifications/ChatNotificationsScreen.kt b/src/main/kotlin/me/nobaboy/nobaaddons/screens/notifications/ChatNotificationsScreen.kt index 07196c11..d4d9a701 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/screens/notifications/ChatNotificationsScreen.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/screens/notifications/ChatNotificationsScreen.kt @@ -1,7 +1,7 @@ package me.nobaboy.nobaaddons.screens.notifications import me.nobaboy.nobaaddons.utils.ScreenUtils -import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawCenteredText import me.nobaboy.nobaaddons.utils.tr import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.screen.Screen @@ -10,6 +10,7 @@ import net.minecraft.client.gui.widget.GridWidget import net.minecraft.client.gui.widget.SimplePositioningWidget import net.minecraft.screen.ScreenTexts +// TODO abstract this class ChatNotificationsScreen(private val parent: Screen?) : Screen(tr("nobaaddons.screen.chatNotifications", "Chat Notifications")) { private lateinit var notificationsList: ChatNotificationsListWidget private var initialized = false @@ -49,7 +50,7 @@ class ChatNotificationsScreen(private val parent: Screen?) : Screen(tr("nobaaddo override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { super.render(context, mouseX, mouseY, delta) - RenderUtils.drawCenteredText(context, this.title, this.width / 2, 12) + context.drawCenteredText(title, width / 2, 12) } override fun close() { diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/ui/HudElement.kt b/src/main/kotlin/me/nobaboy/nobaaddons/ui/HudElement.kt index 6ced1ffc..c1c00848 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/ui/HudElement.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/ui/HudElement.kt @@ -6,6 +6,7 @@ import me.nobaboy.nobaaddons.ui.data.ElementPosition import me.nobaboy.nobaaddons.utils.MCUtils import me.nobaboy.nobaaddons.utils.NumberUtils.roundTo import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawCenteredText import net.minecraft.client.gui.DrawContext import net.minecraft.text.Text import kotlin.math.roundToInt @@ -173,12 +174,7 @@ abstract class HudElement { * Display example text in the UI; the default implementation of this method simply renders [name]. */ protected open fun renderExampleText(context: DrawContext, bounds: ElementBounds, yOffset: Int) { - RenderUtils.drawCenteredText( - context, - name, - bounds.x + bounds.width / 2, - bounds.y + bounds.height / 2 - 4 - yOffset - ) + context.drawCenteredText(name, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2 - 4 - yOffset) } /** diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/ui/TextHudElement.kt b/src/main/kotlin/me/nobaboy/nobaaddons/ui/TextHudElement.kt index 24b81121..c813ae87 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/ui/TextHudElement.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/ui/TextHudElement.kt @@ -5,7 +5,10 @@ import me.nobaboy.nobaaddons.ui.data.TextElement import me.nobaboy.nobaaddons.utils.MCUtils import me.nobaboy.nobaaddons.utils.NobaColor import me.nobaboy.nobaaddons.utils.render.RenderUtils +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawOutlinedText +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawText import me.nobaboy.nobaaddons.utils.render.RenderUtils.getWidth +import me.nobaboy.nobaaddons.utils.render.RenderUtils.scaled import net.minecraft.client.gui.DrawContext import net.minecraft.text.Text import kotlin.math.roundToInt @@ -61,10 +64,10 @@ abstract class TextHudElement(private val element: TextElement) : HudElement() { val y = (this.y + y + line * (MCUtils.textRenderer.fontHeight + 1) * scale).toInt() when(textShadow) { - TextShadow.OUTLINE -> RenderUtils.drawOutlinedText(context, text, x, y, scale, NobaColor(color), NobaColor(outlineColor), applyScaling = false) + TextShadow.OUTLINE -> context.drawOutlinedText(text, x, y, scale, NobaColor(color), NobaColor(outlineColor), applyScaling = false) TextShadow.NONE, TextShadow.SHADOW -> { val shadow = textShadow == TextShadow.SHADOW - RenderUtils.drawText(context, text, x, y, scale, NobaColor(color), shadow, applyScaling = false) + context.drawText(text, x, y, scale, NobaColor(color), shadow, applyScaling = false) } } } @@ -77,7 +80,7 @@ abstract class TextHudElement(private val element: TextElement) : HudElement() { protected abstract fun renderText(context: DrawContext) override fun render(context: DrawContext) { - RenderUtils.scaled(context, scale) { + context.scaled(scale) { renderText(context) } } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaColor.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaColor.kt index a318e168..91feb0c1 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaColor.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaColor.kt @@ -14,6 +14,9 @@ value class NobaColor(val rgb: Int) { val green: Int get() = (rgb shr 8) and 0xFF val blue: Int get() = rgb and 0xFF + val normalized: Triple + get() = Triple(red / 255f, green / 255f, blue / 255f) + val formatting: Formatting? get() = Formatting.entries.firstOrNull { it.colorValue == rgb } val colorCode: Char? get() = formatting?.code diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaVec.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaVec.kt index 5323bd76..59822278 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaVec.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaVec.kt @@ -84,9 +84,6 @@ data class NobaVec( fun inverse() = NobaVec(1.0 / x, 1.0 / y, 1.0 / z) - fun min() = min(x, min(y, z)) - fun max() = max(x, max(y, z)) - fun minOfEach(other: NobaVec) = NobaVec(min(x, other.x), min(y, other.y), min(z, other.z)) fun maxOfEach(other: NobaVec) = NobaVec(max(x, other.x), max(y, other.y), max(z, other.z)) @@ -138,6 +135,13 @@ data class NobaVec( return NobaVec(this[0], this[1], this[2]) } + fun Pair.toBox(): Box { + val (start, end) = this + val min = start.minOfEach(end) + val max = start.maxOfEach(end) + return Box(min.x, min.y, min.z, max.x + 1, max.y + 1, max.z + 1) + } + val expandVector = NobaVec(0.0020000000949949026, 0.0020000000949949026, 0.0020000000949949026) } } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/FrustumUtils.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/FrustumUtils.kt index 212c041b..7130a162 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/FrustumUtils.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/FrustumUtils.kt @@ -3,24 +3,37 @@ package me.nobaboy.nobaaddons.utils.render import me.nobaboy.nobaaddons.mixins.accessors.WorldRendererAccessor import me.nobaboy.nobaaddons.utils.MCUtils import me.nobaboy.nobaaddons.utils.NobaVec +import me.nobaboy.nobaaddons.utils.NobaVec.Companion.toBox import net.minecraft.client.render.Frustum import net.minecraft.util.math.Box object FrustumUtils { - fun getFrustum(): Frustum = (MCUtils.worldRenderer as WorldRendererAccessor).frustum + private val frustum: Frustum + get() = (MCUtils.worldRenderer as WorldRendererAccessor).frustum - fun isVisible(box: Box): Boolean { - return getFrustum().isVisible(box) - } + fun isVisible(box: Box): Boolean = frustum.isVisible(box) - fun isVisible(minX: Double, minY: Double, minZ: Double, maxX: Double, maxY: Double, maxZ: Double): Boolean { + fun isVisible( + minX: Double, minY: Double, minZ: Double, + maxX: Double, maxY: Double, maxZ: Double + ): Boolean { val box = Box(minX, minY, minZ, maxX, maxY, maxZ) return isVisible(box) } - fun isVisible(vec0: NobaVec, toWorldHeight: Boolean = false): Boolean { - val vec = vec0.roundToBlock() + // TODO do I have to round here? + fun isVisible(vec: NobaVec, toWorldHeight: Boolean = false): Boolean { + val rounded = vec.roundToBlock() val maxY = if(toWorldHeight) 319.0 else vec.y + 1 - return isVisible(vec.x, vec.y, vec.z, vec.x + 1.0, maxY, vec.z + 1.0) + val box = Box( + rounded.x, rounded.y, rounded.z, + rounded.x + 1.0, maxY, rounded.z + 1.0 + ) + return isVisible(box) + } + + fun isVisible(bounds: Pair): Boolean { + val box = bounds.toBox() + return isVisible(box) } } \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/HighlightMode.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/HighlightMode.kt index 1d25f1db..1c93cf15 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/HighlightMode.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/HighlightMode.kt @@ -4,6 +4,7 @@ import dev.isxander.yacl3.api.NameableEnum import me.nobaboy.nobaaddons.utils.tr import net.minecraft.text.Text +// TODO change to BOX, FULL_BOX, OUTLINE, and OVERLAY enum class HighlightMode : NameableEnum { OUTLINE, FILLED, diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/RenderUtils.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/RenderUtils.kt index 8d6ed072..3d39744c 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/RenderUtils.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/RenderUtils.kt @@ -19,6 +19,7 @@ import me.nobaboy.nobaaddons.mixins.accessors.BeaconBlockEntityRendererInvoker import me.nobaboy.nobaaddons.utils.MCUtils import me.nobaboy.nobaaddons.utils.NobaColor import me.nobaboy.nobaaddons.utils.NobaVec +import me.nobaboy.nobaaddons.utils.NobaVec.Companion.toBox import me.nobaboy.nobaaddons.utils.StringUtils import me.nobaboy.nobaaddons.utils.TextUtils.toText import me.nobaboy.nobaaddons.utils.expand @@ -27,6 +28,8 @@ import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext import net.minecraft.client.font.TextRenderer import net.minecraft.client.gui.DrawContext import net.minecraft.client.render.LightmapTextureManager +import net.minecraft.client.render.RenderLayer +import net.minecraft.client.render.VertexConsumer import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.text.Text import net.minecraft.util.math.Box @@ -41,26 +44,46 @@ object RenderUtils { * Runs [withScale] with the provided [scale]; this is shorthand for wrapping `withScale` in a try-finally * using [startScale] and [endScale]. */ - inline fun scaled(context: DrawContext, scale: Float, withScale: () -> Unit) { - startScale(context, scale) + inline fun DrawContext.scaled(scale: Float, withScale: () -> Unit) { + startScale(scale) + try { withScale() } finally { - endScale(context) + endScale() } } - fun startScale(context: DrawContext, scale: Float) { - context.matrices.push() - context.matrices.scale(scale, scale, 1f) + fun DrawContext.startScale(scale: Float) { + matrices.push() + matrices.scale(scale, scale, 1f) + } + + fun DrawContext.endScale() { + matrices.pop() } - fun endScale(context: DrawContext) = context.matrices.pop() + + /** + * Returns a lerped alpha for [displayTicks], gradually becoming more transparent the closer it is to 0 from [threshold] + */ + fun lerpAlpha(partialTick: Float, displayTicks: Int, threshold: Int): Int { + val lerped = MathHelper.lerp(partialTick, displayTicks.toFloat(), displayTicks - 1f) + return ((lerped / threshold.toDouble()) * 255.0).roundToInt().coerceIn(0, 255) + } + + fun isPointInArea( + pointX: Double, + pointY: Double, + leftX: Double, + leftY: Double, + rightX: Double, + rightY: Double, + ): Boolean = pointX in leftX..rightX && pointY in leftY..rightY fun Text.getWidth(): Int = MCUtils.textRenderer.getWidth(this) fun String.getWidth(): Int = MCUtils.textRenderer.getWidth(this) - fun drawText( - context: DrawContext, + fun DrawContext.drawText( text: Text, x: Int, y: Int, @@ -69,13 +92,12 @@ object RenderUtils { shadow: Boolean = true, applyScaling: Boolean = true, ) { - if(applyScaling && scale != 1f) startScale(context, scale) - context.drawText(MCUtils.textRenderer, text, (x / scale).toInt(), (y / scale).toInt(), color.rgb, shadow) - if(applyScaling && scale != 1f) endScale(context) + if(applyScaling && scale != 1f) startScale(scale) + drawText(MCUtils.textRenderer, text, (x / scale).toInt(), (y / scale).toInt(), color.rgb, shadow) + if(applyScaling && scale != 1f) endScale() } - fun drawText( - context: DrawContext, + fun DrawContext.drawText( text: String, x: Int, y: Int, @@ -84,11 +106,10 @@ object RenderUtils { shadow: Boolean = true, applyScaling: Boolean = true, ) { - drawText(context, text.toText(), x, y, scale, color, shadow, applyScaling) + drawText(text.toText(), x, y, scale, color, shadow, applyScaling) } - fun drawOutlinedText( - context: DrawContext, + fun DrawContext.drawOutlinedText( text: Text, x: Int, y: Int, @@ -97,25 +118,25 @@ object RenderUtils { outlineColor: NobaColor = NobaColor.BLACK, applyScaling: Boolean = true, ) { - if(applyScaling) startScale(context, scale) - val vertexConsumerProvider = context.let { - (it /*? if >=1.21.2 {*/ as DrawContextAccessor/*?}*/).vertexConsumers - } + if(applyScaling && scale != 1f) startScale(scale) + + val consumers = let { it /*? if >=1.21.2 {*/as DrawContextAccessor/*?}*/ }.vertexConsumers + MCUtils.textRenderer.drawWithOutline( text.asOrderedText(), x / scale, y / scale, color.rgb, outlineColor.rgb, - context.matrices.peek().positionMatrix, - vertexConsumerProvider, + matrices.peek().positionMatrix, + consumers, 15728880 ) - if(applyScaling) endScale(context) + + if(applyScaling && scale != 1f) endScale() } - fun drawOutlinedText( - context: DrawContext, + fun DrawContext.drawOutlinedText( text: String, x: Int, y: Int, @@ -124,118 +145,135 @@ object RenderUtils { outlineColor: NobaColor = NobaColor.BLACK, applyScaling: Boolean = true, ) { - drawOutlinedText(context, text.toText(), x, y, scale, color, outlineColor, applyScaling) + drawOutlinedText(text.toText(), x, y, scale, color, outlineColor, applyScaling) } - fun drawCenteredText( - context: DrawContext, + fun DrawContext.drawCenteredText( text: Text, x: Int, y: Int, scale: Float = 1f, color: NobaColor = NobaColor.WHITE, shadow: Boolean = true, - applyScaling: Boolean = true, + applyScaling: Boolean = true ) { val width = (text.getWidth() * scale).toInt() - drawText(context, text, x - width / 2, y, scale, color, shadow, applyScaling) + drawText(text, x - width / 2, y, scale, color, shadow, applyScaling) } - fun drawCenteredText( - context: DrawContext, + fun DrawContext.drawCenteredText( text: String, x: Int, y: Int, scale: Float = 1f, color: NobaColor = NobaColor.WHITE, shadow: Boolean = true, - applyScaling: Boolean = true, + applyScaling: Boolean = true ) { val width = (text.getWidth() * scale).toInt() - drawText(context, text.toText(), x - width / 2, y, scale, color, shadow, applyScaling) + drawText(text.toText(), x - width / 2, y, scale, color, shadow, applyScaling) } - fun isPointInArea( - pointX: Double, - pointY: Double, - leftX: Double, - leftY: Double, - rightX: Double, - rightY: Double, - ): Boolean = pointX in leftX..rightX && pointY in leftY..rightY - fun drawTitle( text: Text, + subtext: Text? = null, color: NobaColor = NobaColor.WHITE, scale: Float = 4f, offset: Int = 0, duration: Duration = 3.seconds, id: String = StringUtils.randomAlphanumeric(), - subtext: Text? = null, ) { - TitleManager.draw(text, color, scale, offset, duration, id, subtext) + TitleManager.draw(text, subtext, color, scale, offset, duration, id) } fun drawTitle( text: String, + subtext: Text? = null, color: NobaColor = NobaColor.WHITE, scale: Float = 4f, offset: Int = 0, duration: Duration = 3.seconds, id: String = StringUtils.randomAlphanumeric(), - subtext: Text? = null, ) { - TitleManager.draw(text.toText(), color, scale, offset, duration, id, subtext) + TitleManager.draw(text.toText(), subtext, color, scale, offset, duration, id) } - fun Box.expandBlock(n: Int = 1) = expand(NobaVec.expandVector * n) - fun Box.shrinkBlock(n: Int = 1) = expand(NobaVec.expandVector * -n) + // WORLD SPACE RENDERING + + private fun WorldRenderContext.getBuffer(layer: RenderLayer): VertexConsumer? { + val consumers = consumers() as? VertexConsumerProvider.Immediate ?: return null + return consumers.getBuffer(layer) + } - fun renderWaypoint( - context: WorldRenderContext, + private fun Box.expand(n: Int = 1): Box = expand(NobaVec.expandVector * n) + private fun Box.shrink(n: Int = 1): Box = expand(NobaVec.expandVector * -n) + + fun WorldRenderContext.renderWaypoint( location: NobaVec, color: NobaColor, + alpha: Float? = null, extraSize: Double = 0.0, extraSizeTopY: Double = extraSize, extraSizeBottomY: Double = extraSize, beaconThreshold: Double = 5.0, throughBlocks: Boolean = false, ) { - renderBeaconBeam(context, location.raise(), color, beaconThreshold) - renderFilledBox(context, location, color, extraSize, extraSizeTopY, extraSizeBottomY, throughBlocks) + renderBeacon(location, color, beaconThreshold) + renderFilled(location, color, alpha, extraSize, extraSizeTopY, extraSizeBottomY, throughBlocks) } - fun renderOutlinedFilledBox( - context: WorldRenderContext, + fun WorldRenderContext.renderFullBox( location: NobaVec, color: NobaColor, + alpha: Float? = null, lineWidth: Float = 3f, extraSize: Double = 0.0, extraSizeTopY: Double = extraSize, extraSizeBottomY: Double = extraSize, throughBlocks: Boolean = false, ) { - renderOutline(context, location, color, lineWidth, extraSize, extraSizeTopY, extraSizeBottomY, throughBlocks) - renderFilledBox(context, location, color, extraSize, extraSizeTopY, extraSizeBottomY, throughBlocks) + renderOutline(location, color, alpha, lineWidth, extraSize, extraSizeTopY, extraSizeBottomY, throughBlocks) + renderFilled(location, color, alpha, extraSize, extraSizeTopY, extraSizeBottomY, throughBlocks) + } + + fun WorldRenderContext.renderFullBox( + box: Box, + color: NobaColor, + alpha: Float = 0.5f, + lineWidth: Float = 3f, + throughBlocks: Boolean = false, + ) { + renderOutline(box, color, alpha, lineWidth, throughBlocks) + renderFilled(box, color, alpha, throughBlocks) } - fun renderBeaconBeam( - context: WorldRenderContext, + fun WorldRenderContext.renderFullBox( + bounds: Pair, + color: NobaColor, + alpha: Float = 0.5f, + lineWidth: Float = 3f, + throughBlocks: Boolean = false, + ) { + renderOutline(bounds, color, alpha, lineWidth, throughBlocks) + renderFilled(bounds, color, alpha, throughBlocks) + } + + fun WorldRenderContext.renderBeacon( location: NobaVec, color: NobaColor, hideThreshold: Double = 5.0, ) { if(!FrustumUtils.isVisible(location, toWorldHeight = true)) return - val matrices = context.matrixStack() ?: return - val cameraPos = context.camera().pos.toNobaVec() + val matrices = matrixStack() ?: return + val cameraPos = camera().pos.toNobaVec() val dist = location.distance(cameraPos, center = true) if(dist <= hideThreshold) return //? if >=1.21.5 { /*val horizontalDist = location.distanceIgnoreY(cameraPos, center = true) - val scale = max(1f, horizontalDist.toFloat() / 96f) + val scale = max(1.0, horizontalDist / 96).toFloat() *///?} val x = location.x - cameraPos.x @@ -247,14 +285,14 @@ object RenderUtils { BeaconBlockEntityRendererInvoker.invokeRenderBeam( matrices, - context.consumers(), + consumers(), //? if >=1.21.5 { - /*context.tickCounter().getTickProgress(true), + /*tickCounter().getTickProgress(true), scale, *///?} else { - context.tickCounter().getTickDelta(true), + tickCounter().getTickDelta(true), //?} - context.world().time, + world().time, 0, 2048, color.rgb @@ -263,10 +301,11 @@ object RenderUtils { matrices.pop() } - fun renderFilledBox( - context: WorldRenderContext, + fun WorldRenderContext.renderOutline( location: NobaVec, color: NobaColor, + alpha: Float? = null, + lineWidth: Float = 3f, extraSize: Double = 0.0, extraSizeTopY: Double = extraSize, extraSizeBottomY: Double = extraSize, @@ -274,33 +313,53 @@ object RenderUtils { ) { if(!FrustumUtils.isVisible(location)) return - val matrices = context.matrixStack() ?: return - val consumers = context.consumers() as? VertexConsumerProvider.Immediate ?: return + val box = Box( + location.x - extraSize, location.y - extraSizeBottomY, location.z - extraSize, + location.x + extraSize + 1, location.y + extraSizeTopY + 1, location.z + extraSize + 1 + ) - val layer = if(throughBlocks) NobaRenderLayers.FILLED_THROUGH_BLOCKS else NobaRenderLayers.FILLED - val buffer = consumers.getBuffer(layer) + val cameraPos = camera().pos.toNobaVec() + val distSq = location.distanceSq(cameraPos, center = true) + val alpha = alpha ?: (0.1f + 0.005f * distSq).coerceIn(0.7, 1.0).toFloat() - val cameraPos = context.camera().pos.toNobaVec() + renderOutline(box, color, alpha, lineWidth, throughBlocks) + } - val red = color.red / 255f - val green = color.green / 255f - val blue = color.blue / 255f + fun WorldRenderContext.renderOutline( + bounds: Pair, + color: NobaColor, + alpha: Float = 1f, + lineWidth: Float = 3f, + throughBlocks: Boolean = false, + ) { + if(!FrustumUtils.isVisible(bounds)) return - val distSq = location.distanceSq(cameraPos, center = true) - val alpha = (0.1f + 0.005f * distSq.toFloat()).coerceIn(0.3f, 0.7f) + val box = bounds.toBox().expand() + renderOutline(box, color, alpha, lineWidth, throughBlocks) + } - val box = Box( - location.x - extraSize, location.y - extraSizeBottomY, location.z - extraSize, - location.x + 1 + extraSize, location.y + 1 + extraSizeTopY, location.z + 1 + extraSize - ).expandBlock() + fun WorldRenderContext.renderOutline( + box: Box, + color: NobaColor, + alpha: Float = 1f, + lineWidth: Float = 3f, + throughBlocks: Boolean = false, + ) { + val matrices = matrixStack() ?: return + + val layer = if(throughBlocks) NobaRenderLayers.getLinesThroughWalls(lineWidth) else NobaRenderLayers.getLines(lineWidth) + val buffer = getBuffer(layer) ?: return + + val cameraPos = camera().pos.toNobaVec() + val (red, green, blue) = color.normalized matrices.push() matrices.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z) //? if >=1.21.2 { - VertexRendering.drawFilledBox( + VertexRendering.drawBox( //?} else { - /*WorldRenderer.renderFilledBox( + /*WorldRenderer.drawBox( *///?} matrices, buffer, box.minX, box.minY, box.minZ, @@ -311,11 +370,10 @@ object RenderUtils { matrices.pop() } - fun renderOutline( - context: WorldRenderContext, + fun WorldRenderContext.renderFilled( location: NobaVec, color: NobaColor, - lineWidth: Float = 3f, + alpha: Float? = null, extraSize: Double = 0.0, extraSizeTopY: Double = extraSize, extraSizeBottomY: Double = extraSize, @@ -323,33 +381,51 @@ object RenderUtils { ) { if(!FrustumUtils.isVisible(location)) return - val matrices = context.matrixStack() ?: return - val consumers = context.consumers() as? VertexConsumerProvider.Immediate ?: return + val box = Box( + location.x - extraSize, location.y - extraSizeBottomY, location.z - extraSize, + location.x + extraSize + 1, location.y + extraSizeTopY + 1, location.z + extraSize + 1 + ) - val layer = if(throughBlocks) NobaRenderLayers.getLinesThroughWalls(lineWidth) else NobaRenderLayers.getLines(lineWidth) - val buffer = consumers.getBuffer(layer) + val cameraPos = camera().pos.toNobaVec() + val distSq = location.distanceSq(cameraPos, center = true) + val alpha = alpha ?: (0.1f + 0.005f * distSq).coerceIn(0.3, 0.7).toFloat() - val cameraPos = context.camera().pos.toNobaVec() + renderFilled(box, color, alpha, throughBlocks) + } - val red = color.red / 255f - val green = color.green / 255f - val blue = color.blue / 255f + fun WorldRenderContext.renderFilled( + bounds: Pair, + color: NobaColor, + alpha: Float = 1f, + throughBlocks: Boolean = false, + ) { + if(!FrustumUtils.isVisible(bounds)) return - val distSq = location.distanceSq(cameraPos, center = true) - val alpha = (0.1f + 0.005f * distSq.toFloat()).coerceIn(0.7f, 1f) + val box = bounds.toBox().expand() + renderFilled(box, color, alpha, throughBlocks) + } - val box = Box( - location.x - extraSize, location.y - extraSizeBottomY, location.z - extraSize, - location.x + 1 + extraSize, location.y + 1 + extraSizeTopY, location.z + 1 + extraSize - ).expandBlock() + fun WorldRenderContext.renderFilled( + box: Box, + color: NobaColor, + alpha: Float = 1f, + throughBlocks: Boolean = false, + ) { + val matrices = matrixStack() ?: return + + val layer = if(throughBlocks) NobaRenderLayers.FILLED_THROUGH_BLOCKS else NobaRenderLayers.FILLED + val buffer = getBuffer(layer) + + val cameraPos = camera().pos.toNobaVec() + val (red, green, blue) = color.normalized matrices.push() matrices.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z) //? if >=1.21.2 { - VertexRendering.drawBox( + VertexRendering.drawFilledBox( //?} else { - /*WorldRenderer.drawBox( + /*WorldRenderer.renderFilledBox( *///?} matrices, buffer, box.minX, box.minY, box.minZ, @@ -360,8 +436,7 @@ object RenderUtils { matrices.pop() } - fun renderText( - context: WorldRenderContext, + fun WorldRenderContext.renderText( location: NobaVec, text: Text, color: NobaColor = NobaColor.WHITE, @@ -374,9 +449,9 @@ object RenderUtils { if(!FrustumUtils.isVisible(location)) return val positionMatrix = Matrix4f() - val consumers = context.consumers() as? VertexConsumerProvider.Immediate ?: return + val consumers = consumers() as? VertexConsumerProvider.Immediate ?: return - val camera = context.camera() + val camera = camera() val cameraPos = camera.pos.toNobaVec() val dist = location.distance(cameraPos) @@ -424,8 +499,7 @@ object RenderUtils { //?} } - fun renderText( - context: WorldRenderContext, + fun WorldRenderContext.renderText( location: NobaVec, text: String, color: NobaColor = NobaColor.WHITE, @@ -435,14 +509,6 @@ object RenderUtils { hideThreshold: Double = 0.0, throughBlocks: Boolean = false, ) { - renderText(context, location, text.toText(), color, shadow, yOffset, scaleMultiplier, hideThreshold, throughBlocks) - } - - /** - * Returns a lerped alpha for [displayTicks], gradually becoming more transparent the closer it is to 0 from [threshold] - */ - fun lerpAlpha(partialTick: Float, displayTicks: Int, threshold: Int): Int { - val lerped = MathHelper.lerp(partialTick, displayTicks.toFloat(), displayTicks - 1f) - return ((lerped / threshold.toDouble()) * 255.0).roundToInt().coerceIn(0, 255) + renderText(location, text.toText(), color, shadow, yOffset, scaleMultiplier, hideThreshold, throughBlocks) } } \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/TitleManager.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/TitleManager.kt index 16e2ccd3..b786913c 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/TitleManager.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/TitleManager.kt @@ -4,6 +4,7 @@ import me.nobaboy.nobaaddons.events.impl.skyblock.SkyBlockEvents import me.nobaboy.nobaaddons.utils.MCUtils import me.nobaboy.nobaaddons.utils.NobaColor import me.nobaboy.nobaaddons.utils.Timestamp +import me.nobaboy.nobaaddons.utils.render.RenderUtils.drawCenteredText import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback import net.minecraft.client.gui.DrawContext import net.minecraft.text.Text @@ -26,32 +27,32 @@ object TitleManager { titles.values.forEach { val textHeight = (9 * it.scale).toInt() val y = height / 2 - textHeight + it.offset - RenderUtils.drawCenteredText(context, it.text, width / 2, y, it.scale, it.color) - if(it.subtext != null) RenderUtils.drawCenteredText(context, it.subtext, width / 2, y + textHeight + 5, it.scale - 1.5f, it.color) + context.drawCenteredText(it.text, width / 2, y, it.scale, it.color) + if(it.subtext != null) context.drawCenteredText(it.subtext, width / 2, y + textHeight + 5, it.scale - 1.5f, it.color) } } fun draw( text: Text, + subtext: Text?, color: NobaColor, scale: Float, offset: Int, duration: Duration, id: String, - subtext: Text?, ) { - val title = Title(text, color, scale, offset, duration, Timestamp.now(), subtext) + val title = Title(text, subtext, color, scale, offset, duration, Timestamp.now()) titles[id] = title } data class Title( val text: Text, + val subtext: Text?, val color: NobaColor, val scale: Float, val offset: Int, val duration: Duration, val timestamp: Timestamp, - val subtext: Text?, ) { val expired: Boolean get() = timestamp.elapsedSince() >= duration }