diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt
index a164733aa..b83ed1ded 100644
--- a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt
+++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt
@@ -49,12 +49,12 @@ abstract class Entity(
protected open val hasCollisions = true
private val defaultAABB = AABB(
- Vec3(-(entityType.width / 2 + HITBOX_MARGIN), 0 , -(entityType.width / 2 + HITBOX_MARGIN)),
- Vec3(+(entityType.width / 2 + HITBOX_MARGIN), entityType.height , +(entityType.width / 2 + HITBOX_MARGIN))
+ Vec3(-(entityType.width / 2 + HITBOX_MARGIN), 0, -(entityType.width / 2 + HITBOX_MARGIN)),
+ Vec3(+(entityType.width / 2 + HITBOX_MARGIN), entityType.height, +(entityType.width / 2 + HITBOX_MARGIN))
)
- fun forceMove(relativePosition: Vec3) {
- position = position + relativePosition
+ fun forceMove(deltaPosition: Vec3) {
+ position = position + deltaPosition
}
fun addEffect(effect: StatusEffectInstance) {
@@ -202,6 +202,7 @@ abstract class Entity(
val blockPositions = (originalAABB extend deltaPosition extend Directions.DOWN.directionVector).getBlockPositions()
val result = VoxelShape()
for (blockPosition in blockPositions) {
+ // ToDo: Check if chunk is loaded
val blockState = connection.world.getBlockState(blockPosition) ?: continue
result.add(blockState.collisionShape + blockPosition)
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt
index bbd42a69d..53be6eca3 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt
@@ -23,11 +23,13 @@ import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.hud.atlas.HUDAtlasElement
import de.bixilon.minosoft.gui.rendering.hud.elements.other.CrosshairHUDElement
import de.bixilon.minosoft.gui.rendering.hud.nodes.HUDElement
+import de.bixilon.minosoft.gui.rendering.hud.nodes.chat.ChatBoxHUDElement
import de.bixilon.minosoft.gui.rendering.hud.nodes.debug.HUDSystemDebugNode
import de.bixilon.minosoft.gui.rendering.hud.nodes.debug.HUDWorldDebugNode
import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
+import de.bixilon.minosoft.util.MMath
import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap
import glm_.glm
import glm_.mat4x4.Mat4
@@ -87,6 +89,11 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
toggleKeyBinding = KeyBindingsNames.TOGGLE_DEBUG_SCREEN,
enabled = false,
))
+ addElement(ElementsNames.CHAT_RESOURCE_LOCATION, ChatBoxHUDElement(this), HUDElementProperties(
+ position = Vec2(0.0f, -1.0f),
+ xBinding = HUDElementProperties.PositionBindings.CENTER,
+ ))
+
}
fun addElement(resourceLocation: ResourceLocation, hudElement: HUDElement, defaultProperties: HUDElementProperties) {
@@ -174,6 +181,8 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
for ((elementProperties, hudElement) in enabledHUDElement.values) {
val realScaleFactor = elementProperties.scale * Minosoft.getConfig().config.game.hud.scale
val realSize = hudElement.layout.sizing.currentSize * realScaleFactor
+ realSize.x = MMath.clamp(realSize.x, hudElement.layout.sizing.minSize.x, hudElement.layout.sizing.maxSize.x)
+ realSize.y = MMath.clamp(realSize.y, hudElement.layout.sizing.minSize.y, hudElement.layout.sizing.maxSize.y)
val elementStart = getRealPosition(realSize, elementProperties, renderWindow.screenDimensions)
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/SubmittableTextField.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/SubmittableTextField.kt
new file mode 100644
index 000000000..76be81558
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/SubmittableTextField.kt
@@ -0,0 +1,40 @@
+/*
+ * Minosoft
+ * Copyright (C) 2021 Moritz Zwerger
+ *
+ * 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.gui.rendering.hud.elements.input
+
+import de.bixilon.minosoft.config.key.KeyCodes
+import de.bixilon.minosoft.gui.rendering.RenderWindow
+
+class SubmittableTextField(
+ renderWindow: RenderWindow,
+ defaultText: String = "",
+ maxLength: Int = 256,
+ private val onSubmit: (text: String) -> Unit,
+) : TextField(renderWindow, defaultText, maxLength) {
+
+ fun submit() {
+ onSubmit.invoke(text)
+ text = ""
+ }
+
+
+ override fun keyInput(keyCodes: KeyCodes) {
+ if (keyCodes == KeyCodes.KEY_ENTER) {
+ // submit
+ submit()
+ return
+ }
+ super.keyInput(keyCodes)
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/TextField.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/TextField.kt
new file mode 100644
index 000000000..9f2ec480e
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/TextField.kt
@@ -0,0 +1,104 @@
+/*
+ * Minosoft
+ * Copyright (C) 2021 Moritz Zwerger
+ *
+ * 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.gui.rendering.hud.elements.input
+
+import de.bixilon.minosoft.config.key.KeyCodes
+import de.bixilon.minosoft.data.text.ChatComponent
+import de.bixilon.minosoft.gui.rendering.RenderConstants
+import de.bixilon.minosoft.gui.rendering.RenderWindow
+import de.bixilon.minosoft.gui.rendering.hud.nodes.layout.AbsoluteLayout
+import de.bixilon.minosoft.gui.rendering.hud.nodes.primitive.ImageNode
+import de.bixilon.minosoft.gui.rendering.hud.nodes.primitive.LabelNode
+import de.bixilon.minosoft.util.MMath
+import glm_.vec2.Vec2i
+
+
+open class TextField(
+ renderWindow: RenderWindow,
+ defaultText: String = "",
+ var maxLength: Int = 256,
+) : AbsoluteLayout(renderWindow), KeyConsumer, MouseConsumer {
+ override var focused: Boolean = true
+ private var textBuilder: StringBuilder = StringBuilder(defaultText)
+ private val textElement = LabelNode(renderWindow, sizing = sizing, text = ChatComponent.valueOf(raw = text), background = false)
+ private var position = text.length
+
+ var text: String
+ get() = textBuilder.toString()
+ set(value) {
+ position = value.length
+ textBuilder = StringBuilder(value)
+ update()
+ }
+
+ init {
+ addChild(Vec2i(0, 0), textElement)
+ addChild(Vec2i(0, 0), ImageNode(renderWindow, sizing = sizing, renderWindow.WHITE_TEXTURE, 0, RenderConstants.TEXT_BACKGROUND_COLOR))
+ clearChildrenCache()
+ }
+
+ fun clearText() {
+ textBuilder.clear()
+ update()
+ }
+
+ private fun update() {
+ textElement.text = ChatComponent.valueOf(raw = text)
+ }
+
+ override fun keyInput(keyCodes: KeyCodes) {
+ when (keyCodes) {
+ KeyCodes.KEY_BACKSPACE -> {
+ if (textBuilder.isEmpty()) {
+ return
+ }
+ textBuilder.deleteCharAt(--position)
+ }
+ KeyCodes.KEY_DELETE -> {
+ if (textBuilder.isEmpty() || position == textBuilder.length) {
+ return
+ }
+ textBuilder.deleteCharAt(position)
+ }
+ KeyCodes.KEY_ENTER -> {
+ if (position > maxLength) {
+ return
+ }
+ textBuilder.insert(position++, '\n')
+ }
+ KeyCodes.KEY_LEFT -> {
+ position = MMath.clamp(position - 1, 0, text.length)
+ return
+ }
+ KeyCodes.KEY_RIGHT -> {
+ position = MMath.clamp(position + 1, 0, text.length)
+ return
+ }
+ // ToDo: Up and down for line breaks, shift and ctrl modifier, ...
+ else -> {
+ return
+ }
+ }
+ update()
+ super.keyInput(keyCodes)
+ }
+
+ override fun charInput(char: Char) {
+ if (position >= maxLength) {
+ return
+ }
+ textBuilder.insert(position++, char.toString())
+ update()
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt
new file mode 100644
index 000000000..b2db30217
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt
@@ -0,0 +1,62 @@
+/*
+ * Minosoft
+ * Copyright (C) 2021 Moritz Zwerger
+ *
+ * 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.gui.rendering.hud.nodes.chat
+
+
+import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
+import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
+import de.bixilon.minosoft.gui.rendering.hud.elements.input.SubmittableTextField
+import de.bixilon.minosoft.gui.rendering.hud.nodes.HUDElement
+import glm_.vec2.Vec2i
+
+class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer) {
+ private lateinit var inputField: SubmittableTextField
+
+ override fun init() {
+ inputField = SubmittableTextField(renderWindow = hudRenderer.renderWindow, maxLength = 256, onSubmit = {
+ hudRenderer.renderWindow.connection.sender.sendChatMessage(it)
+ closeChat()
+ })
+
+ layout.addChild(Vec2i(0, 0), inputField)
+ inputField.apply()
+
+ hudRenderer.renderWindow.registerKeyCallback(KeyBindingsNames.OPEN_CHAT) { _, _ ->
+ openChat()
+ }
+ hudRenderer.renderWindow.registerKeyCallback(KeyBindingsNames.CLOSE_CHAT) { _, _ ->
+ closeChat()
+ }
+ }
+
+ override fun screenChangeResizeCallback(screenDimensions: Vec2i) {
+ layout.sizing.minSize.x = screenDimensions.x
+ layout.sizing.maxSize.x = screenDimensions.x
+ layout.sizing.validate()
+ layout.apply()
+ }
+
+ fun openChat() {
+ hudRenderer.renderWindow.currentKeyConsumer = inputField
+ hudRenderer.renderWindow.currentElement.remove(KeyBindingsNames.WHEN_IN_GAME)
+ hudRenderer.renderWindow.currentElement.add(KeyBindingsNames.WHEN_IN_CHAT)
+ }
+
+ fun closeChat() {
+ inputField.clearText()
+ hudRenderer.renderWindow.currentKeyConsumer = null
+ hudRenderer.renderWindow.currentElement.remove(KeyBindingsNames.WHEN_IN_CHAT)
+ hudRenderer.renderWindow.currentElement.add(KeyBindingsNames.WHEN_IN_GAME)
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/layout/AbsoluteLayout.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/layout/AbsoluteLayout.kt
index 11631d71a..23fbf43e1 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/layout/AbsoluteLayout.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/layout/AbsoluteLayout.kt
@@ -83,8 +83,7 @@ open class AbsoluteLayout(
private fun recalculateSize() {
if (children.isEmpty()) {
- sizing.currentSize.x = sizing.minSize.x
- sizing.currentSize.y = sizing.minSize.y
+ sizing.currentSize = Vec2i(sizing.minSize)
} else {
for ((childNode, start) in children) {
checkSize(childNode, start)
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/primitive/LabelNode.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/primitive/LabelNode.kt
index a4172bd73..9ac549416 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/primitive/LabelNode.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/primitive/LabelNode.kt
@@ -37,6 +37,7 @@ class LabelNode(
prepare()
apply()
}
+
var sText: String
get() = text.message
set(value) {
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/properties/NodeSizing.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/properties/NodeSizing.kt
index b90306926..7fd3e6103 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/properties/NodeSizing.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/properties/NodeSizing.kt
@@ -13,14 +13,20 @@
package de.bixilon.minosoft.gui.rendering.hud.nodes.properties
+import de.bixilon.minosoft.util.MMath
import glm_.vec2.Vec2i
data class NodeSizing(
- val minSize: Vec2i = Vec2i(0, 0),
- val margin: Spacing = Spacing(),
- val padding: Spacing = Spacing(),
- val maxSize: Vec2i = Vec2i(Int.MAX_VALUE, Int.MAX_VALUE),
+ var minSize: Vec2i = Vec2i(0, 0),
+ var margin: Spacing = Spacing(0, 0, 0, 0),
+ var padding: Spacing = Spacing(0, 0, 0, 0),
+ var maxSize: Vec2i = Vec2i(Int.MAX_VALUE, Int.MAX_VALUE),
var forceAlign: NodeAlignment? = null,
) {
- val currentSize: Vec2i = Vec2i(minSize)
+ var currentSize: Vec2i = Vec2i(minSize)
+
+
+ fun validate() {
+ MMath.clamp(currentSize, minSize, maxSize)
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/util/MMath.kt b/src/main/java/de/bixilon/minosoft/util/MMath.kt
index 71d8c01aa..b48c01252 100644
--- a/src/main/java/de/bixilon/minosoft/util/MMath.kt
+++ b/src/main/java/de/bixilon/minosoft/util/MMath.kt
@@ -13,6 +13,8 @@
package de.bixilon.minosoft.util
+import glm_.vec2.Vec2i
+
object MMath {
fun minClamp(value: Int, min: Int): Int {
@@ -22,6 +24,12 @@ object MMath {
return value
}
+ fun clamp(value: Vec2i, min: Vec2i, max: Vec2i): Vec2i {
+ value.x = clamp(value.x, min.x, max.x)
+ value.y = clamp(value.y, min.y, max.y)
+ return value
+ }
+
fun clamp(value: Int, min: Int, max: Int): Int {
if (value < min) {
return min