mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
hud: add support for dynamic text
This commit is contained in:
parent
ad9f8cade5
commit
b2178e2cfa
@ -19,6 +19,7 @@ import de.bixilon.minosoft.data.locale.minecraft.Translator
|
|||||||
import de.bixilon.minosoft.data.text.RGBColor.Companion.asColor
|
import de.bixilon.minosoft.data.text.RGBColor.Companion.asColor
|
||||||
import de.bixilon.minosoft.data.text.events.ClickEvent
|
import de.bixilon.minosoft.data.text.events.ClickEvent
|
||||||
import de.bixilon.minosoft.data.text.events.HoverEvent
|
import de.bixilon.minosoft.data.text.events.HoverEvent
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.elements.text.HUDTextTranslator
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
import de.bixilon.minosoft.util.KUtil.nullCast
|
import de.bixilon.minosoft.util.KUtil.nullCast
|
||||||
import javafx.collections.ObservableList
|
import javafx.collections.ObservableList
|
||||||
@ -141,6 +142,71 @@ class BaseComponent : ChatComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(translator: Translator?, hudTextTranslator: HUDTextTranslator, parent: TextComponent?, json: Map<String, *>) {
|
||||||
|
val currentParent: TextComponent?
|
||||||
|
var currentText = ""
|
||||||
|
(json["text"] as String?)?.let {
|
||||||
|
if (it.indexOf(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR) != -1) {
|
||||||
|
parts.add(ChatComponent.of(it, translator, parent, hudTextTranslator = hudTextTranslator))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentText = it
|
||||||
|
}
|
||||||
|
|
||||||
|
val color = (json["color"] as String?)?.let { colorName ->
|
||||||
|
if (colorName.startsWith("#")) {
|
||||||
|
colorName.asColor()
|
||||||
|
} else {
|
||||||
|
ChatCode.FORMATTING_CODES[colorName]?.nullCast<RGBColor>()
|
||||||
|
}
|
||||||
|
} ?: parent?.color
|
||||||
|
|
||||||
|
val formatting = parent?.formatting?.toMutableSet() ?: mutableSetOf()
|
||||||
|
|
||||||
|
formatting.addOrRemove(PreChatFormattingCodes.BOLD, (json["bold"] as Boolean?))
|
||||||
|
formatting.addOrRemove(PreChatFormattingCodes.ITALIC, (json["italic"] as Boolean?))
|
||||||
|
formatting.addOrRemove(PreChatFormattingCodes.UNDERLINED, (json["underlined"] as Boolean?))
|
||||||
|
formatting.addOrRemove(PreChatFormattingCodes.STRIKETHROUGH, (json["strikethrough"] as Boolean?))
|
||||||
|
formatting.addOrRemove(PreChatFormattingCodes.OBFUSCATED, (json["obfuscated"] as Boolean?))
|
||||||
|
|
||||||
|
val clickEvent = (json["clickEvent"] as Map<String, *>?)?.let { click -> ClickEvent(click) }
|
||||||
|
val hoverEvent = (json["hoverEvent"] as Map<String, *>?)?.let { click -> HoverEvent(click) }
|
||||||
|
|
||||||
|
val textComponent = MultiChatComponent(
|
||||||
|
message = currentText,
|
||||||
|
color = color,
|
||||||
|
formatting = formatting,
|
||||||
|
clickEvent = clickEvent,
|
||||||
|
hoverEvent = hoverEvent,
|
||||||
|
)
|
||||||
|
if (currentText.isNotEmpty()) {
|
||||||
|
parts.add(textComponent)
|
||||||
|
}
|
||||||
|
currentParent = textComponent
|
||||||
|
|
||||||
|
|
||||||
|
(json["extra"] as Array<*>?)?.let {
|
||||||
|
for (data in it) {
|
||||||
|
parts.add(ChatComponent.of(data, translator, currentParent, hudTextTranslator = hudTextTranslator))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
(json["translate"] as String?)?.let {
|
||||||
|
val with = mutableListOf<Any>()
|
||||||
|
(json["with"] as List<*>?)?.let { withArray ->
|
||||||
|
for (part in withArray) {
|
||||||
|
with.add(part!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parts.add(translator?.translate(it, currentParent, *with.toTypedArray()) ?: ChatComponent.of(json["with"], translator, currentParent, hudTextTranslator = hudTextTranslator))
|
||||||
|
}
|
||||||
|
|
||||||
|
(json["data"] as String?)?.let {
|
||||||
|
parts.add(hudTextTranslator.translate(it, currentParent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val ansiColoredMessage: String
|
override val ansiColoredMessage: String
|
||||||
get() {
|
get() {
|
||||||
val stringBuilder = StringBuilder()
|
val stringBuilder = StringBuilder()
|
||||||
|
@ -17,6 +17,7 @@ import com.google.gson.JsonObject
|
|||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
import com.google.gson.JsonPrimitive
|
import com.google.gson.JsonPrimitive
|
||||||
import de.bixilon.minosoft.data.locale.minecraft.Translator
|
import de.bixilon.minosoft.data.locale.minecraft.Translator
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.elements.text.HUDTextTranslator
|
||||||
import javafx.collections.FXCollections
|
import javafx.collections.FXCollections
|
||||||
import javafx.collections.ObservableList
|
import javafx.collections.ObservableList
|
||||||
import javafx.scene.Node
|
import javafx.scene.Node
|
||||||
@ -57,7 +58,7 @@ interface ChatComponent {
|
|||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun of(raw: Any?, translator: Translator? = null, parent: TextComponent? = null, ignoreJson: Boolean = false): ChatComponent {
|
fun of(raw: Any?, translator: Translator? = null, parent: TextComponent? = null, ignoreJson: Boolean = false, hudTextTranslator: HUDTextTranslator? = null): ChatComponent {
|
||||||
if (raw == null) {
|
if (raw == null) {
|
||||||
return BaseComponent()
|
return BaseComponent()
|
||||||
}
|
}
|
||||||
@ -75,6 +76,16 @@ interface ChatComponent {
|
|||||||
}
|
}
|
||||||
return component
|
return component
|
||||||
}
|
}
|
||||||
|
is List<*> -> {
|
||||||
|
val component = BaseComponent()
|
||||||
|
for (part in raw) {
|
||||||
|
component.parts.add(of(part, translator, parent, hudTextTranslator = hudTextTranslator))
|
||||||
|
}
|
||||||
|
return component
|
||||||
|
}
|
||||||
|
is Map<*, *> -> {
|
||||||
|
return BaseComponent(translator, hudTextTranslator!!, parent, raw as Map<String, *>)
|
||||||
|
}
|
||||||
is JsonPrimitive -> raw.asString
|
is JsonPrimitive -> raw.asString
|
||||||
else -> raw.toString()
|
else -> raw.toString()
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,16 @@ class ClickEvent {
|
|||||||
this.value = value
|
this.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(json: Map<String, *>) {
|
||||||
|
action = ClickEventActions[(json["action"] as String).lowercase()]
|
||||||
|
val primitive = json["value"]
|
||||||
|
value = if (primitive is Number) {
|
||||||
|
primitive
|
||||||
|
} else {
|
||||||
|
primitive.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum class ClickEventActions {
|
enum class ClickEventActions {
|
||||||
OPEN_URL,
|
OPEN_URL,
|
||||||
RUN_COMMAND,
|
RUN_COMMAND,
|
||||||
|
@ -45,6 +45,22 @@ class HoverEvent {
|
|||||||
this.value = value
|
this.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(json: Map<String, *>) {
|
||||||
|
action = HoverEventActions.valueOf((json["action"] as String).uppercase(Locale.getDefault()))
|
||||||
|
var data: Any = json
|
||||||
|
json["value"]?.let {
|
||||||
|
data = it
|
||||||
|
}
|
||||||
|
json["contents"]?.let {
|
||||||
|
data = it
|
||||||
|
}
|
||||||
|
this.value = when (action) {
|
||||||
|
HoverEventActions.SHOW_TEXT -> ChatComponent.of(data)
|
||||||
|
HoverEventActions.SHOW_ENTITY -> EntityHoverData.deserialize(data)
|
||||||
|
else -> TODO("Don't know what todo with $action: $json")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum class HoverEventActions {
|
enum class HoverEventActions {
|
||||||
SHOW_TEXT,
|
SHOW_TEXT,
|
||||||
SHOW_ITEM,
|
SHOW_ITEM,
|
||||||
|
@ -46,5 +46,10 @@ class EntityHoverData(
|
|||||||
|
|
||||||
return EntityHoverData(json["id"].asString.asUUID(), type, ChatComponent.of(json["name"]))
|
return EntityHoverData(json["id"].asString.asUUID(), type, ChatComponent.of(json["name"]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun deserialize(data: Any): EntityHoverData {
|
||||||
|
val json = JsonParser.parseString(data as String).asJsonObject
|
||||||
|
return deserialize(json)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,19 +21,22 @@ import de.bixilon.minosoft.gui.rendering.Renderer
|
|||||||
import de.bixilon.minosoft.gui.rendering.RendererBuilder
|
import de.bixilon.minosoft.gui.rendering.RendererBuilder
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.atlas.HUDAtlasElement
|
import de.bixilon.minosoft.gui.rendering.hud.atlas.HUDAtlasElement
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.elements.primitive.HUDElement
|
import de.bixilon.minosoft.gui.rendering.hud.elements.primitive.HUDElement
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.elements.text.HUDTextTranslator
|
||||||
import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent
|
import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap
|
import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap
|
||||||
|
import de.bixilon.minosoft.util.task.time.TimeWorker
|
||||||
|
import de.bixilon.minosoft.util.task.time.TimeWorkerTask
|
||||||
import glm_.glm
|
import glm_.glm
|
||||||
import glm_.mat4x4.Mat4
|
import glm_.mat4x4.Mat4
|
||||||
|
|
||||||
class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow) : Renderer {
|
class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow) : Renderer {
|
||||||
private var prepareNext: Boolean = true
|
private lateinit var updateTask: TimeWorkerTask
|
||||||
private lateinit var hudElements: MutableMap<ResourceLocation, HUDElement>
|
private lateinit var hudElements: MutableMap<ResourceLocation, HUDElement>
|
||||||
private val enabledHUDElements: MutableMap<ResourceLocation, HUDElement> = mutableMapOf()
|
private val enabledHUDElements = mutableMapOf<ResourceLocation, HUDElement>()
|
||||||
private val hudShader = Shader(
|
private val hudShader = Shader(
|
||||||
renderWindow = renderWindow,
|
renderWindow = renderWindow,
|
||||||
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "hud"),
|
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "hud"),
|
||||||
@ -42,13 +45,17 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
|||||||
var orthographicMatrix: Mat4 = Mat4()
|
var orthographicMatrix: Mat4 = Mat4()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
val hudTextTranslator = HUDTextTranslator(connection)
|
||||||
|
|
||||||
var hudEnabled = true
|
var hudEnabled = true
|
||||||
var currentMenu: HUDMenus = HUDMenus.IN_GAME
|
var currentMenu: HUDMenus = HUDMenus.IN_GAME
|
||||||
set(value) {
|
set(value) {
|
||||||
if (field == value) {
|
if (field == value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
prepareNext = true
|
for (element in hudElements.values) {
|
||||||
|
element.prepareNext = true
|
||||||
|
}
|
||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +70,15 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
|||||||
|
|
||||||
connection.registerEvent(CallbackEventInvoker.of<ScreenResizeEvent> {
|
connection.registerEvent(CallbackEventInvoker.of<ScreenResizeEvent> {
|
||||||
orthographicMatrix = glm.ortho(0f, renderWindow.screenDimensions.x.toFloat(), renderWindow.screenDimensions.y.toFloat(), 0f)
|
orthographicMatrix = glm.ortho(0f, renderWindow.screenDimensions.x.toFloat(), renderWindow.screenDimensions.y.toFloat(), 0f)
|
||||||
prepareNext = true
|
for (element in hudElements.values) {
|
||||||
|
element.prepareNext = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
updateTask = TimeWorker.addTask(TimeWorkerTask(ProtocolDefinition.TICK_TIME*2) {
|
||||||
|
for (hudElement in hudElements.values) {
|
||||||
|
hudElement.update()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,17 +104,12 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
|||||||
|
|
||||||
override fun draw() {
|
override fun draw() {
|
||||||
if (RenderConstants.RENDER_HUD && hudEnabled) {
|
if (RenderConstants.RENDER_HUD && hudEnabled) {
|
||||||
if (prepareNext) {
|
|
||||||
for (hudElement in hudElements.values) {
|
|
||||||
if (hudElement.isEnabled) {
|
|
||||||
hudElement.prepare(orthographicMatrix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prepareNext = false
|
|
||||||
}
|
|
||||||
hudShader.use()
|
hudShader.use()
|
||||||
for (hudElement in enabledHUDElements.values) {
|
for (hudElement in enabledHUDElements.values) {
|
||||||
if (hudElement.isEnabled) {
|
if (hudElement.isEnabled) {
|
||||||
|
if (hudElement.prepareNext) {
|
||||||
|
hudElement.prepare()
|
||||||
|
}
|
||||||
hudElement.draw()
|
hudElement.draw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
|||||||
import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementPositionAnchors
|
import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementPositionAnchors
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2
|
import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec2
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec2
|
||||||
import glm_.mat4x4.Mat4
|
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
|
|
||||||
abstract class HUDElement(
|
abstract class HUDElement(
|
||||||
@ -30,8 +29,11 @@ abstract class HUDElement(
|
|||||||
val isEnabled: Boolean get() = activeOnMenu?.let {
|
val isEnabled: Boolean get() = activeOnMenu?.let {
|
||||||
hudRenderer.currentMenu == it
|
hudRenderer.currentMenu == it
|
||||||
} ?: true
|
} ?: true
|
||||||
|
|
||||||
lateinit var hudRenderer: HUDRenderer
|
lateinit var hudRenderer: HUDRenderer
|
||||||
|
|
||||||
|
var prepareNext = true
|
||||||
|
|
||||||
open fun init(hudRenderer: HUDRenderer) {
|
open fun init(hudRenderer: HUDRenderer) {
|
||||||
this.hudRenderer = hudRenderer
|
this.hudRenderer = hudRenderer
|
||||||
position.init()
|
position.init()
|
||||||
@ -41,7 +43,9 @@ abstract class HUDElement(
|
|||||||
|
|
||||||
open fun draw() {}
|
open fun draw() {}
|
||||||
|
|
||||||
open fun prepare(matrix: Mat4) {}
|
open fun prepare() {
|
||||||
|
prepareNext = false
|
||||||
|
}
|
||||||
|
|
||||||
fun getPositionAtAnchor(anchor: HUDElementPositionAnchors): Vec2i {
|
fun getPositionAtAnchor(anchor: HUDElementPositionAnchors): Vec2i {
|
||||||
val realSize = size.getRealVector(hudRenderer).toVec2
|
val realSize = size.getRealVector(hudRenderer).toVec2
|
||||||
@ -49,6 +53,8 @@ abstract class HUDElement(
|
|||||||
return realPosition - realSize * position.anchor.positionTransform + realSize * anchor.positionTransform
|
return realPosition - realSize * position.anchor.positionTransform + realSize * anchor.positionTransform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun checkToPrepare() {}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other !is HUDElement) return false
|
if (other !is HUDElement) return false
|
||||||
@ -68,4 +74,6 @@ abstract class HUDElement(
|
|||||||
result = 31 * result + hudRenderer.hashCode()
|
result = 31 * result + hudRenderer.hashCode()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun update() {}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2
|
|||||||
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
||||||
import de.bixilon.minosoft.gui.rendering.util.mesh.SimpleTextureMesh
|
import de.bixilon.minosoft.gui.rendering.util.mesh.SimpleTextureMesh
|
||||||
import de.bixilon.minosoft.util.json.RGBColorSerializer
|
import de.bixilon.minosoft.util.json.RGBColorSerializer
|
||||||
import glm_.mat4x4.Mat4
|
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec4.Vec4
|
import glm_.vec4.Vec4
|
||||||
@ -52,8 +51,8 @@ class HUDImageElement: HUDElement {
|
|||||||
mesh.draw()
|
mesh.draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun prepare(matrix: Mat4) {
|
override fun prepare() {
|
||||||
super.prepare(matrix)
|
super.prepare()
|
||||||
if (mesh.state == Mesh.MeshStates.LOADED) {
|
if (mesh.state == Mesh.MeshStates.LOADED) {
|
||||||
mesh.unload()
|
mesh.unload()
|
||||||
mesh = SimpleTextureMesh()
|
mesh = SimpleTextureMesh()
|
||||||
@ -69,7 +68,7 @@ class HUDImageElement: HUDElement {
|
|||||||
), texture.texture, textureUV, tint)
|
), texture.texture, textureUV, tint)
|
||||||
}
|
}
|
||||||
for (position in DRAW_ORDER) {
|
for (position in DRAW_ORDER) {
|
||||||
addVertex((matrix * Vec4(positions[position], 1f, 1f)).xy, uvs[position])
|
addVertex((hudRenderer.orthographicMatrix * Vec4(positions[position], 1f, 1f)).xy, uvs[position])
|
||||||
}
|
}
|
||||||
mesh.load()
|
mesh.load()
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ import de.bixilon.minosoft.gui.rendering.hud.elements.primitive.HUDSpacerElement
|
|||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec2
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec2
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
import glm_.glm
|
import glm_.glm
|
||||||
import glm_.mat4x4.Mat4
|
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
|
|
||||||
class HUDTextElement : HUDElement {
|
class HUDTextElement : HUDElement {
|
||||||
@ -39,11 +38,15 @@ class HUDTextElement : HUDElement {
|
|||||||
|
|
||||||
private val alignment: HUDElementPositionAnchors
|
private val alignment: HUDElementPositionAnchors
|
||||||
|
|
||||||
private var contents: String = ""
|
private lateinit var contents: List<*>
|
||||||
|
|
||||||
|
private var currentText: ChatComponent? = null
|
||||||
|
|
||||||
|
var lastElement: HUDElement? = null
|
||||||
|
|
||||||
constructor(position: HUDElementPosition, size: HUDElementVec2, json: Map<String, Any>? = null, activeOnMenu: HUDMenus?) : super(position, size, (json?.get("z") as Double?)?.toInt() ?: 0, activeOnMenu) {
|
constructor(position: HUDElementPosition, size: HUDElementVec2, json: Map<String, Any>? = null, activeOnMenu: HUDMenus?) : super(position, size, (json?.get("z") as Double?)?.toInt() ?: 0, activeOnMenu) {
|
||||||
alignment = json?.get("alignment")?.let { HUDElementPositionAnchors.of(it as String) } ?: HUDElementPositionAnchors.TOP_LEFT
|
alignment = json?.get("alignment")?.let { HUDElementPositionAnchors.of(it as String) } ?: HUDElementPositionAnchors.TOP_LEFT
|
||||||
(json?.get("static_text") as String?)?.let { contents = it }
|
contents = json?.get("content") as List<*>
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(position: HUDElementPosition, size: HUDElementVec2, z: Int) : super(position, size, z) {
|
constructor(position: HUDElementPosition, size: HUDElementVec2, z: Int) : super(position, size, z) {
|
||||||
@ -52,6 +55,7 @@ class HUDTextElement : HUDElement {
|
|||||||
|
|
||||||
private fun renderChatComponent(chatComponent: ChatComponent) {
|
private fun renderChatComponent(chatComponent: ChatComponent) {
|
||||||
elements.clear()
|
elements.clear()
|
||||||
|
lastElement = null
|
||||||
val newLinePositions = mutableListOf<Int>()
|
val newLinePositions = mutableListOf<Int>()
|
||||||
addChatComponent(chatComponent, newLinePositions)
|
addChatComponent(chatComponent, newLinePositions)
|
||||||
newLinePositions += elements.size
|
newLinePositions += elements.size
|
||||||
@ -72,7 +76,6 @@ class HUDTextElement : HUDElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun addChars(chars: CharArray, color: RGBColor?, newLinePositions: MutableList<Int>): MutableList<Int> {
|
private fun addChars(chars: CharArray, color: RGBColor?, newLinePositions: MutableList<Int>): MutableList<Int> {
|
||||||
var lastElement: HUDElement? = null
|
|
||||||
val maxRight = getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_RIGHT).x
|
val maxRight = getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_RIGHT).x
|
||||||
val bottomLeftPosition = getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_LEFT).toVec2
|
val bottomLeftPosition = getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_LEFT).toVec2
|
||||||
for (char in chars) {
|
for (char in chars) {
|
||||||
@ -145,10 +148,28 @@ class HUDTextElement : HUDElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun prepare(matrix: Mat4) {
|
override fun prepare() {
|
||||||
renderChatComponent(BaseComponent(null, contents))
|
if (currentText == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
renderChatComponent(currentText!!)
|
||||||
for (element in elements) {
|
for (element in elements) {
|
||||||
element.prepare(matrix)
|
element.prepare()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTextComponent(): ChatComponent {
|
||||||
|
return ChatComponent.of(contents, translator = hudRenderer.connection.version.localeManager.language, hudTextTranslator = hudRenderer.hudTextTranslator)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update() {
|
||||||
|
if (!isEnabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val newText = getTextComponent()
|
||||||
|
if (currentText != newText) {
|
||||||
|
currentText = newText
|
||||||
|
prepareNext = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.rendering.hud.elements.text
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.locale.minecraft.Translator
|
||||||
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
|
import de.bixilon.minosoft.data.text.TextComponent
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
|
import de.bixilon.minosoft.util.MMath.round
|
||||||
|
|
||||||
|
|
||||||
|
class HUDTextTranslator(val connection: PlayConnection) : Translator {
|
||||||
|
override fun translate(key: String?, parent: TextComponent?, vararg data: Any?): ChatComponent {
|
||||||
|
if (key == null) {
|
||||||
|
return ChatComponent.of(key)
|
||||||
|
}
|
||||||
|
val resourceLocation = ResourceLocation(key)
|
||||||
|
if (resourceLocation !in insertRunnables) {
|
||||||
|
return ChatComponent.of(key)
|
||||||
|
}
|
||||||
|
val runnable = insertRunnables[resourceLocation]!! // checked before
|
||||||
|
return ChatComponent.of(runnable.invoke(connection))
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val insertRunnables = mutableMapOf<ResourceLocation, (PlayConnection) -> String>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
insertRunnables[ResourceLocation("minosoft:playerPosition_x")] = { connection ->
|
||||||
|
connection.player.position.x.round(2).toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.util
|
package de.bixilon.minosoft.util
|
||||||
|
|
||||||
|
import glm_.func.common.floor
|
||||||
|
import glm_.glm
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
|
||||||
@ -99,4 +101,14 @@ object MMath {
|
|||||||
} else {
|
} else {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Float.round(digits: Int): Float {
|
||||||
|
val multiplicationFactor = glm.pow(10, digits)
|
||||||
|
return (this * multiplicationFactor).floor / multiplicationFactor
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Double.round(digits: Int): Double {
|
||||||
|
val multiplicationFactor = glm.pow(10, digits)
|
||||||
|
return (this * multiplicationFactor).floor / multiplicationFactor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user