mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 10:55:01 -04:00
rendering: wip: chat field
This commit is contained in:
parent
c1fa6d5829
commit
4866528802
@ -52,11 +52,16 @@ object KeyBindingsNames {
|
|||||||
|
|
||||||
val WHEN_IN_GAME = ResourceLocation("minosoft:in_game")
|
val WHEN_IN_GAME = ResourceLocation("minosoft:in_game")
|
||||||
val WHEN_PLAYER_IS_FLYING = ResourceLocation("minosoft:is_flying")
|
val WHEN_PLAYER_IS_FLYING = ResourceLocation("minosoft:is_flying")
|
||||||
|
val WHEN_IN_CHAT = ResourceLocation("minosoft:in_chat")
|
||||||
|
|
||||||
val TAKE_SCREENSHOT = ResourceLocation("minosoft:take_screenshot")
|
val TAKE_SCREENSHOT = ResourceLocation("minosoft:take_screenshot")
|
||||||
|
|
||||||
val TOGGLE_HUD = ResourceLocation("minosoft:toggle_hud")
|
val TOGGLE_HUD = ResourceLocation("minosoft:toggle_hud")
|
||||||
|
|
||||||
|
val OPEN_CHAT = ResourceLocation("minosoft:open_chat")
|
||||||
|
|
||||||
|
val CLOSE_CHAT = ResourceLocation("minosoft:close_chat")
|
||||||
|
|
||||||
|
|
||||||
val SELECT_HOTBAR_SLOTS = arrayOf(ResourceLocation("minosoft:select_hotbar_slot_1"),
|
val SELECT_HOTBAR_SLOTS = arrayOf(ResourceLocation("minosoft:select_hotbar_slot_1"),
|
||||||
ResourceLocation("minosoft:select_hotbar_slot_2"),
|
ResourceLocation("minosoft:select_hotbar_slot_2"),
|
||||||
@ -217,5 +222,17 @@ object KeyBindingsNames {
|
|||||||
),
|
),
|
||||||
mutableSetOf(mutableSetOf(WHEN_IN_GAME))
|
mutableSetOf(mutableSetOf(WHEN_IN_GAME))
|
||||||
),
|
),
|
||||||
|
OPEN_CHAT to KeyBinding(
|
||||||
|
mutableMapOf(
|
||||||
|
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_T)
|
||||||
|
),
|
||||||
|
mutableSetOf(mutableSetOf(WHEN_IN_GAME))
|
||||||
|
),
|
||||||
|
CLOSE_CHAT to KeyBinding(
|
||||||
|
mutableMapOf(
|
||||||
|
KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_ESCAPE)
|
||||||
|
),
|
||||||
|
mutableSetOf(mutableSetOf(WHEN_IN_CHAT))
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -25,4 +25,5 @@ object ElementsNames {
|
|||||||
val CROSSHAIR_RESOURCE_LOCATION = ResourceLocation("minosoft:crosshair")
|
val CROSSHAIR_RESOURCE_LOCATION = ResourceLocation("minosoft:crosshair")
|
||||||
val WORLD_DEBUG_SCREEN_RESOURCE_LOCATION = ResourceLocation("minosoft:world_debug_screen")
|
val WORLD_DEBUG_SCREEN_RESOURCE_LOCATION = ResourceLocation("minosoft:world_debug_screen")
|
||||||
val SYSTEM_DEBUG_SCREEN_RESOURCE_LOCATION = ResourceLocation("minosoft:system_debug_screen")
|
val SYSTEM_DEBUG_SCREEN_RESOURCE_LOCATION = ResourceLocation("minosoft:system_debug_screen")
|
||||||
|
val CHAT_RESOURCE_LOCATION = ResourceLocation("minosoft:chat")
|
||||||
}
|
}
|
||||||
|
@ -216,8 +216,7 @@ open class TextComponent : ChatComponent {
|
|||||||
for (char in charArray) {
|
for (char in charArray) {
|
||||||
if (char == '\n') {
|
if (char == '\n') {
|
||||||
offset.x = 0
|
offset.x = 0
|
||||||
offset.y = 0
|
val yOffset = Font.CHAR_HEIGHT + RenderConstants.TEXT_LINE_PADDING
|
||||||
val yOffset = offset.y + Font.CHAR_HEIGHT + RenderConstants.TEXT_LINE_PADDING
|
|
||||||
offset.y += yOffset
|
offset.y += yOffset
|
||||||
retMaxSize.y += yOffset
|
retMaxSize.y += yOffset
|
||||||
continue
|
continue
|
||||||
|
@ -125,9 +125,9 @@ class World : BiomeAccessor {
|
|||||||
fun getBlocks(start: Vec3i, end: Vec3i): Map<Vec3i, BlockState> {
|
fun getBlocks(start: Vec3i, end: Vec3i): Map<Vec3i, BlockState> {
|
||||||
val blocks: MutableMap<Vec3i, BlockState> = mutableMapOf()
|
val blocks: MutableMap<Vec3i, BlockState> = mutableMapOf()
|
||||||
|
|
||||||
for (z in start.z until end.z) {
|
for (z in start.z..end.z) {
|
||||||
for (y in start.y until end.y) {
|
for (y in start.y..end.y) {
|
||||||
for (x in start.x until end.x) {
|
for (x in start.x..end.x) {
|
||||||
val blockPosition = Vec3i(x, y, z)
|
val blockPosition = Vec3i(x, y, z)
|
||||||
getBlockState(blockPosition)?.let {
|
getBlockState(blockPosition)?.let {
|
||||||
blocks[blockPosition] = it
|
blocks[blockPosition] = it
|
||||||
|
@ -95,6 +95,9 @@ class Camera(
|
|||||||
var yOffset = yPos - this.lastMouseY
|
var yOffset = yPos - this.lastMouseY
|
||||||
lastMouseX = xPos
|
lastMouseX = xPos
|
||||||
lastMouseY = yPos
|
lastMouseY = yPos
|
||||||
|
if (!renderWindow.currentElement.contains(KeyBindingsNames.WHEN_IN_GAME)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
xOffset *= mouseSensitivity
|
xOffset *= mouseSensitivity
|
||||||
yOffset *= mouseSensitivity
|
yOffset *= mouseSensitivity
|
||||||
var yaw = xOffset.toFloat() + playerEntity.rotation.headYaw
|
var yaw = xOffset.toFloat() + playerEntity.rotation.headYaw
|
||||||
@ -145,7 +148,7 @@ class Camera(
|
|||||||
fun handleInput(deltaTime: Double) {
|
fun handleInput(deltaTime: Double) {
|
||||||
var cameraSpeed = movementSpeed * deltaTime
|
var cameraSpeed = movementSpeed * deltaTime
|
||||||
val movementFront = Vec3(cameraFront)
|
val movementFront = Vec3(cameraFront)
|
||||||
if (! Minosoft.getConfig().config.game.camera.noCipMovement) {
|
if (!Minosoft.getConfig().config.game.camera.noCipMovement) {
|
||||||
movementFront.y = 0.0f
|
movementFront.y = 0.0f
|
||||||
movementFront.normalizeAssign() // when moving forwards, do not move down
|
movementFront.normalizeAssign() // when moving forwards, do not move down
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import de.bixilon.minosoft.data.text.RGBColor
|
|||||||
import de.bixilon.minosoft.gui.rendering.chunk.WorldRenderer
|
import de.bixilon.minosoft.gui.rendering.chunk.WorldRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.font.Font
|
import de.bixilon.minosoft.gui.rendering.font.Font
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.elements.input.KeyConsumer
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
||||||
import de.bixilon.minosoft.gui.rendering.util.ScreenshotTaker
|
import de.bixilon.minosoft.gui.rendering.util.ScreenshotTaker
|
||||||
@ -36,10 +37,9 @@ import de.bixilon.minosoft.util.CountUpAndDownLatch
|
|||||||
import de.bixilon.minosoft.util.logging.Log
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
import org.lwjgl.*
|
|
||||||
import org.lwjgl.glfw.*
|
import org.lwjgl.glfw.*
|
||||||
import org.lwjgl.glfw.GLFW.*
|
import org.lwjgl.glfw.GLFW.*
|
||||||
import org.lwjgl.opengl.*
|
import org.lwjgl.opengl.GL
|
||||||
import org.lwjgl.opengl.GL11.*
|
import org.lwjgl.opengl.GL11.*
|
||||||
import org.lwjgl.system.MemoryStack
|
import org.lwjgl.system.MemoryStack
|
||||||
import org.lwjgl.system.MemoryUtil
|
import org.lwjgl.system.MemoryUtil
|
||||||
@ -81,6 +81,30 @@ class RenderWindow(
|
|||||||
|
|
||||||
val renderQueue = ConcurrentLinkedQueue<Runnable>()
|
val renderQueue = ConcurrentLinkedQueue<Runnable>()
|
||||||
|
|
||||||
|
private var _currentInputConsumer: KeyConsumer? = null
|
||||||
|
val currentElement: MutableList<ResourceLocation> = mutableListOf(KeyBindingsNames.WHEN_IN_GAME, KeyBindingsNames.WHEN_PLAYER_IS_FLYING)
|
||||||
|
|
||||||
|
private var skipNextChatPress = false
|
||||||
|
|
||||||
|
var currentInputConsumer: KeyConsumer?
|
||||||
|
get() = _currentInputConsumer
|
||||||
|
set(value) {
|
||||||
|
_currentInputConsumer = value
|
||||||
|
for ((_, binding) in keyBindingCallbacks) {
|
||||||
|
if (!keyBindingDown.contains(binding.first)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (!binding.first.action.containsKey(KeyAction.TOGGLE) && !binding.first.action.containsKey(KeyAction.CHANGE)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for (keyCallback in binding.second) {
|
||||||
|
keyCallback.invoke(KeyCodes.KEY_UNKNOWN, KeyAction.RELEASE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keyBindingDown.clear()
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
connection.registerEvent(EventInvokerCallback<ConnectionStateChangeEvent> {
|
connection.registerEvent(EventInvokerCallback<ConnectionStateChangeEvent> {
|
||||||
if (it.connection.isDisconnected) {
|
if (it.connection.isDisconnected) {
|
||||||
@ -104,7 +128,6 @@ class RenderWindow(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun init(latch: CountUpAndDownLatch) {
|
fun init(latch: CountUpAndDownLatch) {
|
||||||
// Setup an error callback. The default implementation
|
// Setup an error callback. The default implementation
|
||||||
// will print the error message in System.err.
|
// will print the error message in System.err.
|
||||||
@ -146,12 +169,37 @@ class RenderWindow(
|
|||||||
keysDown.remove(keyCode)
|
keysDown.remove(keyCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keyAction == KeyAction.PRESS) {
|
||||||
|
// ToDo: Repeatable keys, long holding, etc
|
||||||
|
|
||||||
|
currentInputConsumer?.keyInput(keyCode)
|
||||||
|
}
|
||||||
|
|
||||||
for ((_, keyCallbackPair) in keyBindingCallbacks) {
|
for ((_, keyCallbackPair) in keyBindingCallbacks) {
|
||||||
run {
|
run {
|
||||||
val keyBinding = keyCallbackPair.first
|
val keyBinding = keyCallbackPair.first
|
||||||
val keyCallbacks = keyCallbackPair.second
|
val keyCallbacks = keyCallbackPair.second
|
||||||
|
|
||||||
var anyCheckRun = false
|
var anyCheckRun = false
|
||||||
|
|
||||||
|
var andWhenValid = false
|
||||||
|
for (or in keyBinding.`when`) {
|
||||||
|
var andValid = true
|
||||||
|
for (and in or) {
|
||||||
|
if (!currentElement.contains(and)) {
|
||||||
|
andValid = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (andValid) {
|
||||||
|
andWhenValid = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!andWhenValid) {
|
||||||
|
return@run
|
||||||
|
}
|
||||||
|
|
||||||
keyBinding.action[KeyAction.MODIFIER]?.let {
|
keyBinding.action[KeyAction.MODIFIER]?.let {
|
||||||
val previousKeysDown = if (keyAction == KeyAction.RELEASE) {
|
val previousKeysDown = if (keyAction == KeyAction.RELEASE) {
|
||||||
val previousKeysDown = keysDown.toMutableList()
|
val previousKeysDown = keysDown.toMutableList()
|
||||||
@ -196,11 +244,19 @@ class RenderWindow(
|
|||||||
}
|
}
|
||||||
for (keyCallback in keyCallbacks) {
|
for (keyCallback in keyCallbacks) {
|
||||||
keyCallback.invoke(keyCode, keyAction)
|
keyCallback.invoke(keyCode, keyAction)
|
||||||
|
skipNextChatPress = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glfwSetCharCallback(windowId) { _: Long, char: Int ->
|
||||||
|
if (skipNextChatPress) {
|
||||||
|
skipNextChatPress = false
|
||||||
|
return@glfwSetCharCallback
|
||||||
|
}
|
||||||
|
currentInputConsumer?.charInput(char.toChar())
|
||||||
|
}
|
||||||
|
|
||||||
if (mouseCatch) {
|
if (mouseCatch) {
|
||||||
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
|
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
|
||||||
|
@ -19,8 +19,8 @@ import glm_.vec2.Vec2
|
|||||||
|
|
||||||
data class HUDElementProperties(
|
data class HUDElementProperties(
|
||||||
val position: Vec2,
|
val position: Vec2,
|
||||||
@Json(name = "x_binding") val xBinding: PositionBindings,
|
@Json(name = "x_binding") val xBinding: PositionBindings = PositionBindings.FURTHEST_POINT_AWAY,
|
||||||
@Json(name = "y_binding") val yBinding: PositionBindings,
|
@Json(name = "y_binding") val yBinding: PositionBindings = PositionBindings.FURTHEST_POINT_AWAY,
|
||||||
@Json(name = "toggle_key_binding") var toggleKeyBinding: ResourceLocation? = null,
|
@Json(name = "toggle_key_binding") var toggleKeyBinding: ResourceLocation? = null,
|
||||||
val scale: Float = 1.0f,
|
val scale: Float = 1.0f,
|
||||||
var enabled: Boolean = true,
|
var enabled: Boolean = true,
|
||||||
|
@ -22,6 +22,7 @@ import de.bixilon.minosoft.gui.rendering.RenderWindow
|
|||||||
import de.bixilon.minosoft.gui.rendering.Renderer
|
import de.bixilon.minosoft.gui.rendering.Renderer
|
||||||
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.HUDElement
|
import de.bixilon.minosoft.gui.rendering.hud.elements.HUDElement
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.elements.chat.ChatBoxHUDElement
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.elements.debug.HUDSystemDebugElement
|
import de.bixilon.minosoft.gui.rendering.hud.elements.debug.HUDSystemDebugElement
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.elements.debug.HUDWorldDebugElement
|
import de.bixilon.minosoft.gui.rendering.hud.elements.debug.HUDWorldDebugElement
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.elements.other.CrosshairHUDElement
|
import de.bixilon.minosoft.gui.rendering.hud.elements.other.CrosshairHUDElement
|
||||||
@ -75,7 +76,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
|||||||
addElement(ElementsNames.HOTBAR_RESOURCE_LOCATION, HotbarHUDElement(this), HUDElementProperties(
|
addElement(ElementsNames.HOTBAR_RESOURCE_LOCATION, HotbarHUDElement(this), HUDElementProperties(
|
||||||
position = Vec2(0.0f, -1.0f),
|
position = Vec2(0.0f, -1.0f),
|
||||||
xBinding = HUDElementProperties.PositionBindings.CENTER,
|
xBinding = HUDElementProperties.PositionBindings.CENTER,
|
||||||
yBinding = HUDElementProperties.PositionBindings.FURTHEST_POINT_AWAY,
|
|
||||||
))
|
))
|
||||||
|
|
||||||
addElement(ElementsNames.CROSSHAIR_RESOURCE_LOCATION, CrosshairHUDElement(this), HUDElementProperties(
|
addElement(ElementsNames.CROSSHAIR_RESOURCE_LOCATION, CrosshairHUDElement(this), HUDElementProperties(
|
||||||
@ -85,18 +85,17 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
|||||||
))
|
))
|
||||||
addElement(ElementsNames.WORLD_DEBUG_SCREEN_RESOURCE_LOCATION, HUDWorldDebugElement(this), HUDElementProperties(
|
addElement(ElementsNames.WORLD_DEBUG_SCREEN_RESOURCE_LOCATION, HUDWorldDebugElement(this), HUDElementProperties(
|
||||||
position = Vec2(-1.0f, 1.0f),
|
position = Vec2(-1.0f, 1.0f),
|
||||||
xBinding = HUDElementProperties.PositionBindings.FURTHEST_POINT_AWAY,
|
|
||||||
yBinding = HUDElementProperties.PositionBindings.FURTHEST_POINT_AWAY,
|
|
||||||
toggleKeyBinding = KeyBindingsNames.TOGGLE_DEBUG_SCREEN,
|
toggleKeyBinding = KeyBindingsNames.TOGGLE_DEBUG_SCREEN,
|
||||||
enabled = false,
|
enabled = false,
|
||||||
))
|
))
|
||||||
addElement(ElementsNames.SYSTEM_DEBUG_SCREEN_RESOURCE_LOCATION, HUDSystemDebugElement(this), HUDElementProperties(
|
addElement(ElementsNames.SYSTEM_DEBUG_SCREEN_RESOURCE_LOCATION, HUDSystemDebugElement(this), HUDElementProperties(
|
||||||
position = Vec2(1.0f, 1.0f),
|
position = Vec2(1.0f, 1.0f),
|
||||||
xBinding = HUDElementProperties.PositionBindings.FURTHEST_POINT_AWAY,
|
|
||||||
yBinding = HUDElementProperties.PositionBindings.FURTHEST_POINT_AWAY,
|
|
||||||
toggleKeyBinding = KeyBindingsNames.TOGGLE_DEBUG_SCREEN,
|
toggleKeyBinding = KeyBindingsNames.TOGGLE_DEBUG_SCREEN,
|
||||||
enabled = false,
|
enabled = false,
|
||||||
))
|
))
|
||||||
|
addElement(ElementsNames.CHAT_RESOURCE_LOCATION, ChatBoxHUDElement(this), HUDElementProperties(
|
||||||
|
position = Vec2(0f, -1.0f),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addElement(resourceLocation: ResourceLocation, hudElement: HUDElement, defaultProperties: HUDElementProperties) {
|
fun addElement(resourceLocation: ResourceLocation, hudElement: HUDElement, defaultProperties: HUDElementProperties) {
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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 <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.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.HUDElement
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.elements.input.SubmittableTextField
|
||||||
|
|
||||||
|
class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer) {
|
||||||
|
private lateinit var inputField: SubmittableTextField
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
inputField = SubmittableTextField(font = hudRenderer.renderWindow.font, z = 100, maxLength = 256, onSubmit = {
|
||||||
|
try {
|
||||||
|
hudRenderer.renderWindow.connection.sender.sendChatMessage(it)
|
||||||
|
closeChat()
|
||||||
|
return@SubmittableTextField true
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
closeChat()
|
||||||
|
return@SubmittableTextField false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
layout.addChild(inputField)
|
||||||
|
|
||||||
|
hudRenderer.renderWindow.registerKeyCallback(KeyBindingsNames.OPEN_CHAT) { _, _ ->
|
||||||
|
openChat()
|
||||||
|
}
|
||||||
|
hudRenderer.renderWindow.registerKeyCallback(KeyBindingsNames.CLOSE_CHAT) { _, _ ->
|
||||||
|
closeChat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun openChat() {
|
||||||
|
hudRenderer.renderWindow.currentInputConsumer = inputField
|
||||||
|
hudRenderer.renderWindow.currentElement.remove(KeyBindingsNames.WHEN_IN_GAME)
|
||||||
|
hudRenderer.renderWindow.currentElement.add(KeyBindingsNames.WHEN_IN_CHAT)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun closeChat() {
|
||||||
|
inputField.clearText()
|
||||||
|
hudRenderer.renderWindow.currentInputConsumer = null
|
||||||
|
hudRenderer.renderWindow.currentElement.remove(KeyBindingsNames.WHEN_IN_CHAT)
|
||||||
|
hudRenderer.renderWindow.currentElement.add(KeyBindingsNames.WHEN_IN_GAME)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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 <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.input
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
|
|
||||||
|
interface KeyConsumer {
|
||||||
|
|
||||||
|
val focused: Boolean
|
||||||
|
|
||||||
|
fun charInput(char: Char) {}
|
||||||
|
|
||||||
|
fun keyInput(keyCodes: KeyCodes) {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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 <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.input
|
||||||
|
|
||||||
|
import glm_.vec2.Vec2i
|
||||||
|
|
||||||
|
interface MouseConsumer {
|
||||||
|
val focused: Boolean
|
||||||
|
|
||||||
|
fun mouseMove(position: Vec2i) {}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* 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 <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.input
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
|
import de.bixilon.minosoft.gui.rendering.font.Font
|
||||||
|
import glm_.vec2.Vec2i
|
||||||
|
|
||||||
|
class SubmittableTextField(
|
||||||
|
start: Vec2i = Vec2i(0, 0),
|
||||||
|
z: Int = 0,
|
||||||
|
font: Font,
|
||||||
|
defaultText: String = "",
|
||||||
|
maxLength: Int = 256,
|
||||||
|
private val onSubmit: (text: String) -> Boolean,
|
||||||
|
) : TextField(start, z, font, defaultText, maxLength) {
|
||||||
|
|
||||||
|
fun submit() {
|
||||||
|
if (!onSubmit.invoke(text)) {
|
||||||
|
// failed
|
||||||
|
return
|
||||||
|
}
|
||||||
|
text = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun keyInput(keyCodes: KeyCodes) {
|
||||||
|
if (keyCodes == KeyCodes.KEY_ENTER) {
|
||||||
|
// submit
|
||||||
|
submit()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
super.keyInput(keyCodes)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* 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 <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.input
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
|
import de.bixilon.minosoft.gui.rendering.font.Font
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.elements.primitive.Layout
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.elements.primitive.TextElement
|
||||||
|
import de.bixilon.minosoft.util.MMath
|
||||||
|
import glm_.vec2.Vec2i
|
||||||
|
|
||||||
|
open class TextField(
|
||||||
|
start: Vec2i = Vec2i(0, 0),
|
||||||
|
z: Int = 0,
|
||||||
|
font: Font,
|
||||||
|
defaultText: String = "",
|
||||||
|
val maxLength: Int = 256,
|
||||||
|
) : Layout(start, z), KeyConsumer, MouseConsumer {
|
||||||
|
override var focused: Boolean = true
|
||||||
|
private var textBuilder: StringBuilder = StringBuilder(defaultText)
|
||||||
|
private val textElement = TextElement(ChatComponent.valueOf(text), font)
|
||||||
|
private var position = text.length
|
||||||
|
|
||||||
|
var text: String
|
||||||
|
get() = textBuilder.toString()
|
||||||
|
set(value) {
|
||||||
|
position = value.length
|
||||||
|
textBuilder = StringBuilder(value)
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
addChild(textElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearText() {
|
||||||
|
textBuilder.clear()
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun update() {
|
||||||
|
textElement.text = ChatComponent.valueOf(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()
|
||||||
|
}
|
||||||
|
}
|
@ -34,7 +34,6 @@ import glm_.vec2.Vec2i
|
|||||||
class HotbarHUDElement(
|
class HotbarHUDElement(
|
||||||
hudRender: HUDRenderer,
|
hudRender: HUDRenderer,
|
||||||
) : HUDElement(hudRender) {
|
) : HUDElement(hudRender) {
|
||||||
|
|
||||||
private lateinit var hotbarBase: HotbarBaseElement
|
private lateinit var hotbarBase: HotbarBaseElement
|
||||||
|
|
||||||
private lateinit var experienceBar: ProgressBar
|
private lateinit var experienceBar: ProgressBar
|
||||||
@ -55,7 +54,6 @@ class HotbarHUDElement(
|
|||||||
z = 1,
|
z = 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
levelText = TextElement(
|
levelText = TextElement(
|
||||||
font = hudRenderer.renderWindow.font,
|
font = hudRenderer.renderWindow.font,
|
||||||
background = false,
|
background = false,
|
||||||
@ -110,7 +108,6 @@ class HotbarHUDElement(
|
|||||||
healthBar.prepare()
|
healthBar.prepare()
|
||||||
prepare()
|
prepare()
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun prepare() {
|
private fun prepare() {
|
||||||
@ -166,7 +163,7 @@ class HotbarHUDElement(
|
|||||||
private val frame = ImageElement(textureLike = frameHUDAtlasElement, z = 2)
|
private val frame = ImageElement(textureLike = frameHUDAtlasElement, z = 2)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
fakeX = base.size.x.toInt()
|
fakeX = base.size.x
|
||||||
addChild(base)
|
addChild(base)
|
||||||
addChild(frame)
|
addChild(frame)
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ import org.checkerframework.common.value.qual.IntRange;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PacketSender {
|
public class PacketSender {
|
||||||
public static final String[] ILLEGAL_CHAT_CHARS = {"§"};
|
public static final char[] ILLEGAL_CHAT_CHARS = {'§', '\n', '\r'};
|
||||||
private final PlayConnection connection;
|
private final PlayConnection connection;
|
||||||
|
|
||||||
public PacketSender(PlayConnection connection) {
|
public PacketSender(PlayConnection connection) {
|
||||||
@ -45,8 +45,11 @@ public class PacketSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void sendChatMessage(String message) {
|
public void sendChatMessage(String message) {
|
||||||
for (String illegalChar : ILLEGAL_CHAT_CHARS) {
|
if (message.isBlank()) {
|
||||||
if (message.contains(illegalChar)) {
|
throw new IllegalArgumentException(("Chat message is blank!"));
|
||||||
|
}
|
||||||
|
for (char illegalChar : ILLEGAL_CHAT_CHARS) {
|
||||||
|
if (message.indexOf(illegalChar) != -1) {
|
||||||
throw new IllegalArgumentException(String.format("%s is not allowed in chat", illegalChar));
|
throw new IllegalArgumentException(String.format("%s is not allowed in chat", illegalChar));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user