mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
rendering: crosshair, improved hotbar, experience bar, network: add packet data check
This commit is contained in:
parent
71a75b7b53
commit
63eb03a17b
@ -39,6 +39,7 @@ class Player(val account: Account) {
|
|||||||
var selectedSlot: Int = 0
|
var selectedSlot: Int = 0
|
||||||
var level = 0
|
var level = 0
|
||||||
var totalExperience = 0
|
var totalExperience = 0
|
||||||
|
var experienceBarProgress = 0f
|
||||||
var entity: PlayerEntity? = null
|
var entity: PlayerEntity? = null
|
||||||
var isSpawnConfirmed = false
|
var isSpawnConfirmed = false
|
||||||
var playerUUID: UUID = account.uuid
|
var playerUUID: UUID = account.uuid
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.hud
|
package de.bixilon.minosoft.gui.rendering.hud
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.text.RGBColor
|
||||||
import de.bixilon.minosoft.gui.rendering.util.Mesh
|
import de.bixilon.minosoft.gui.rendering.util.Mesh
|
||||||
import glm_.BYTES
|
import glm_.BYTES
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
@ -32,21 +33,28 @@ class HUDMesh : Mesh() {
|
|||||||
glEnableVertexAttribArray(index++)
|
glEnableVertexAttribArray(index++)
|
||||||
glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.BYTES, (5 * Float.BYTES).toLong())
|
glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.BYTES, (5 * Float.BYTES).toLong())
|
||||||
glEnableVertexAttribArray(index++)
|
glEnableVertexAttribArray(index++)
|
||||||
|
glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.BYTES, (6 * Float.BYTES).toLong())
|
||||||
|
glEnableVertexAttribArray(index++)
|
||||||
super.unbind()
|
super.unbind()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun addVertex(position: Vec3, textureCoordinates: Vec2, atlasPage: Int) {
|
fun addVertex(position: Vec3, textureCoordinates: Vec2, atlasPage: Int, tintColor: RGBColor? = null) {
|
||||||
data.add(position.x)
|
data.add(position.x)
|
||||||
data.add(position.y)
|
data.add(position.y)
|
||||||
data.add(position.z)
|
data.add(position.z)
|
||||||
data.add(textureCoordinates.x)
|
data.add(textureCoordinates.x)
|
||||||
data.add(textureCoordinates.y)
|
data.add(textureCoordinates.y)
|
||||||
data.add(Float.fromBits(atlasPage))
|
data.add(Float.fromBits(atlasPage))
|
||||||
|
if (tintColor == null) {
|
||||||
|
data.add(0f)
|
||||||
|
} else {
|
||||||
|
data.add(Float.fromBits(tintColor.color))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val FLOATS_PER_VERTEX = 6
|
private const val FLOATS_PER_VERTEX = 7
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,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.other.CrosshairHUDElement
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.elements.other.HotbarHUDElement
|
import de.bixilon.minosoft.gui.rendering.hud.elements.other.HotbarHUDElement
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.elements.text.HUDTextElement
|
import de.bixilon.minosoft.gui.rendering.hud.elements.text.HUDTextElement
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||||
@ -37,10 +38,11 @@ class HUDRenderer(val connection: Connection, val renderWindow: RenderWindow) :
|
|||||||
val hudElements: MutableMap<ResourceLocation, HUDElement> = mutableMapOf(
|
val hudElements: MutableMap<ResourceLocation, HUDElement> = mutableMapOf(
|
||||||
ResourceLocation("minosoft:hud_text_renderer") to HUDTextElement(connection, this, renderWindow),
|
ResourceLocation("minosoft:hud_text_renderer") to HUDTextElement(connection, this, renderWindow),
|
||||||
ResourceLocation("minosoft:hotbar") to HotbarHUDElement(this),
|
ResourceLocation("minosoft:hotbar") to HotbarHUDElement(this),
|
||||||
|
ResourceLocation("minosoft:crosshair") to CrosshairHUDElement(this),
|
||||||
)
|
)
|
||||||
val hudShader = Shader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_vertex.glsl"), ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_fragment.glsl"))
|
val hudShader = Shader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_vertex.glsl"), ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_fragment.glsl"))
|
||||||
lateinit var hudTextures: TextureArray
|
lateinit var hudAtlasTextures: TextureArray
|
||||||
lateinit var hudImages: Map<ResourceLocation, HUDAtlasElement>
|
lateinit var hudAtlasElements: Map<ResourceLocation, HUDAtlasElement>
|
||||||
var lastTickTime = 0L
|
var lastTickTime = 0L
|
||||||
var orthographicMatrix: Mat4 = Mat4()
|
var orthographicMatrix: Mat4 = Mat4()
|
||||||
private set
|
private set
|
||||||
@ -51,10 +53,10 @@ class HUDRenderer(val connection: Connection, val renderWindow: RenderWindow) :
|
|||||||
hudShader.load(Minosoft.MINOSOFT_ASSETS_MANAGER)
|
hudShader.load(Minosoft.MINOSOFT_ASSETS_MANAGER)
|
||||||
|
|
||||||
val hudImages = HUDAtlasElement.deserialize(ResourceLocationJsonMap.create(Minosoft.MINOSOFT_ASSETS_MANAGER.readJsonAsset(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "mapping/atlas.json"))), connection.version.versionId)
|
val hudImages = HUDAtlasElement.deserialize(ResourceLocationJsonMap.create(Minosoft.MINOSOFT_ASSETS_MANAGER.readJsonAsset(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "mapping/atlas.json"))), connection.version.versionId)
|
||||||
this.hudImages = hudImages.second
|
this.hudAtlasElements = hudImages.second
|
||||||
|
|
||||||
hudTextures = TextureArray.createTextureArray(connection.version.assetsManager, hudImages.first.toSet())
|
hudAtlasTextures = TextureArray.createTextureArray(connection.version.assetsManager, hudImages.first.toSet())
|
||||||
hudTextures.load()
|
hudAtlasTextures.load()
|
||||||
|
|
||||||
for (element in hudElements.values) {
|
for (element in hudElements.values) {
|
||||||
element.init()
|
element.init()
|
||||||
@ -62,7 +64,7 @@ class HUDRenderer(val connection: Connection, val renderWindow: RenderWindow) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun postInit() {
|
override fun postInit() {
|
||||||
hudTextures.use(hudShader, "hudTextureArray")
|
hudAtlasTextures.use(hudShader, "hudTextureArray")
|
||||||
for (element in hudElements.values) {
|
for (element in hudElements.values) {
|
||||||
element.postInit()
|
element.postInit()
|
||||||
}
|
}
|
||||||
|
@ -22,14 +22,14 @@ data class Vec2Binding(
|
|||||||
val start: Vec2,
|
val start: Vec2,
|
||||||
val end: Vec2,
|
val end: Vec2,
|
||||||
) {
|
) {
|
||||||
val size: Vec2 = glm.abs(Vec2(start - end))
|
val size: Vec2 = glm.abs(Vec2(start - end)) + 1
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun deserialize(json: JsonElement): Vec2Binding {
|
fun deserialize(json: JsonElement): Vec2Binding {
|
||||||
check(json is JsonObject)
|
check(json is JsonObject)
|
||||||
|
|
||||||
return Vec2Binding(json["start"].asJsonArray.let { Vec2(it[0].asInt, it[1].asInt) }, json["end"].asJsonArray.let { Vec2(it[0].asInt, it[1].asInt) + 1 })
|
return Vec2Binding(json["start"].asJsonArray.let { Vec2(it[0].asInt, it[1].asInt) }, json["end"].asJsonArray.let { Vec2(it[0].asInt, it[1].asInt) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ import de.bixilon.minosoft.gui.rendering.hud.HUDElementProperties
|
|||||||
import de.bixilon.minosoft.gui.rendering.hud.HUDMesh
|
import de.bixilon.minosoft.gui.rendering.hud.HUDMesh
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
||||||
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.other.HotbarHUDElement
|
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec4.Vec4
|
import glm_.vec4.Vec4
|
||||||
@ -33,13 +32,13 @@ abstract class HUDElement(protected val hudRenderer: HUDRenderer) {
|
|||||||
open fun screenChangeResizeCallback(screenWidth: Int, screenHeight: Int) {}
|
open fun screenChangeResizeCallback(screenWidth: Int, screenHeight: Int) {}
|
||||||
|
|
||||||
|
|
||||||
fun getRealPosition(elementSize: Vec2, elementProperties: HUDElementProperties, realType: HotbarHUDElement.RealTypes, innerOffset: Vec2 = Vec2()): Vec2 {
|
fun getRealPosition(elementSize: Vec2, elementProperties: HUDElementProperties, realType: RealTypes, innerOffset: Vec2 = Vec2()): Vec2 {
|
||||||
// ToDo: Improve this code
|
// ToDo: Improve this code
|
||||||
val halfElementSize = elementSize / 2f
|
val halfElementSize = elementSize / 2f
|
||||||
val realPosition = elementProperties.position * hudRenderer.renderWindow.screenDimensions
|
val realPosition = elementProperties.position * hudRenderer.renderWindow.screenDimensions
|
||||||
|
|
||||||
fun getValue(elementSize: Float, halfSize: Float, position: Float, binding: HUDElementProperties.PositionBindings, innerOffset: Float): Float {
|
fun getValue(elementSize: Float, halfSize: Float, position: Float, binding: HUDElementProperties.PositionBindings, innerOffset: Float): Float {
|
||||||
val ourHalfSize = if (realType == HotbarHUDElement.RealTypes.START) {
|
val ourHalfSize = if (realType == RealTypes.START) {
|
||||||
-halfSize
|
-halfSize
|
||||||
} else {
|
} else {
|
||||||
halfSize
|
halfSize
|
||||||
@ -63,14 +62,14 @@ abstract class HUDElement(protected val hudRenderer: HUDRenderer) {
|
|||||||
0f
|
0f
|
||||||
} else {
|
} else {
|
||||||
when (realType) {
|
when (realType) {
|
||||||
HotbarHUDElement.RealTypes.START -> {
|
RealTypes.START -> {
|
||||||
if (position < 0f) {
|
if (position < 0f) {
|
||||||
position
|
position
|
||||||
} else {
|
} else {
|
||||||
position - (elementSize)
|
position - (elementSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HotbarHUDElement.RealTypes.END -> {
|
RealTypes.END -> {
|
||||||
if (position < 0f) {
|
if (position < 0f) {
|
||||||
position + (elementSize)
|
position + (elementSize)
|
||||||
} else {
|
} else {
|
||||||
@ -91,15 +90,20 @@ abstract class HUDElement(protected val hudRenderer: HUDRenderer) {
|
|||||||
|
|
||||||
|
|
||||||
fun drawImage(start: Vec2, end: Vec2, hudMesh: HUDMesh, hudAtlasElement: HUDAtlasElement, z: Int = 1) {
|
fun drawImage(start: Vec2, end: Vec2, hudMesh: HUDMesh, hudAtlasElement: HUDAtlasElement, z: Int = 1) {
|
||||||
|
val textureStart = Vec2((hudAtlasElement.binding.start.x * hudAtlasElement.texture.widthFactor) / hudAtlasElement.texture.width.toFloat(), (hudAtlasElement.binding.start.y * hudAtlasElement.texture.heightFactor) / hudAtlasElement.texture.height.toFloat())
|
||||||
|
val textureEnd = Vec2(((hudAtlasElement.binding.end.x + 1) * hudAtlasElement.texture.widthFactor) / (hudAtlasElement.texture.width + 1f), ((hudAtlasElement.binding.end.y + 1) * hudAtlasElement.texture.heightFactor) / (hudAtlasElement.texture.height + 1f))
|
||||||
|
|
||||||
|
drawImage(start, end, hudMesh, hudAtlasElement, textureStart, textureEnd, z)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun drawImage(start: Vec2, end: Vec2, hudMesh: HUDMesh, hudAtlasElement: HUDAtlasElement, textureStart: Vec2, textureEnd: Vec2, z: Int = 1) {
|
||||||
val modelStart = hudRenderer.orthographicMatrix * Vec4(start, 1f, 1.0f)
|
val modelStart = hudRenderer.orthographicMatrix * Vec4(start, 1f, 1.0f)
|
||||||
val modelEnd = hudRenderer.orthographicMatrix * Vec4(end, 1f, 1.0f)
|
val modelEnd = hudRenderer.orthographicMatrix * Vec4(end, 1f, 1.0f)
|
||||||
|
|
||||||
val textureStart = Vec2((hudAtlasElement.binding.start.x * hudAtlasElement.texture.widthFactor) / hudAtlasElement.texture.width.toFloat(), (hudAtlasElement.binding.start.y * hudAtlasElement.texture.heightFactor) / hudAtlasElement.texture.height.toFloat())
|
|
||||||
val textureEnd = Vec2((hudAtlasElement.binding.end.x * hudAtlasElement.texture.widthFactor) / hudAtlasElement.texture.width.toFloat(), (hudAtlasElement.binding.end.y * hudAtlasElement.texture.heightFactor) / hudAtlasElement.texture.height.toFloat())
|
|
||||||
|
|
||||||
|
|
||||||
val realZ = HUD_Z_COORDINATE + HUD_Z_COORDINATE_Z_FACTOR * z
|
val realZ = HUD_Z_COORDINATE + HUD_Z_COORDINATE_Z_FACTOR * z
|
||||||
|
|
||||||
|
|
||||||
hudMesh.addVertex(Vec3(modelStart.x, modelStart.y, realZ), Vec2(textureStart.x, textureEnd.y), hudAtlasElement.texture.id)
|
hudMesh.addVertex(Vec3(modelStart.x, modelStart.y, realZ), Vec2(textureStart.x, textureEnd.y), hudAtlasElement.texture.id)
|
||||||
hudMesh.addVertex(Vec3(modelEnd.x, modelStart.y, realZ), Vec2(textureEnd.x, textureEnd.y), hudAtlasElement.texture.id)
|
hudMesh.addVertex(Vec3(modelEnd.x, modelStart.y, realZ), Vec2(textureEnd.x, textureEnd.y), hudAtlasElement.texture.id)
|
||||||
hudMesh.addVertex(Vec3(modelStart.x, modelEnd.y, realZ), Vec2(textureStart.x, textureStart.y), hudAtlasElement.texture.id)
|
hudMesh.addVertex(Vec3(modelStart.x, modelEnd.y, realZ), Vec2(textureStart.x, textureStart.y), hudAtlasElement.texture.id)
|
||||||
@ -108,6 +112,12 @@ abstract class HUDElement(protected val hudRenderer: HUDRenderer) {
|
|||||||
hudMesh.addVertex(Vec3(modelEnd.x, modelEnd.y, realZ), Vec2(textureEnd.x, textureStart.y), hudAtlasElement.texture.id)
|
hudMesh.addVertex(Vec3(modelEnd.x, modelEnd.y, realZ), Vec2(textureEnd.x, textureStart.y), hudAtlasElement.texture.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum class RealTypes {
|
||||||
|
START,
|
||||||
|
END
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val HUD_Z_COORDINATE = -0.9996f
|
private const val HUD_Z_COORDINATE = -0.9996f
|
||||||
private const val HUD_Z_COORDINATE_Z_FACTOR = -0.000001f
|
private const val HUD_Z_COORDINATE_Z_FACTOR = -0.000001f
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.HUDMesh
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.atlas.HUDAtlasElement
|
||||||
|
import glm_.vec2.Vec2
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
class ProgressBar(
|
||||||
|
private val emptyAtlasElement: HUDAtlasElement,
|
||||||
|
private val fullAtlasElement: HUDAtlasElement,
|
||||||
|
private val hudElement: HUDElement,
|
||||||
|
) {
|
||||||
|
val size: Vec2 = emptyAtlasElement.binding.size
|
||||||
|
|
||||||
|
fun draw(hudMesh: HUDMesh, start: Vec2, end: Vec2, progress: Float, z: Int = 1) {
|
||||||
|
hudElement.drawImage(start, end, hudMesh, emptyAtlasElement, z)
|
||||||
|
|
||||||
|
if (progress == 0.0f) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val xDiff = abs(end.x - start.x)
|
||||||
|
|
||||||
|
val ourXDiff = xDiff * progress
|
||||||
|
|
||||||
|
val textureStart = Vec2((fullAtlasElement.binding.start.x * fullAtlasElement.texture.widthFactor) / fullAtlasElement.texture.width.toFloat(), (fullAtlasElement.binding.start.y * fullAtlasElement.texture.heightFactor) / fullAtlasElement.texture.height.toFloat())
|
||||||
|
var textureEnd = Vec2(((fullAtlasElement.binding.end.x + 1) * fullAtlasElement.texture.widthFactor) / (fullAtlasElement.texture.width + 1f), ((fullAtlasElement.binding.end.y + 1) * fullAtlasElement.texture.heightFactor) / (fullAtlasElement.texture.height + 1f))
|
||||||
|
|
||||||
|
textureEnd = Vec2((textureEnd.x - textureStart.x) * progress, textureEnd.y)
|
||||||
|
|
||||||
|
hudElement.drawImage(start, Vec2(start.x + ourXDiff, end.y), hudMesh, fullAtlasElement, textureStart, textureEnd, z + 1)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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.other
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.HUDElementProperties
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.HUDMesh
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.atlas.HUDAtlasElement
|
||||||
|
import de.bixilon.minosoft.gui.rendering.hud.elements.HUDElement
|
||||||
|
import glm_.vec2.Vec2
|
||||||
|
|
||||||
|
class CrosshairHUDElement(
|
||||||
|
hudRender: HUDRenderer,
|
||||||
|
) : HUDElement(hudRender) {
|
||||||
|
override val elementProperties = HUDElementProperties(
|
||||||
|
position = Vec2(0f, 0f),
|
||||||
|
xBinding = HUDElementProperties.PositionBindings.CENTER,
|
||||||
|
yBinding = HUDElementProperties.PositionBindings.CENTER,
|
||||||
|
scale = 1f,
|
||||||
|
enabled = true,
|
||||||
|
)
|
||||||
|
|
||||||
|
private lateinit var crosshairAtlasElement: HUDAtlasElement
|
||||||
|
|
||||||
|
private lateinit var crosshairRealSize: Vec2
|
||||||
|
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
crosshairAtlasElement = hudRenderer.hudAtlasElements[ResourceLocation("minecraft:crosshair")]!!
|
||||||
|
crosshairRealSize = crosshairAtlasElement.binding.size * hudRenderer.hudScale.scale * elementProperties.scale
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun prepare(hudMesh: HUDMesh) {
|
||||||
|
drawImage(getRealPosition(crosshairRealSize, elementProperties, RealTypes.START), getRealPosition(crosshairRealSize, elementProperties, RealTypes.END), hudMesh, crosshairAtlasElement, 1)
|
||||||
|
}
|
||||||
|
}
|
@ -14,12 +14,14 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.hud.elements.other
|
package de.bixilon.minosoft.gui.rendering.hud.elements.other
|
||||||
|
|
||||||
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
||||||
|
import de.bixilon.minosoft.data.GameModes
|
||||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.HUDElementProperties
|
import de.bixilon.minosoft.gui.rendering.hud.HUDElementProperties
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.HUDMesh
|
import de.bixilon.minosoft.gui.rendering.hud.HUDMesh
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
||||||
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.ProgressBar
|
||||||
import glm_.glm
|
import glm_.glm
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
|
|
||||||
@ -34,18 +36,29 @@ class HotbarHUDElement(
|
|||||||
enabled = true,
|
enabled = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
lateinit var hotbarBaseAtlas: HUDAtlasElement
|
private val realScale = elementProperties.scale * hudRenderer.hudScale.scale
|
||||||
lateinit var hotbarSelectedSlotFrame: HUDAtlasElement
|
private val elementPadding = 2 * realScale
|
||||||
|
|
||||||
|
private lateinit var hotbarBaseAtlasElement: HUDAtlasElement
|
||||||
private lateinit var hotbarBaseRealSize: Vec2
|
private lateinit var hotbarBaseRealSize: Vec2
|
||||||
|
private lateinit var hotbarSelectedSlotFrameAtlasElement: HUDAtlasElement
|
||||||
private lateinit var hotbarSelectedSlotFrameRealSize: Vec2
|
private lateinit var hotbarSelectedSlotFrameRealSize: Vec2
|
||||||
|
|
||||||
|
|
||||||
|
private lateinit var experienceBar: ProgressBar
|
||||||
|
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
hotbarBaseAtlas = hudRenderer.hudImages[ResourceLocation("minecraft:hotbar_base")]!!
|
hotbarBaseAtlasElement = hudRenderer.hudAtlasElements[ResourceLocation("minecraft:hotbar_base")]!!
|
||||||
hotbarBaseRealSize = hotbarBaseAtlas.binding.size * hudRenderer.hudScale.scale * elementProperties.scale
|
hotbarBaseRealSize = hotbarBaseAtlasElement.binding.size * hudRenderer.hudScale.scale * elementProperties.scale
|
||||||
hotbarSelectedSlotFrame = hudRenderer.hudImages[ResourceLocation("minecraft:hotbar_selected_slot_frame")]!!
|
hotbarSelectedSlotFrameAtlasElement = hudRenderer.hudAtlasElements[ResourceLocation("minecraft:hotbar_selected_slot_frame")]!!
|
||||||
hotbarSelectedSlotFrameRealSize = hotbarSelectedSlotFrame.binding.size * hudRenderer.hudScale.scale * elementProperties.scale
|
hotbarSelectedSlotFrameRealSize = hotbarSelectedSlotFrameAtlasElement.binding.size * hudRenderer.hudScale.scale * elementProperties.scale
|
||||||
|
|
||||||
|
experienceBar = ProgressBar(
|
||||||
|
hudRenderer.hudAtlasElements[ResourceLocation("minecraft:experience_bar_empty")]!!,
|
||||||
|
hudRenderer.hudAtlasElements[ResourceLocation("minecraft:experience_bar_full")]!!,
|
||||||
|
this
|
||||||
|
)
|
||||||
|
|
||||||
for ((slotIndex, resourceLocation) in KeyBindingsNames.SELECT_HOTBAR_SLOTS.withIndex()) {
|
for ((slotIndex, resourceLocation) in KeyBindingsNames.SELECT_HOTBAR_SLOTS.withIndex()) {
|
||||||
hudRenderer.renderWindow.registerKeyCallback(resourceLocation) { _, _ ->
|
hudRenderer.renderWindow.registerKeyCallback(resourceLocation) { _, _ ->
|
||||||
@ -55,28 +68,35 @@ class HotbarHUDElement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum class RealTypes {
|
|
||||||
START,
|
|
||||||
END
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun drawBaseBar(hudMesh: HUDMesh) {
|
|
||||||
val hotbarStart = getRealPosition(hotbarBaseRealSize, elementProperties, RealTypes.START)
|
|
||||||
drawImage(hotbarStart, getRealPosition(hotbarBaseRealSize, elementProperties, RealTypes.END), hudMesh, hotbarBaseAtlas, 1)
|
|
||||||
|
|
||||||
|
|
||||||
val selectedSlotBinding = hotbarBaseAtlas.slots[hudRenderer.connection.player.selectedSlot] ?: return
|
|
||||||
val selectedSlotFrameBinding = hotbarSelectedSlotFrame.slots[0] ?: return
|
|
||||||
|
|
||||||
val slotSizeFactorDelta = glm.abs(Vec2(hotbarSelectedSlotFrame.binding.size - selectedSlotFrameBinding.size))
|
|
||||||
|
|
||||||
val selectedSlotStart = hotbarStart + selectedSlotBinding.start * hudRenderer.hudScale.scale * elementProperties.scale - slotSizeFactorDelta
|
|
||||||
val selectedSlotEnd = hotbarStart + selectedSlotBinding.end * hudRenderer.hudScale.scale * elementProperties.scale + slotSizeFactorDelta
|
|
||||||
|
|
||||||
drawImage(selectedSlotStart, selectedSlotEnd, hudMesh, hotbarSelectedSlotFrame, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun prepare(hudMesh: HUDMesh) {
|
override fun prepare(hudMesh: HUDMesh) {
|
||||||
drawBaseBar(hudMesh)
|
if (hudRenderer.connection.player.gameMode == GameModes.SPECTATOR) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// hotbar
|
||||||
|
val hotbarStart = getRealPosition(hotbarBaseRealSize, elementProperties, RealTypes.START)
|
||||||
|
val hotbarEnd = getRealPosition(hotbarBaseRealSize, elementProperties, RealTypes.END)
|
||||||
|
drawImage(hotbarStart, hotbarEnd, hudMesh, hotbarBaseAtlasElement, 1)
|
||||||
|
|
||||||
|
// selectedFrame
|
||||||
|
val selectedSlotBinding = hotbarBaseAtlasElement.slots[hudRenderer.connection.player.selectedSlot] ?: return
|
||||||
|
val selectedSlotFrameBinding = hotbarSelectedSlotFrameAtlasElement.slots[0] ?: return
|
||||||
|
|
||||||
|
val slotSizeFactorDelta = glm.abs(Vec2(hotbarSelectedSlotFrameAtlasElement.binding.size - selectedSlotFrameBinding.size))
|
||||||
|
|
||||||
|
val selectedSlotStart = hotbarStart + selectedSlotBinding.start * realScale - slotSizeFactorDelta + Vec2(0, realScale)
|
||||||
|
val selectedSlotEnd = hotbarStart + selectedSlotBinding.end * realScale + slotSizeFactorDelta + Vec2(realScale, realScale)
|
||||||
|
|
||||||
|
drawImage(selectedSlotStart, selectedSlotEnd, hudMesh, hotbarSelectedSlotFrameAtlasElement, 2)
|
||||||
|
|
||||||
|
|
||||||
|
if (hudRenderer.connection.player.gameMode == GameModes.CREATIVE) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// experience bar
|
||||||
|
val experienceBarStart = Vec2(hotbarStart.x, (hotbarEnd.y + (experienceBar.size.y * realScale) + elementPadding))
|
||||||
|
val experienceBarEnd = Vec2(hotbarEnd.x, (hotbarEnd.y + elementPadding))
|
||||||
|
|
||||||
|
experienceBar.draw(hudMesh, experienceBarStart, experienceBarEnd, hudRenderer.connection.player.experienceBarProgress, 3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ class HUDDebugScreenElement(private val hudTextElement: HUDTextElement) : HUDTex
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getScreenDimensions(): String {
|
private fun getScreenDimensions(): String {
|
||||||
return "${hudTextElement.renderWindow.screenDimensions.x}x${hudTextElement.renderWindow.screenDimensions.y}"
|
return "${hudTextElement.renderWindow.screenWidth}x${hudTextElement.renderWindow.screenHeight}"
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLocation(): String {
|
private fun getLocation(): String {
|
||||||
|
@ -39,6 +39,7 @@ class TextureArray(val textures: Collection<Texture>, val maxWidth: Int, val max
|
|||||||
|
|
||||||
for (texture in textures) {
|
for (texture in textures) {
|
||||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, texture.id, texture.width, texture.height, 1, GL_RGBA, GL_UNSIGNED_BYTE, texture.buffer)
|
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, texture.id, texture.width, texture.height, 1, GL_RGBA, GL_UNSIGNED_BYTE, texture.buffer)
|
||||||
|
texture.buffer.clear()
|
||||||
}
|
}
|
||||||
glGenerateMipmap(GL_TEXTURE_2D_ARRAY)
|
glGenerateMipmap(GL_TEXTURE_2D_ARRAY)
|
||||||
return textureId
|
return textureId
|
||||||
|
@ -83,14 +83,14 @@ public abstract class Network {
|
|||||||
boolean success;
|
boolean success;
|
||||||
try {
|
try {
|
||||||
success = packet.read(data);
|
success = packet.read(data);
|
||||||
|
if (data.getBytesLeft() > 0 || !success) {
|
||||||
|
throw new PacketParseException(String.format("Could not parse packet %s (used=%d, available=%d, total=%d, success=%s)", packetType, data.getPosition(), data.getBytesLeft(), data.getLength(), success));
|
||||||
|
}
|
||||||
|
packet.check(this.connection);
|
||||||
} catch (Throwable exception) {
|
} catch (Throwable exception) {
|
||||||
packet.onError(this.connection);
|
packet.onError(this.connection);
|
||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
if (data.getBytesLeft() > 0 || !success) {
|
|
||||||
packet.onError(this.connection);
|
|
||||||
throw new PacketParseException(String.format("Could not parse packet %s (used=%d, available=%d, total=%d, success=%s)", packetType, data.getPosition(), data.getBytesLeft(), data.getLength(), success));
|
|
||||||
}
|
|
||||||
return packet;
|
return packet;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Log.protocol(String.format("An error occurred while parsing a packet (%s): %s", packetType, e));
|
Log.protocol(String.format("An error occurred while parsing a packet (%s): %s", packetType, e));
|
||||||
|
@ -23,4 +23,6 @@ abstract class ClientboundPacket : Packet {
|
|||||||
open fun handle(connection: Connection) {}
|
open fun handle(connection: Connection) {}
|
||||||
|
|
||||||
open fun onError(connection: Connection) {}
|
open fun onError(connection: Connection) {}
|
||||||
|
|
||||||
|
open fun check(connection: Connection) {}
|
||||||
}
|
}
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Minosoft
|
|
||||||
* Copyright (C) 2020 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.protocol.packets.clientbound.play;
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.modding.event.events.ExperienceChangeEvent;
|
|
||||||
import de.bixilon.minosoft.protocol.network.Connection;
|
|
||||||
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
|
||||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
|
||||||
import de.bixilon.minosoft.util.logging.Log;
|
|
||||||
|
|
||||||
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_14W04A;
|
|
||||||
|
|
||||||
public class PacketSetExperience extends ClientboundPacket {
|
|
||||||
float bar;
|
|
||||||
int level;
|
|
||||||
int total;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean read(InByteBuffer buffer) {
|
|
||||||
this.bar = buffer.readFloat();
|
|
||||||
if (buffer.getVersionId() < V_14W04A) {
|
|
||||||
this.level = buffer.readUnsignedShort();
|
|
||||||
this.total = buffer.readUnsignedShort();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
this.level = buffer.readVarInt();
|
|
||||||
this.total = buffer.readVarInt();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(Connection connection) {
|
|
||||||
if (connection.fireEvent(new ExperienceChangeEvent(connection, this))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connection.getPlayer().setLevel(getLevel());
|
|
||||||
connection.getPlayer().setTotalExperience(getTotal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void log() {
|
|
||||||
Log.protocol(String.format("[IN] Level update received. Now at %d levels, totally %d exp", this.level, this.total));
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getBar() {
|
|
||||||
return this.bar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLevel() {
|
|
||||||
return this.level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTotal() {
|
|
||||||
return this.total;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2020 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.protocol.packets.clientbound.play
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.modding.event.events.ExperienceChangeEvent
|
||||||
|
import de.bixilon.minosoft.protocol.network.Connection
|
||||||
|
import de.bixilon.minosoft.protocol.packets.ClientboundPacket
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.InByteBuffer
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
|
||||||
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
|
|
||||||
|
class PacketSetExperience : ClientboundPacket() {
|
||||||
|
var bar = 0f
|
||||||
|
private set
|
||||||
|
var level = 0
|
||||||
|
private set
|
||||||
|
var total = 0
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun read(buffer: InByteBuffer): Boolean {
|
||||||
|
bar = buffer.readFloat()
|
||||||
|
if (buffer.versionId < ProtocolVersions.V_14W04A) {
|
||||||
|
level = buffer.readUnsignedShort()
|
||||||
|
total = buffer.readUnsignedShort()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
level = buffer.readVarInt()
|
||||||
|
total = buffer.readVarInt()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun check(connection: Connection) {
|
||||||
|
check(bar in 0.0f..1.0f) { "Bar is invalid!" }
|
||||||
|
check(level >= 0) { "Level is negative is invalid!" }
|
||||||
|
check(total >= 0) { "Total experience is negative!" }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun handle(connection: Connection) {
|
||||||
|
if (connection.fireEvent(ExperienceChangeEvent(connection, this))) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
connection.player.level = level
|
||||||
|
connection.player.experienceBarProgress = bar
|
||||||
|
connection.player.totalExperience = total
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun log() {
|
||||||
|
Log.protocol("[IN] Level update received. Now at $level level(s), total $total experience, experience bar at $bar", level, total)
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@
|
|||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
"start": [43, 3],
|
"start": [43, 3],
|
||||||
"end": [56, 18]
|
"end": [58, 18]
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"start": [63, 3],
|
"start": [63, 3],
|
||||||
@ -60,5 +60,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"minecraft:crosshair": {
|
||||||
|
"texture": "minecraft:textures/gui/icons.png",
|
||||||
|
"versions": {
|
||||||
|
"0": {
|
||||||
|
"start": [0, 0],
|
||||||
|
"end": [15, 15]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minecraft:experience_bar_empty": {
|
||||||
|
"texture": "minecraft:textures/gui/icons.png",
|
||||||
|
"versions": {
|
||||||
|
"0": {
|
||||||
|
"start": [0, 64],
|
||||||
|
"end": [181, 68]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minecraft:experience_bar_full": {
|
||||||
|
"texture": "minecraft:textures/gui/icons.png",
|
||||||
|
"versions": {
|
||||||
|
"0": {
|
||||||
|
"start": [0, 69],
|
||||||
|
"end": [181, 73]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,17 @@
|
|||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
|
|
||||||
in vec3 passTextureCoordinates;
|
in vec3 passTextureCoordinates;
|
||||||
|
in vec4 passTintColor;
|
||||||
|
|
||||||
uniform sampler2DArray hudTextureArray;
|
uniform sampler2DArray hudTextureArray;
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 textureColor = texture(hudTextureArray, passTextureCoordinates);
|
vec4 textureColor = texture(hudTextureArray, passTextureCoordinates);
|
||||||
if (textureColor.a == 0) {
|
if (passTintColor.a == 1.0f && textureColor.a == 0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
if (passTintColor.a != 0.0f){
|
||||||
|
textureColor *= passTintColor;
|
||||||
|
}
|
||||||
outColor = textureColor;
|
outColor = textureColor;
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,13 @@
|
|||||||
layout (location = 0) in vec3 inPosition;
|
layout (location = 0) in vec3 inPosition;
|
||||||
layout (location = 1) in vec2 textureIndex;
|
layout (location = 1) in vec2 textureIndex;
|
||||||
layout (location = 2) in uint textureLayer;
|
layout (location = 2) in uint textureLayer;
|
||||||
|
layout (location = 3) in uint tintColor;
|
||||||
|
|
||||||
out vec3 passTextureCoordinates;
|
out vec3 passTextureCoordinates;
|
||||||
|
out vec4 passTintColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(inPosition.xyz, 1.0f);
|
gl_Position = vec4(inPosition.xyz, 1.0f);
|
||||||
passTextureCoordinates = vec3(textureIndex, textureLayer);
|
passTextureCoordinates = vec3(textureIndex, textureLayer);
|
||||||
|
passTintColor = vec4(((tintColor >> 24u) & 0xFFu) / 255.0f, ((tintColor >> 16u) & 0xFFu) / 255.0f, ((tintColor >> 8u) & 0xFFu) / 255.0f, (tintColor & 0xFFu) / 255.0f);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user