diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt index e62094bb9..93223a8d2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt @@ -33,7 +33,6 @@ object RenderConstants { val EXPERIENCE_BAR_LEVEL_COLOR = "#80ff20".asColor() - val HP_TEXT_COLOR = "#ff1313".asColor() const val COLORMAP_SIZE = 255 diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/AbstractHotbarHealthElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/AbstractHotbarHealthElement.kt index 93d34511d..0982f7f68 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/AbstractHotbarHealthElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/AbstractHotbarHealthElement.kt @@ -1,7 +1,10 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar +import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.RGBColor.Companion.asColor import de.bixilon.minosoft.gui.rendering.gui.elements.Element import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ImageElement +import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer import de.bixilon.minosoft.gui.rendering.gui.hud.atlas.HUDAtlasElement import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer @@ -14,17 +17,27 @@ abstract class AbstractHotbarHealthElement(hudRenderer: HUDRenderer) : Element(h abstract val totalMaxHealth: Float var totalMaxHearts = 0 var rows = 0 + var text = false + private var textElement = TextElement(hudRenderer, "", parent = this) override fun forceSilentApply() { totalMaxHearts = (totalMaxHealth / 2).ceil - rows = totalMaxHearts / HEARTS_PER_ROW - if (totalMaxHearts % HEARTS_PER_ROW != 0) { - rows++ + text = totalMaxHearts > HP_TEXT_LIMIT + if (text) { + textElement.text = createText() + + _size = textElement.size + } else { + rows = totalMaxHearts / HEARTS_PER_ROW + if (totalMaxHearts % HEARTS_PER_ROW != 0) { + rows++ + } + + _size = Vec2i(HEARTS_PER_ROW, rows) * HEART_SIZE + Vec2i(1, 0) // 1 pixel is overlapping, so we have one more for the heart } - _size = Vec2i(HEARTS_PER_ROW, rows) * HEART_SIZE + Vec2i(1, 0) // 1 pixel is overlapping, so we have one more for the heart cacheUpToDate = false } @@ -39,11 +52,19 @@ abstract class AbstractHotbarHealthElement(hudRenderer: HUDRenderer) : Element(h } } + override fun forceRender(offset: Vec2i, z: Int, consumer: GUIVertexConsumer, options: GUIVertexOptions?): Int { + return textElement.render(offset, z, consumer, options) + } + + abstract fun createText(): ChatComponent + companion object { - const val LAYERS = 2 + val NORMAL_TEXT_COLOR = "#ff1313".asColor() private const val HP_PER_ROW = 20 const val HEARTS_PER_ROW = HP_PER_ROW / 2 val HEART_SIZE = Vec2i(8, 9) + const val LAYERS = 2 + const val HP_TEXT_LIMIT = 40 } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarHealthElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarHealthElement.kt index 78e4f8926..56d2b5cff 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarHealthElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarHealthElement.kt @@ -15,6 +15,10 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar import de.bixilon.minosoft.data.registries.effects.DefaultStatusEffects import de.bixilon.minosoft.data.registries.effects.attributes.DefaultStatusEffectAttributeNames +import de.bixilon.minosoft.data.text.BaseComponent +import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.RGBColor.Companion.asColor +import de.bixilon.minosoft.data.text.TextComponent import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ImageElement import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer @@ -23,6 +27,7 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions import de.bixilon.minosoft.util.KUtil.decide import de.bixilon.minosoft.util.KUtil.unsafeCast +import de.bixilon.minosoft.util.MMath.round10 import glm_.vec2.Vec2i import java.lang.Float.max import java.lang.Float.min @@ -144,7 +149,10 @@ class HotbarHealthElement(hudRenderer: HUDRenderer) : AbstractHotbarHealthElemen override var totalMaxHealth = 0.0f override fun forceRender(offset: Vec2i, z: Int, consumer: GUIVertexConsumer, options: GUIVertexOptions?): Int { - // ToDo: Damage animation, regeneration, caching, stacking (and eventual text replace) + if (text) { + return super.forceRender(offset, z, consumer, options) + } + // ToDo: Damage animation, regeneration, caching, stacking drawCanisters(offset, z, consumer, options, blackHeartContainer) val hardcoreIndex = hardcode.decide(1, 0) @@ -239,7 +247,36 @@ class HotbarHealthElement(hudRenderer: HUDRenderer) : AbstractHotbarHealthElemen return true } + override fun createText(): ChatComponent { + val text = BaseComponent() + + text += TextComponent(totalHealth.round10).apply { + color = when { + poison -> POISON_TEXT_COLOR + wither -> WITHER_TEXT_COLOR + frozen -> FROZEN_TEXT_COLOR + else -> NORMAL_TEXT_COLOR + } + } + text += TextComponent("/") + text += TextComponent(totalMaxHealth.round10).apply { + color = when { + absorptionsAmount > 0.0f -> ABSORPTION_TEXT_COLOR + else -> NORMAL_TEXT_COLOR + } + } + + return text + } + override fun tick() { apply() } + + companion object { + val POISON_TEXT_COLOR = "#602020".asColor() + val WITHER_TEXT_COLOR = "#2b2b2b".asColor() + val FROZEN_TEXT_COLOR = "#a8f7ff".asColor() + val ABSORPTION_TEXT_COLOR = "#d4af37".asColor() + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarVehicleHealthElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarVehicleHealthElement.kt index 845d29110..5fcf46631 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarVehicleHealthElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarVehicleHealthElement.kt @@ -15,18 +15,17 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar import de.bixilon.minosoft.data.entities.entities.LivingEntity import de.bixilon.minosoft.data.registries.effects.attributes.DefaultStatusEffectAttributeNames +import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.TextComponent import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ImageElement import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions import de.bixilon.minosoft.util.KUtil.decide +import de.bixilon.minosoft.util.MMath.round10 import glm_.vec2.Vec2i -import java.lang.Float -import kotlin.Boolean -import kotlin.Int -import kotlin.arrayOf -import kotlin.let +import java.lang.Float.max class HotbarVehicleHealthElement(hudRenderer: HUDRenderer) : AbstractHotbarHealthElement(hudRenderer), Pollable { private val atlasManager = hudRenderer.atlasManager @@ -45,7 +44,9 @@ class HotbarVehicleHealthElement(hudRenderer: HUDRenderer) : AbstractHotbarHealt override var totalMaxHealth = 0.0f override fun forceRender(offset: Vec2i, z: Int, consumer: GUIVertexConsumer, options: GUIVertexOptions?): Int { - // ToDo: Eventual text replace + if (text) { + return super.forceRender(offset, z, consumer, options) + } drawCanisters(offset, z, consumer, options, vehicleHeartContainer) var healthLeft = totalHealth @@ -82,7 +83,7 @@ class HotbarVehicleHealthElement(hudRenderer: HUDRenderer) : AbstractHotbarHealt } val health = riddenEntity.health.toFloat() - val maxHealth = Float.max(0.0f, riddenEntity.getAttributeValue(DefaultStatusEffectAttributeNames.GENERIC_MAX_HEALTH).toFloat()) + val maxHealth = max(0.0f, riddenEntity.getAttributeValue(DefaultStatusEffectAttributeNames.GENERIC_MAX_HEALTH).toFloat()) if (health == this.totalHealth && this.totalMaxHealth == maxHealth) { return false @@ -93,6 +94,10 @@ class HotbarVehicleHealthElement(hudRenderer: HUDRenderer) : AbstractHotbarHealt return true } + override fun createText(): ChatComponent { + return TextComponent("${totalHealth.round10} / ${totalMaxHealth.round10}").color(NORMAL_TEXT_COLOR) + } + override fun tick() { apply() }