diff --git a/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt index dc504c91a..57f35be0a 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2021 Moritz Zwerger, Lukas Eisenhauer * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -59,6 +59,7 @@ class BaseComponent : ChatComponent { ChatColors.VALUES.getOrNull(Character.digit(formattingChar, 16))?.let { push() + currentColor = it } ?: ChatFormattingCodes.getChatFormattingCodeByChar(formattingChar)?.let { push() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDImageElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDImageElement.kt index 8eb51d47f..20220a989 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDImageElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDImageElement.kt @@ -35,10 +35,10 @@ class HUDImageElement: HUDElement { tint = ChatColors.WHITE } - constructor(position: HUDElementPosition, size: HUDElementVec2, z: Int, texture: TextureLike): super(position, size, z) { + constructor(position: HUDElementPosition, size: HUDElementVec2, z: Int, texture: TextureLike, tint: RGBColor?): super(position, size, z) { textureName = null this.texture = texture - tint = ChatColors.WHITE + this.tint = tint ?: ChatColors.WHITE } override fun init(hudRenderer: HUDRenderer) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt index 75ece7eda..61c0f2c39 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt @@ -15,7 +15,9 @@ package de.bixilon.minosoft.gui.rendering.hud.elements.text import de.bixilon.minosoft.Minosoft +import de.bixilon.minosoft.data.text.BaseComponent import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.RGBColor import de.bixilon.minosoft.data.text.TextComponent import de.bixilon.minosoft.gui.rendering.font.Font import de.bixilon.minosoft.gui.rendering.hud.HUDMenus @@ -49,15 +51,28 @@ class HUDTextElement : HUDElement { } private fun renderChatComponent(chatComponent: ChatComponent) { - val chars = chatComponent.message.toCharArray() elements.clear() - val newLinePositions = addChars(chars) + val newLinePositions = mutableListOf() + addChatComponent(chatComponent, newLinePositions) + newLinePositions += elements.size adjustPositionsForLineBreaks(newLinePositions) } - private fun addChars(chars: CharArray): MutableList { + private fun addChatComponent(chatComponent: ChatComponent, newLinePositions: MutableList) { + when (chatComponent) { + is BaseComponent -> { + for (part in chatComponent.parts) { + addChatComponent(part, newLinePositions) + } + } + is TextComponent -> { + addChars(chatComponent.message.toCharArray(), chatComponent.color, newLinePositions) + } + } + } + + private fun addChars(chars: CharArray, color: RGBColor?, newLinePositions: MutableList): MutableList { var lastElement: HUDElement? = null - val newLinePositions = mutableListOf() val maxRight = getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_RIGHT).x val bottomLeftPosition = getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_LEFT).toVec2 for (char in chars) { @@ -76,7 +91,7 @@ class HUDTextElement : HUDElement { val newElement = if (char == ' ') { HUDSpacerElement(elementPosition, elementSize, z) } else { - HUDImageElement(elementPosition, elementSize, z, fontChar) + HUDImageElement(elementPosition, elementSize, z, fontChar, tint = color) } elements += newElement newElement.init(hudRenderer) @@ -91,7 +106,6 @@ class HUDTextElement : HUDElement { elements[relevantIndex].position = HUDElementPosition(HUDElementVec2(bottomLeftPosition, HUDElementPositionUnits.PIXELS), HUDElementPositionAnchors.BOTTOM_LEFT) } } - newLinePositions += elements.size return newLinePositions } @@ -114,13 +128,13 @@ class HUDTextElement : HUDElement { private fun adjustPositionsForLineBreaks(newLinePositions: MutableList) { var y = when (alignment) { HUDElementPositionAnchors.TOP_LEFT, HUDElementPositionAnchors.BOTTOM_LEFT -> getPositionAtAnchor(HUDElementPositionAnchors.TOP_LEFT).y - HUDElementPositionAnchors.TOP_RIGHT, HUDElementPositionAnchors.BOTTOM_RIGHT -> getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_RIGHT).y - (newLinePositions.size-2) * (Font.CHAR_HEIGHT+1) * Minosoft.getConfig().config.game.hud.scale.toInt() + HUDElementPositionAnchors.TOP_RIGHT, HUDElementPositionAnchors.BOTTOM_RIGHT -> getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_RIGHT).y - (newLinePositions.size - 2) * (Font.CHAR_HEIGHT + 1) * Minosoft.getConfig().config.game.hud.scale.toInt() else -> TODO() } val left = getPositionAtAnchor(HUDElementPositionAnchors.TOP_LEFT).x val right = glm.min(hudRenderer.renderWindow.screenDimensions.x, getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_RIGHT).x) - for (i in 0 until newLinePositions.size-1) { - elements[newLinePositions[i]].position = alignment.textAlignmentTransform.invoke(left, right, y, elements[newLinePositions[i+1] - 1]) + for (i in 0 until newLinePositions.lastIndex) { + elements[newLinePositions[i]].position = alignment.textAlignmentTransform.invoke(left, right, y, elements[newLinePositions[i + 1] - 1]) y += ((Font.CHAR_HEIGHT + 1) * Minosoft.getConfig().config.game.hud.scale).toInt() } } @@ -132,7 +146,7 @@ class HUDTextElement : HUDElement { } override fun prepare(matrix: Mat4) { - renderChatComponent(TextComponent(contents)) + renderChatComponent(BaseComponent(null, contents)) for (element in elements) { element.prepare(matrix) }