wip refactor atlas

This commit is contained in:
Moritz Zwerger 2023-09-27 14:12:18 +02:00
parent 6fcfb71df3
commit 2f2bb2c77e
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
79 changed files with 813 additions and 685 deletions

View File

@ -26,8 +26,7 @@
"type": "object",
"properties": {
"texture": {
"type": "string",
"pattern": "\\w+:.+\\.png"
"type": "string"
},
"start": {
"$ref": "#/definitions/vec2i"
@ -80,13 +79,14 @@
}
},
"required": [
"texture",
"start",
"end"
"texture"
],
"optional": [
"slots",
"areas"
"areas",
"resolution",
"start",
"end"
],
"additionalProperties": false
}

View File

@ -38,8 +38,8 @@ class MemoryAssetsManager : AssetsManager {
override fun unload() {
}
override fun contains(path: ResourceLocation): Boolean {
return path in entries
override fun getAssetsManager(path: ResourceLocation): AssetsManager? {
return if (path in entries) this else null
}
fun push(path: ResourceLocation, data: ByteArray) {

View File

@ -35,7 +35,5 @@ object TestAssetsManager : AssetsManager {
override fun unload() {
}
override fun contains(path: ResourceLocation): Boolean {
return false
}
override fun getAssetsManager(path: ResourceLocation) = null
}

View File

@ -72,7 +72,8 @@ interface AssetsManager {
*/
fun unload()
operator fun contains(path: ResourceLocation): Boolean
fun getAssetsManager(path: ResourceLocation): AssetsManager?
operator fun contains(path: ResourceLocation) = getAssetsManager(path) != null
companion object {

View File

@ -91,7 +91,7 @@ class DirectoryAssetsManager(
return FileUtil.safeReadFile(path.filePath, false)
}
override fun contains(path: ResourceLocation): Boolean {
return path in assets
override fun getAssetsManager(path: ResourceLocation): AssetsManager? {
return if (path in assets) this else null
}
}

View File

@ -61,7 +61,7 @@ class ZipAssetsManager(
}
}
override fun contains(path: ResourceLocation): Boolean {
return path in assets
override fun getAssetsManager(path: ResourceLocation): AssetsManager? {
return if (path in assets) this else null
}
}

View File

@ -17,6 +17,7 @@ import com.fasterxml.jackson.databind.JsonNode
import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.kutil.string.StringUtil.formatPlaceholder
import de.bixilon.kutil.url.URLUtil.toURL
import de.bixilon.minosoft.assets.AssetsManager
import de.bixilon.minosoft.assets.InvalidAssetException
import de.bixilon.minosoft.assets.minecraft.MinecraftAssetsVersion.packFormat
import de.bixilon.minosoft.assets.properties.manager.AssetsManagerProperties
@ -161,11 +162,11 @@ class JarAssetsManager(
loaded = false
}
override fun contains(path: ResourceLocation): Boolean {
override fun getAssetsManager(path: ResourceLocation): AssetsManager? {
if (path.namespace != Namespaces.MINECRAFT) {
return false
return null
}
return path.path in assets
return if (path.path in assets) this else null
}
companion object {

View File

@ -22,6 +22,7 @@ import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.kutil.primitive.LongUtil.toLong
import de.bixilon.kutil.string.StringUtil.formatPlaceholder
import de.bixilon.kutil.url.URLUtil.toURL
import de.bixilon.minosoft.assets.AssetsManager
import de.bixilon.minosoft.assets.error.AssetCorruptedError
import de.bixilon.minosoft.assets.error.AssetNotFoundError
import de.bixilon.minosoft.assets.minecraft.MinecraftAssetsManager
@ -146,7 +147,7 @@ class IndexAssetsManager(
return FileAssetsUtil.readOrNull(property.hash, type = property.type.type, verify = verify)?.let { ByteArrayInputStream(it) }
}
override fun contains(path: ResourceLocation): Boolean {
return path in assets
override fun getAssetsManager(path: ResourceLocation): AssetsManager? {
return if (path in assets) this else null
}
}

View File

@ -81,13 +81,11 @@ class PriorityAssetsManager(
}
}
override fun contains(path: ResourceLocation): Boolean {
override fun getAssetsManager(path: ResourceLocation): AssetsManager? {
for (manager in managers) {
if (path in manager) {
return true
}
return manager.getAssetsManager(path) ?: continue
}
return false
return null
}
}

View File

@ -41,10 +41,10 @@ class ResourceAssetsManager(
return clazz.getResourceAsStream(url)
}
override fun contains(path: ResourceLocation): Boolean {
val stream = open(path) ?: return false
override fun getAssetsManager(path: ResourceLocation): AssetsManager? {
val stream = open(path) ?: return null
stream.close()
return true
return this
}
override fun get(path: ResourceLocation): InputStream {

View File

@ -16,6 +16,7 @@ package de.bixilon.minosoft.assets.util
import com.fasterxml.jackson.module.kotlin.readValue
import de.bixilon.kutil.buffer.BufferDefinition
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.json.JsonObject
import de.bixilon.mbf.MBFBinaryReader
import de.bixilon.minosoft.util.json.Jackson
import de.matthiasmann.twl.utils.PNGDecoder
@ -46,7 +47,7 @@ object InputStreamUtil {
return builder.toString()
}
fun InputStream.readJsonObject(close: Boolean = true): Map<String, Any> {
fun InputStream.readJsonObject(close: Boolean = true): JsonObject {
try {
return Jackson.MAPPER.readValue(this, Jackson.JSON_MAP_TYPE)
} finally {

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -26,5 +26,7 @@ enum class BossbarNotches {
companion object : ValuesEnum<BossbarNotches> {
override val VALUES: Array<BossbarNotches> = values()
override val NAME_MAP: Map<String, BossbarNotches> = EnumUtil.getEnumValues(VALUES)
val NOTCHES = arrayOf(NOTCHES_6, NOTCHES_10, NOTCHES_12, NOTCHES_20)
}
}

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.data.registries.identified
import de.bixilon.minosoft.config.StaticConfiguration
import de.bixilon.minosoft.util.KUtil.toResourceLocation
object ResourceLocationUtil {
@ -38,4 +39,21 @@ object ResourceLocationUtil {
throw IllegalArgumentException("Namespace is illegal: $namespace")
}
}
fun ResourceLocation.extend(prefix: String? = null, suffix: String? = null): ResourceLocation {
if (prefix == null && suffix == null) return this
var path = ""
if (prefix != null && !this.path.startsWith(prefix)) {
path += prefix
}
path += this.path
if (suffix != null && !path.endsWith(suffix)) {
path += suffix
}
return "$namespace:$path".toResourceLocation()
}
}

View File

@ -23,6 +23,7 @@ import de.bixilon.kutil.reflection.ReflectionUtil.forceSet
import de.bixilon.kutil.unit.UnitFormatter.formatNanos
import de.bixilon.minosoft.gui.rendering.RenderUtil.pause
import de.bixilon.minosoft.gui.rendering.font.manager.FontManager
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.input.key.DebugKeyBindings
import de.bixilon.minosoft.gui.rendering.input.key.DefaultKeyBindings
import de.bixilon.minosoft.gui.rendering.renderer.renderer.DefaultRenderer
@ -91,6 +92,8 @@ object RenderLoader {
initLatch.dec()
initLatch.await()
renderer[GUIRenderer]?.atlas?.load() // TODO: remove this
// Post init stage
Log.log(LogMessageType.RENDERING, LogLevels.VERBOSE) { "Loading textures (after ${stopwatch.labTime()})..." }
textures.staticTextures.load(renderLatch)

View File

@ -18,6 +18,7 @@ import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.kutil.observer.DataObserver.Companion.observed
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.events.ResizeWindowEvent
import de.bixilon.minosoft.gui.rendering.framebuffer.IntegratedFramebuffer
@ -36,7 +37,6 @@ import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.delegate.RenderingDelegate.observeRendering
class GUIRenderer(
@ -54,14 +54,13 @@ class GUIRenderer(
private set
var resolutionUpdate = true
override val framebuffer: IntegratedFramebuffer get() = context.framebuffer.gui
val shader = context.system.createShader("minosoft:gui".toResourceLocation()) { GUIShader(it) }
val atlasManager = AtlasManager(context)
val shader = context.system.createShader(minosoft("gui")) { GUIShader(it) }
val atlas = AtlasManager(context)
var currentMousePosition: Vec2 by observed(Vec2.EMPTY)
private set
override fun init(latch: AbstractLatch) {
atlasManager.init()
gui.init()
hud.init()
popper.init()
@ -69,7 +68,6 @@ class GUIRenderer(
}
override fun postInit(latch: AbstractLatch) {
atlasManager.postInit()
shader.load()
connection.events.listen<ResizeWindowEvent> { updateResolution(Vec2(it.size)) }

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2023 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.gui.atlas
class Atlas(
private val elements: Map<String, AtlasElement>,
) {
operator fun get(element: String): AtlasElement? {
return elements[element]
}
companion object {
operator fun Atlas?.get(element: String): AtlasElement? {
if (this == null) return null
return this[element]
}
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -14,10 +14,21 @@
package de.bixilon.minosoft.gui.rendering.gui.atlas
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kutil.json.JsonObject
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.toVec2
class AtlasArea(
val start: Vec2,
val end: Vec2,
) {
val size = end - start
companion object {
fun deserialize(data: JsonObject) = AtlasArea(
start = data["start"].toVec2(),
end = data["end"].toVec2(),
)
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -15,18 +15,15 @@ package de.bixilon.minosoft.gui.rendering.gui.atlas
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.gui.rendering.system.base.texture.TexturePart
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
class AtlasElement(
override val texture: Texture,
val resolution: Vec2i?,
val start: Vec2i,
val end: Vec2i,
val slots: Int2ObjectOpenHashMap<AtlasSlot>,
val areas: Map<String, AtlasArea>,
) : TexturePart {
override val size: Vec2i = end - start
override lateinit var uvStart: Vec2
override lateinit var uvEnd: Vec2
}
override val uvStart: Vec2,
override val uvEnd: Vec2,
override val size: Vec2i,
val slots: Int2ObjectMap<AtlasArea>?,
val areas: Map<String, AtlasArea>?,
) : TexturePart

View File

@ -0,0 +1,80 @@
/*
* Minosoft
* Copyright (C) 2020-2023 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.gui.atlas
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.json.JsonObject
import de.bixilon.minosoft.assets.util.InputStreamUtil.readJsonObject
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.identified.ResourceLocationUtil.extend
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class AtlasLoader(val context: RenderContext) {
private val raw: MutableMap<ResourceLocation, Map<String, RawAtlasElement>> = HashMap()
fun load(id: String, packFormat: Int, data: JsonObject): RawAtlasElement? {
val textureName = data["texture"]?.toResourceLocation()?.texture() ?: throw IllegalArgumentException("Missing texture!")
val assets = context.connection.assetsManager.getAssetsManager(textureName) ?: return null
// TODO: check packFormat match
return RawAtlasElement.deserialize(textureName, assets, data)
}
fun load(id: String, data: JsonObject): RawAtlasElement? {
// TODO: sort all by versionId (descending) and load first best matching
// try to load first best
TODO()
}
fun load(name: ResourceLocation, data: JsonObject) {
val elements: MutableMap<String, RawAtlasElement> = hashMapOf()
for ((id, element) in data) {
elements[id] = load(id, element.unsafeCast()) ?: continue
}
raw[name] = elements
}
fun load(name: ResourceLocation) {
val file = name.atlas()
val data = context.connection.assetsManager[file].readJsonObject()
load(name, data)
}
fun load(): Map<ResourceLocation, Atlas> {
val map: MutableMap<ResourceLocation, Atlas> = HashMap()
val textures = AtlasTextureManager(context)
for ((atlasName, atlas) in this.raw) {
val data: MutableMap<String, AtlasElement> = HashMap()
for ((elementName, element) in atlas) {
data[elementName] = element.load(textures)
}
map[atlasName] = Atlas(data)
}
return map
}
fun ResourceLocation.atlas(): ResourceLocation {
return this.extend(prefix = "gui/atlas/", suffix = ".json")
}
}

View File

@ -13,117 +13,26 @@
package de.bixilon.minosoft.gui.rendering.gui.atlas
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.json.JsonUtil.asJsonObject
import de.bixilon.kutil.json.JsonUtil.toJsonObject
import de.bixilon.kutil.primitive.IntUtil.toInt
import de.bixilon.minosoft.assets.util.InputStreamUtil.readJsonObject
import de.bixilon.kutil.cast.CastUtil.unsafeNull
import de.bixilon.kutil.reflection.ReflectionUtil.forceSet
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.toVec2
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.toVec2i
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
class AtlasManager(private val context: RenderContext) {
private lateinit var elements: Map<ResourceLocation, AtlasElement>
var initialized = false
private set
class AtlasManager(val context: RenderContext) {
private val atlas: Map<ResourceLocation, Atlas> = unsafeNull()
private var loader: AtlasLoader? = AtlasLoader(context)
@Synchronized
fun init() {
check(!initialized)
val data = context.connection.assetsManager[ATLAS_DATA].readJsonObject()
val versionId = context.connection.version.versionId
val elements: MutableMap<ResourceLocation, AtlasElement> = mutableMapOf()
for ((resourceLocationString, versions) in data) {
val resourceLocation = resourceLocationString.toResourceLocation()
check(versions is Map<*, *>)
var versionToUse = -1
for (idString in versions.keys) {
val id = idString.toInt()
if (id in (versionToUse + 1)..versionId) {
versionToUse = id
break
}
}
if (versionToUse == -1) {
// can not find version that matches our one
continue
}
val versionData = versions[versionToUse.toString()].asJsonObject()
val texture = context.textures.staticTextures.createTexture(versionData["texture"].toResourceLocation().texture(), mipmaps = false)
val start = versionData["start"].toVec2i()
val end = versionData["end"].toVec2i()
val slots: Int2ObjectOpenHashMap<AtlasSlot> = Int2ObjectOpenHashMap()
versionData["slots"].toJsonObject()?.let {
for ((slotId, slotData) in it) {
val slot = slotData.asJsonObject()
slots[slotId.toInt()] = AtlasSlot(
start = slot["start"].toVec2(),
end = slot["end"].toVec2(),
)
}
}
val areas: MutableMap<String, AtlasArea> = mutableMapOf()
versionData["areas"].toJsonObject()?.let {
for ((areaName, areaPosition) in it) {
val position = areaPosition.asJsonObject()
areas[areaName] = AtlasArea(
start = position["start"].toVec2(),
end = position["end"].toVec2(),
)
}
}
val resolution = versionData["resolution"]?.toVec2i()
val atlasElement = AtlasElement(
texture = texture,
start = start,
resolution = resolution,
end = end,
slots = slots,
areas = areas,
)
elements[resourceLocation] = atlasElement
}
this.elements = elements
this.initialized = true
fun load() {
this::atlas.forceSet(loader!!.load())
this.loader = null
}
fun postInit() {
for (element in elements.values) {
val singePixelSize = element.resolution?.let { Vec2(1.0f) / it / (Vec2(element.texture.array.size) / it) } ?: ATLAS_SINGLE_DEFAULT_PIXEL_SIZE
element.uvStart = singePixelSize * element.start + RenderConstants.UV_ADD
element.uvEnd = singePixelSize * element.end
}
fun load(name: ResourceLocation) {
val loader = this.loader ?: throw IllegalStateException("Can not load anymore! Is init stage done?")
loader.load(name)
}
operator fun get(resourceLocation: ResourceLocation): AtlasElement? {
return elements[resourceLocation]
}
operator fun get(resourceLocation: String): AtlasElement? {
return elements[resourceLocation.toResourceLocation()]
}
companion object {
private val ATLAS_DATA = "minosoft:rendering/atlas.json".toResourceLocation()
private val ATLAS_DEFAULT_SIZE = Vec2i(256, 256)
private val ATLAS_SINGLE_DEFAULT_PIXEL_SIZE = Vec2(1.0f) / ATLAS_DEFAULT_SIZE
operator fun get(atlas: ResourceLocation): Atlas? {
return this.atlas[atlas]
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -13,11 +13,6 @@
package de.bixilon.minosoft.gui.rendering.gui.atlas
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.minosoft.gui.rendering.RenderContext
data class AtlasSlot(
val start: Vec2,
val end: Vec2,
) {
val size = end - start
}
class AtlasTextureManager(private val context: RenderContext)

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.gui.atlas
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.gui.rendering.system.base.texture.TexturePart
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
class CodeTexturePart(

View File

@ -0,0 +1,76 @@
/*
* Minosoft
* Copyright (C) 2020-2023 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.gui.atlas
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.json.JsonObject
import de.bixilon.kutil.primitive.IntUtil.toInt
import de.bixilon.minosoft.assets.AssetsManager
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.toVec2i
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
class RawAtlasElement(
val texture: ResourceLocation,
val resolution: Vec2i = RESOLUTION,
val start: Vec2i = START,
val end: Vec2i = resolution,
val slots: Int2ObjectMap<AtlasArea>?,
val areas: Map<String, AtlasArea>?,
val assets: AssetsManager?,
) {
fun load(textures: AtlasTextureManager): AtlasElement {
TODO()
}
companion object {
val RESOLUTION = Vec2i(256, 256)
val START = Vec2i(0, 0)
private fun Any.toAreas(): Map<String, AtlasArea> {
if (this !is Map<*, *>) throw IllegalArgumentException("Not a JsonObject!")
val areas: MutableMap<String, AtlasArea> = HashMap()
for ((name, data) in this) {
areas[name.toString()] = AtlasArea.deserialize(data.unsafeCast())
}
return areas
}
private fun Any.toSlots(): Int2ObjectMap<AtlasArea> {
if (this !is Map<*, *>) throw IllegalArgumentException("Not a JsonObject!")
val areas = Int2ObjectOpenHashMap<AtlasArea>()
for ((id, data) in this) {
areas[id.toInt()] = AtlasArea.deserialize(data.unsafeCast())
}
return areas
}
fun deserialize(texture: ResourceLocation, assets: AssetsManager?, data: JsonObject): RawAtlasElement {
val resolution = data["resolution"]?.toVec2i() ?: RESOLUTION
val start = data["start"]?.toVec2i() ?: START
val end = data["end"]?.toVec2i() ?: resolution
val slots = data["slots"]?.toSlots()
val areas = data["areas"]?.toAreas()
return RawAtlasElement(texture, resolution, start, end, slots, areas, assets)
}
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -13,6 +13,7 @@
package de.bixilon.minosoft.gui.rendering.gui.elements.input.button
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
open class ButtonElement(
@ -21,11 +22,16 @@ open class ButtonElement(
disabled: Boolean = false,
var onSubmit: () -> Unit,
) : AbstractButtonElement(guiRenderer, text, disabled) {
override val disabledAtlas = guiRenderer.atlasManager["enchanting_table_card_disabled"]
override val normalAtlas = guiRenderer.atlasManager["enchanting_table_card_normal"]
override val hoveredAtlas = guiRenderer.atlasManager["enchanting_table_card_hovered"]
private val atlas = guiRenderer.atlas[ATLAS]
override val disabledAtlas = atlas?.get("disabled")
override val normalAtlas = atlas?.get("normal")
override val hoveredAtlas = atlas?.get("hovered")
override fun submit() {
onSubmit()
}
private companion object {
val ATLAS = minecraft("elements/button")
}
}

View File

@ -16,7 +16,9 @@ package de.bixilon.minosoft.gui.rendering.gui.elements.input.checkbox
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments.Companion.getOffset
@ -39,12 +41,13 @@ open class SwitchElement(
var onChange: (state: Boolean) -> Unit,
) : AbstractCheckboxElement(guiRenderer) {
protected val textElement = TextElement(guiRenderer, text, background = null).apply { this.parent = this@SwitchElement }
private val disabledAtlas = guiRenderer.atlasManager["minosoft:switch_disabled"]
private val normalAtlas = guiRenderer.atlasManager["minosoft:switch_normal"]
private val hoveredAtlas = guiRenderer.atlasManager["minosoft:switch_hovered"]
private val atlas = guiRenderer.atlas[ATLAS]
private val disabledAtlas = atlas["disabled"]
private val normalAtlas = atlas["normal"]
private val hoveredAtlas = atlas["hovered"]
private val onStateAtlas = guiRenderer.atlasManager["minosoft:switch_state_on"]
private val offStateAtlas = guiRenderer.atlasManager["minosoft:switch_state_off"]
private val onStateAtlas = atlas["state_on"]
private val offStateAtlas = atlas["state_off"]
var state: Boolean = state
set(value) {
@ -164,6 +167,7 @@ open class SwitchElement(
}
private companion object {
val ATLAS = minosoft("elements/switch")
val CLICK_SOUND = "minecraft:ui.button.click".toResourceLocation()
const val TEXT_MARGIN = 5
val SIZE = Vec2(30, 20)

View File

@ -17,7 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.minosoft.data.container.Container
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasSlot
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasArea
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.gui.AbstractLayout
import de.bixilon.minosoft.gui.rendering.gui.gui.dragged.elements.item.FloatingItem
@ -26,12 +26,13 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.isGreater
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.isSmaller
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
class ContainerItemsElement(
guiRenderer: GUIRenderer,
val container: Container,
val slots: Int2ObjectOpenHashMap<AtlasSlot>, // ToDo: Use an array?
val slots: Int2ObjectMap<AtlasArea>, // ToDo: Use an array?
) : Element(guiRenderer), AbstractLayout<ItemElement> {
private val itemElements: Int2ObjectOpenHashMap<ItemElementData> = Int2ObjectOpenHashMap()
private var floatingItem: FloatingItem? = null

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -18,11 +18,11 @@ import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.TexturePart
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.system.base.texture.TexturePart
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY

View File

@ -22,6 +22,7 @@ import de.bixilon.minosoft.data.entities.block.sign.SignBlockEntity
import de.bixilon.minosoft.data.entities.block.sign.SignSides
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.blocks.types.pixlyzer.entity.sign.SignBlock
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.sign.SignBlockEntityRenderer
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
@ -33,6 +34,7 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments.Companion.getOffset
import de.bixilon.minosoft.gui.rendering.gui.elements.input.button.ButtonElement
import de.bixilon.minosoft.gui.rendering.gui.elements.input.checkbox.SwitchElement
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ImageElement
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
import de.bixilon.minosoft.gui.rendering.gui.gui.AbstractLayout
@ -42,7 +44,7 @@ import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseActions
import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseButtons
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedModel
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
import de.bixilon.minosoft.modding.event.events.OpenSignEditorEvent
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
@ -57,7 +59,7 @@ class SignEditorScreen(
) : Screen(guiRenderer), AbstractLayout<Element> {
private val headerElement = TextElement(guiRenderer, "Edit sign message", background = null, properties = TextRenderProperties(scale = 3.0f), parent = this)
private val positionElement = TextElement(guiRenderer, "at $blockPosition", background = null, parent = this)
private val backgroundElement = ImageElement(guiRenderer, getTexture(), uvStart = SIGN_UV_START, uvEnd = SIGN_UV_END, size = BACKGROUND_SIZE)
private val backgroundElement = getFront()
private val lines = Array(SignBlockEntity.LINES) { TextInputElement(guiRenderer, blockEntity?.lines?.get(it)?.message ?: "", SIGN_MAX_CHARS, properties = TEXT_PROPERTIES, background = null, cutAtSize = true, parent = this) }
private val doneButton = ButtonElement(guiRenderer, "Done") { guiRenderer.gui.pop() }.apply { size = Vec2(BACKGROUND_SIZE.x, size.y);parent = this@SignEditorScreen }
private val lengthLimitSwitch = SwitchElement(guiRenderer, "Limit length", guiRenderer.connection.profiles.gui.sign.limitLength, parent = this) { guiRenderer.connection.profiles.gui.sign.limitLength = it; forceSilentApply() }
@ -73,12 +75,17 @@ class SignEditorScreen(
forceSilentApply()
}
private fun getTexture(): Texture? {
private fun getFallbackFront(): AtlasImageElement? {
val atlas = guiRenderer.atlas[ATLAS]?.get("front") ?: return null
return AtlasImageElement(guiRenderer, atlas, size = BACKGROUND_SIZE)
}
private fun getFront(): Element? {
if (blockState?.block !is SignBlock) {
return guiRenderer.atlasManager["minecraft:sign_front"]?.texture
return getFallbackFront()
}
// TODO return blockState.model?.nullCast<BakedBlockStateModel>()?.faces?.firstOrNull()?.firstOrNull()?.texture ?: guiRenderer.atlasManager["minecraft:sign_front"]?.texture
return null
val texture = (blockState.model ?: blockState.block.model).nullCast<BakedModel>()?.faces?.firstOrNull()?.firstOrNull()?.texture ?: return getFallbackFront() // TODO: test
return ImageElement(guiRenderer, texture, uvStart = SIGN_UV_START, uvEnd = SIGN_UV_END, size = BACKGROUND_SIZE)
}
override fun forceRender(offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
@ -96,7 +103,7 @@ class SignEditorScreen(
offset.y += positionElement.size.y
offset.y += size.y / 12
backgroundElement.render(offset + HorizontalAlignments.CENTER.getOffset(size, backgroundElement.size), consumer, options)
backgroundElement?.render(offset + HorizontalAlignments.CENTER.getOffset(size, backgroundElement.size), consumer, options)
offset.y += (1.8f * BACKGROUND_SCALE).toInt()
for (line in lines) {
@ -212,6 +219,7 @@ class SignEditorScreen(
}
companion object {
private val ATLAS = minecraft("block/sign")
private val TEXT_PROPERTIES = TextRenderProperties(scale = 2.0f, allowNewLine = false)
private val SIGN_UV_START = Vec2(0.5f / 16.0f, 1.0f / 32.0f)
private val SIGN_UV_END = Vec2(6.5f / 16.0f, 7.0f / 32.0f)

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -16,20 +16,21 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.minosoft.data.container.Container
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasArea
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasSlot
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.isSmaller
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
abstract class BackgroundedContainerScreen<C : Container>(
guiRenderer: GUIRenderer,
container: C,
protected val atlasElement: AtlasElement?,
items: Int2ObjectOpenHashMap<AtlasSlot> = atlasElement?.slots ?: Int2ObjectOpenHashMap(),
items: Int2ObjectMap<AtlasArea> = atlasElement?.slots ?: Int2ObjectOpenHashMap(),
) : ContainerScreen<C>(guiRenderer, container, items) {
protected val containerBackground = AtlasImageElement(guiRenderer, atlasElement)
override val customRenderer: Boolean get() = true

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -19,5 +19,7 @@ import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
interface ContainerGUIFactory<T : ContainerScreen<C>, C : Container> : ClassMappingFactory<C> {
fun build(guiRenderer: GUIRenderer, container: C): T
fun register(gui: GUIRenderer)
fun build(gui: GUIRenderer, container: C): T
}

View File

@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.minosoft.data.container.Container
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasSlot
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasArea
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.items.ContainerItemsElement
import de.bixilon.minosoft.gui.rendering.gui.gui.AbstractLayout
@ -24,12 +24,12 @@ import de.bixilon.minosoft.gui.rendering.gui.gui.screen.Screen
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.isGreater
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
abstract class ContainerScreen<C : Container>(
guiRenderer: GUIRenderer,
val container: C,
items: Int2ObjectOpenHashMap<AtlasSlot>,
items: Int2ObjectMap<AtlasArea>,
) : Screen(guiRenderer), AbstractLayout<Element> {
protected open val containerElement = ContainerItemsElement(guiRenderer, container, items).apply { parent = this@ContainerScreen }
override var activeElement: Element? = null

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -14,18 +14,23 @@
package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container
import de.bixilon.minosoft.data.container.types.CraftingContainer
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import kotlin.reflect.KClass
class CraftingContainerScreen(guiRenderer: GUIRenderer, container: CraftingContainer) : LabeledContainerScreen<CraftingContainer>(guiRenderer, container, guiRenderer.atlasManager["minecraft:crafting_container".toResourceLocation()]) {
class CraftingContainerScreen(guiRenderer: GUIRenderer, container: CraftingContainer) : LabeledContainerScreen<CraftingContainer>(guiRenderer, container, guiRenderer.atlas[ATLAS]?.get("container")) {
companion object : ContainerGUIFactory<CraftingContainerScreen, CraftingContainer> {
private val ATLAS = minecraft("container/crafting")
override val clazz: KClass<CraftingContainer> = CraftingContainer::class
override fun build(guiRenderer: GUIRenderer, container: CraftingContainer): CraftingContainerScreen {
return CraftingContainerScreen(guiRenderer, container)
override fun register(gui: GUIRenderer) {
gui.atlas.load(ATLAS)
}
override fun build(gui: GUIRenderer, container: CraftingContainer): CraftingContainerScreen {
return CraftingContainerScreen(gui, container)
}
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -16,18 +16,19 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.minosoft.data.container.Container
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasArea
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasSlot
import de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.text.ContainerText
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
abstract class LabeledContainerScreen<C : Container>(
guiRenderer: GUIRenderer,
container: C,
atlasElement: AtlasElement?,
items: Int2ObjectOpenHashMap<AtlasSlot> = atlasElement?.slots ?: Int2ObjectOpenHashMap(),
items: Int2ObjectMap<AtlasArea> = atlasElement?.slots ?: Int2ObjectOpenHashMap(),
) : BackgroundedContainerScreen<C>(guiRenderer, container, atlasElement, items) {
protected val titleText = ContainerText.of(guiRenderer, atlasElement?.areas?.get("title"), container.title)
protected val inventoryTitleText = ContainerText.createInventoryTitle(guiRenderer, atlasElement?.areas?.get("inventory_text"))

View File

@ -16,7 +16,10 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.enchanting
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.minosoft.data.container.types.EnchantingContainer
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.ContainerGUIFactory
import de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.LabeledContainerScreen
@ -24,11 +27,10 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.isGreater
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.isSmaller
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import kotlin.reflect.KClass
class EnchantingContainerScreen(guiRenderer: GUIRenderer, container: EnchantingContainer) : LabeledContainerScreen<EnchantingContainer>(guiRenderer, container, guiRenderer.atlasManager["minecraft:enchanting_container".toResourceLocation()]) {
private val cards: Array<EnchantmentButtonElement> = Array(EnchantingContainer.ENCHANTING_OPTIONS) { EnchantmentButtonElement(guiRenderer, this, guiRenderer.atlasManager["minecraft:level_requirement_${it}"], guiRenderer.atlasManager["minecraft:level_requirement_${it}_disabled"], it) }
class EnchantingContainerScreen(guiRenderer: GUIRenderer, container: EnchantingContainer, val atlas: Atlas? = guiRenderer.atlas[ATLAS]) : LabeledContainerScreen<EnchantingContainer>(guiRenderer, container, atlas["container"]) {
private val cards: Array<EnchantmentButtonElement> = Array(EnchantingContainer.ENCHANTING_OPTIONS) { EnchantmentButtonElement(guiRenderer, this, atlas["level_${it + 1}"], atlas["level_${it + 1}_disabled"], it) }
private val cardAreas = Array(EnchantingContainer.ENCHANTING_OPTIONS) { atlasElement?.areas?.get("card_$it") }
@ -73,10 +75,15 @@ class EnchantingContainerScreen(guiRenderer: GUIRenderer, container: EnchantingC
}
companion object : ContainerGUIFactory<EnchantingContainerScreen, EnchantingContainer> {
private val ATLAS = minecraft("container/enchanting")
override val clazz: KClass<EnchantingContainer> = EnchantingContainer::class
override fun build(guiRenderer: GUIRenderer, container: EnchantingContainer): EnchantingContainerScreen {
return EnchantingContainerScreen(guiRenderer, container)
override fun register(gui: GUIRenderer) {
gui.atlas.load(ATLAS)
}
override fun build(gui: GUIRenderer, container: EnchantingContainer): EnchantingContainerScreen {
return EnchantingContainerScreen(gui, container)
}
}
}

View File

@ -21,6 +21,7 @@ import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Companion.getOffset
@ -39,9 +40,9 @@ class EnchantmentButtonElement(
val disabledLevelAtlas: AtlasElement?,
val index: Int,
) : AbstractButtonElement(guiRenderer, "", true) {
override val disabledAtlas = guiRenderer.atlasManager["enchanting_table_card_disabled"]
override val normalAtlas = guiRenderer.atlasManager["enchanting_table_card_normal"]
override val hoveredAtlas = guiRenderer.atlasManager["enchanting_table_card_hovered"]
override val disabledAtlas = container.atlas["card_disabled"]
override val normalAtlas = container.atlas["card_normal"]
override val hoveredAtlas = container.atlas["card_hovered"]
private val levelText = TextElement(guiRenderer, ChatComponent.EMPTY, background = null)
override fun forceRender(offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -16,9 +16,11 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.generic
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.container.types.generic.GenericContainer
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasArea
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasSlot
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.items.ContainerItemsElement
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
@ -39,9 +41,10 @@ open class GenericContainerScreen(
container,
Int2ObjectOpenHashMap(),
) {
private val headerAtlas = guiRenderer.atlasManager["minecraft:generic_container_header"]
private val slotRowAtlas = guiRenderer.atlasManager["minecraft:generic_container_slot_row"]
private val footerAtlas = guiRenderer.atlasManager["minecraft:generic_container_footer"]
private val atlas = guiRenderer.atlas[ATLAS]
private val headerAtlas = atlas["header"]
private val slotRowAtlas = atlas["row"]
private val footerAtlas = atlas["footer"]
private val header = AtlasImageElement(guiRenderer, headerAtlas)
private val slotRow = AtlasImageElement(guiRenderer, slotRowAtlas)
private val footer = AtlasImageElement(guiRenderer, footerAtlas)
@ -83,16 +86,18 @@ open class GenericContainerScreen(
return super.getAt(position - centerOffset)
}
private fun calculateSlots(): Int2ObjectOpenHashMap<AtlasSlot> {
val slots: Int2ObjectOpenHashMap<AtlasSlot> = Int2ObjectOpenHashMap()
private fun calculateSlots(): Int2ObjectOpenHashMap<AtlasArea> {
val slots: Int2ObjectOpenHashMap<AtlasArea> = Int2ObjectOpenHashMap()
var slotOffset = 0
val offset = Vec2i(0, 0)
fun pushElement(atlasElement: AtlasElement) {
for ((slotId, slot) in atlasElement.slots) {
slots[slotId + slotOffset] = AtlasSlot(slot.start + offset, slot.end + offset)
if (atlasElement.slots != null) {
for ((slotId, slot) in atlasElement.slots) {
slots[slotId + slotOffset] = AtlasArea(slot.start + offset, slot.end + offset)
}
slotOffset += atlasElement.slots.size
}
slotOffset += atlasElement.slots.size
offset.y += atlasElement.size.y
}
headerAtlas?.let { pushElement(it) }
@ -107,10 +112,15 @@ open class GenericContainerScreen(
}
companion object : ContainerGUIFactory<GenericContainerScreen, GenericContainer> {
private val ATLAS = minecraft("container/generic")
override val clazz: KClass<GenericContainer> = GenericContainer::class
override fun build(guiRenderer: GUIRenderer, container: GenericContainer): GenericContainerScreen {
return GenericContainerScreen(guiRenderer, container)
override fun register(gui: GUIRenderer) {
gui.atlas.load(ATLAS)
}
override fun build(gui: GUIRenderer, container: GenericContainer): GenericContainerScreen {
return GenericContainerScreen(gui, container)
}
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -14,9 +14,10 @@
package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.inventory
import de.bixilon.minosoft.data.container.types.PlayerInventory
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.BackgroundedContainerScreen
import de.bixilon.minosoft.util.KUtil.toResourceLocation
open class InventoryScreen(
guiRenderer: GUIRenderer,
@ -24,5 +25,10 @@ open class InventoryScreen(
) : BackgroundedContainerScreen<PlayerInventory>(
guiRenderer,
container,
guiRenderer.atlasManager["minecraft:inventory_base".toResourceLocation()],
)
guiRenderer.atlas[ATLAS]["container"],
) {
companion object {
val ATLAS = minecraft("container/inventory")
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.processing.smelting
import de.bixilon.minosoft.data.container.types.processing.smelting.BlastFurnaceContainer
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.ContainerGUIFactory
import kotlin.reflect.KClass
@ -21,14 +22,19 @@ import kotlin.reflect.KClass
class BlastFurnaceContainerScreen(
guiRenderer: GUIRenderer,
container: BlastFurnaceContainer,
) : SmeltingContainerScreen<BlastFurnaceContainer>(guiRenderer, container, guiRenderer.atlasManager["minecraft:blast_furnace_container"], guiRenderer.atlasManager["minecraft:blast_furnace_container_fuel"], guiRenderer.atlasManager["minecraft:blast_furnace_container_process"]) {
) : SmeltingContainerScreen<BlastFurnaceContainer>(guiRenderer, container, guiRenderer.atlas[ATLAS]) {
companion object : ContainerGUIFactory<BlastFurnaceContainerScreen, BlastFurnaceContainer> {
private val ATLAS = minecraft("container/furnace/blast")
override val clazz: KClass<BlastFurnaceContainer> = BlastFurnaceContainer::class
override fun build(guiRenderer: GUIRenderer, container: BlastFurnaceContainer): BlastFurnaceContainerScreen {
return BlastFurnaceContainerScreen(guiRenderer, container)
override fun register(gui: GUIRenderer) {
gui.atlas.load(ATLAS)
}
override fun build(gui: GUIRenderer, container: BlastFurnaceContainer): BlastFurnaceContainerScreen {
return BlastFurnaceContainerScreen(gui, container)
}
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.processing.smelting
import de.bixilon.minosoft.data.container.types.processing.smelting.FurnaceContainer
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.ContainerGUIFactory
import kotlin.reflect.KClass
@ -21,14 +22,19 @@ import kotlin.reflect.KClass
class FurnaceContainerScreen(
guiRenderer: GUIRenderer,
container: FurnaceContainer,
) : SmeltingContainerScreen<FurnaceContainer>(guiRenderer, container, guiRenderer.atlasManager["minecraft:furnace_container"], guiRenderer.atlasManager["minecraft:furnace_container_fuel"], guiRenderer.atlasManager["minecraft:furnace_container_process"]) {
) : SmeltingContainerScreen<FurnaceContainer>(guiRenderer, container, guiRenderer.atlas[ATLAS]) {
companion object : ContainerGUIFactory<FurnaceContainerScreen, FurnaceContainer> {
private val ATLAS = minecraft("container/furnace/furnace")
override val clazz: KClass<FurnaceContainer> = FurnaceContainer::class
override fun build(guiRenderer: GUIRenderer, container: FurnaceContainer): FurnaceContainerScreen {
return FurnaceContainerScreen(guiRenderer, container)
override fun register(gui: GUIRenderer) {
gui.atlas.load(ATLAS)
}
override fun build(gui: GUIRenderer, container: FurnaceContainer): FurnaceContainerScreen {
return FurnaceContainerScreen(gui, container)
}
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -18,6 +18,7 @@ import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.math.interpolation.FloatInterpolation.interpolateLinear
import de.bixilon.minosoft.data.container.types.processing.smelting.SmeltingContainer
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
@ -28,12 +29,12 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
abstract class SmeltingContainerScreen<C : SmeltingContainer>(
guiRenderer: GUIRenderer,
container: C,
atlasElement: AtlasElement?,
protected val fuelAtlasElement: AtlasElement?,
protected val processAtlasElement: AtlasElement?,
) : ProcessingContainerScreen<C>(guiRenderer, container, atlasElement), Pollable {
atlas: Atlas?,
) : ProcessingContainerScreen<C>(guiRenderer, container, atlas?.get("container")), Pollable {
protected val fuelAtlasElement: AtlasElement? = atlas?.get("fuel")
protected val processAtlasElement: AtlasElement? = atlas?.get("process")
private val fuelArea = atlasElement?.areas?.get("fuel")
private val processArea = atlasElement?.areas?.get("process")
private val processArea = atlasElement?.areas?.get("progress")
private var fuel = 0.0f
private var process = 0.0f

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.processing.smelting
import de.bixilon.minosoft.data.container.types.processing.smelting.SmokerContainer
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.gui.screen.container.ContainerGUIFactory
import kotlin.reflect.KClass
@ -21,14 +22,19 @@ import kotlin.reflect.KClass
class SmokerContainerScreen(
guiRenderer: GUIRenderer,
container: SmokerContainer,
) : SmeltingContainerScreen<SmokerContainer>(guiRenderer, container, guiRenderer.atlasManager["minecraft:blast_furnace_container"], guiRenderer.atlasManager["minecraft:blast_furnace_container_fuel"], guiRenderer.atlasManager["minecraft:blast_furnace_container_process"]) {
) : SmeltingContainerScreen<SmokerContainer>(guiRenderer, container, guiRenderer.atlas[ATLAS]) {
companion object : ContainerGUIFactory<SmokerContainerScreen, SmokerContainer> {
private val ATLAS = minecraft("container/furnace/smoker")
override val clazz: KClass<SmokerContainer> = SmokerContainer::class
override fun build(guiRenderer: GUIRenderer, container: SmokerContainer): SmokerContainerScreen {
return SmokerContainerScreen(guiRenderer, container)
override fun register(gui: GUIRenderer) {
gui.atlas.load(ATLAS)
}
override fun build(gui: GUIRenderer, container: SmokerContainer): SmokerContainerScreen {
return SmokerContainerScreen(gui, container)
}
}
}

View File

@ -27,5 +27,6 @@ interface HUDBuilder<T : HUDElement> : Identified {
val DEFAULT_ENABLED: Boolean
get() = true
fun register(gui: GUIRenderer) = Unit
fun build(guiRenderer: GUIRenderer): T
}

View File

@ -0,0 +1,39 @@
/*
* Minosoft
* Copyright (C) 2020-2023 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.gui.hud.elements.bossbar
import de.bixilon.minosoft.data.bossbar.BossbarColors
import de.bixilon.minosoft.data.bossbar.BossbarNotches
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
class BossbarAtlas(atlas: Atlas) {
val colors = Array(BossbarColors.VALUES.size) {
arrayOf(
atlas[BossbarColors[it].name.lowercase() + "_empty"],
atlas[BossbarColors[it].name.lowercase() + "_full"]
)
}
operator fun get(color: BossbarColors): Array<AtlasElement?> = colors[color.ordinal]
val notches = Array(BossbarNotches.NOTCHES.size) {
arrayOf(
atlas[BossbarNotches.NOTCHES[it].name.lowercase() + "_empty"],
atlas[BossbarNotches.NOTCHES[it].name.lowercase() + "_full"]
)
}
operator fun get(notches: BossbarNotches): Array<AtlasElement?> = this.notches[notches.ordinal - 1]
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -15,12 +15,11 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.bossbar
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.array.ArrayUtil.cast
import de.bixilon.minosoft.data.bossbar.Bossbar
import de.bixilon.minosoft.data.bossbar.BossbarColors
import de.bixilon.minosoft.data.bossbar.BossbarNotches
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Companion.getOffset
@ -32,7 +31,7 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
class BossbarElement(
guiRenderer: GUIRenderer,
val bossbar: Bossbar,
val atlas: Array<Array<Array<AtlasElement?>>>,
val atlas: BossbarAtlas?,
) : Element(guiRenderer), Pollable {
private var color: BossbarColors = bossbar.color
private var notches: BossbarNotches = bossbar.notches
@ -89,12 +88,8 @@ class BossbarElement(
private fun setStyle() {
// ToDo: Cache progress
val notches = if (notches == BossbarNotches.NO_NOTCHES) {
null
} else {
atlas[1][notches.ordinal - 1]
}
progress = BossbarProgressElement(guiRenderer, atlas[0][color.ordinal].unsafeCast(), notches.unsafeCast(), 0.0f)
val notches = if (notches == BossbarNotches.NO_NOTCHES) null else atlas?.get(notches)
progress = BossbarProgressElement(guiRenderer, atlas?.get(color)!!.cast(), notches?.cast(), 0.0f)
}
override fun forceSilentApply() {

View File

@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.bossbar
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
import de.bixilon.minosoft.data.bossbar.Bossbar
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
@ -35,61 +36,8 @@ class BossbarLayout(guiRenderer: GUIRenderer) : RowLayout(guiRenderer, Horizonta
override val layoutOffset: Vec2
get() = Vec2((guiRenderer.scaledSize.x - super.size.x) / 2, 2)
val atlasManager = guiRenderer.atlasManager
/**
* [bar|notches][color.ordinal|notches.ordinal-1][empty|full]
*/
private val atlas = arrayOf(
arrayOf(
arrayOf(
atlasManager["minecraft:bossbar_pink_empty"],
atlasManager["minecraft:bossbar_pink_full"],
),
arrayOf(
atlasManager["minecraft:bossbar_blue_empty"],
atlasManager["minecraft:bossbar_blue_full"],
),
arrayOf(
atlasManager["minecraft:bossbar_red_empty"],
atlasManager["minecraft:bossbar_red_full"],
),
arrayOf(
atlasManager["minecraft:bossbar_green_empty"],
atlasManager["minecraft:bossbar_green_full"],
),
arrayOf(
atlasManager["minecraft:bossbar_yellow_empty"],
atlasManager["minecraft:bossbar_yellow_full"],
),
arrayOf(
atlasManager["minecraft:bossbar_purple_empty"],
atlasManager["minecraft:bossbar_purple_full"],
),
arrayOf(
atlasManager["minecraft:bossbar_white_empty"],
atlasManager["minecraft:bossbar_white_full"],
),
),
arrayOf(
arrayOf(
atlasManager["minecraft:bossbar_notches_6_empty"],
atlasManager["minecraft:bossbar_notches_6_full"],
),
arrayOf(
atlasManager["minecraft:bossbar_notches_10_empty"],
atlasManager["minecraft:bossbar_notches_10_full"],
),
arrayOf(
atlasManager["minecraft:bossbar_notches_12_empty"],
atlasManager["minecraft:bossbar_notches_12_empty"],
),
arrayOf(
atlasManager["minecraft:bossbar_notches_20_empty"],
atlasManager["minecraft:bossbar_notches_20_full"],
),
),
)
val atlas = guiRenderer.atlas[ATLAS]?.let { BossbarAtlas(it) }
override fun postInit() {
connection.events.listen<BossbarAddEvent> {
@ -117,8 +65,13 @@ class BossbarLayout(guiRenderer: GUIRenderer) : RowLayout(guiRenderer, Horizonta
companion object : HUDBuilder<LayoutedGUIElement<BossbarLayout>> {
private val ATLAS = minecraft("hud/bossbar")
override val identifier: ResourceLocation = "minosoft:bossbar".toResourceLocation()
override fun register(gui: GUIRenderer) {
gui.atlas.load(ATLAS)
}
override fun build(guiRenderer: GUIRenderer): LayoutedGUIElement<BossbarLayout> {
return LayoutedGUIElement(BossbarLayout(guiRenderer))
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -55,7 +55,7 @@ abstract class AbstractHotbarHealthElement(guiRenderer: GUIRenderer) : Element(g
cacheUpToDate = false
}
protected fun drawCanisters(offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, atlasElement: AtlasElement) {
protected fun drawCanisters(offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, atlasElement: AtlasElement?) {
for (heart in 0 until totalMaxHearts) {
val row = heart / HEARTS_PER_ROW
val column = heart % HEARTS_PER_ROW

View File

@ -17,7 +17,9 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.math.simple.FloatMath.ceil
import de.bixilon.minosoft.data.registries.fluid.fluids.WaterFluid
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
@ -26,8 +28,9 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
class HotbarAirElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Pollable {
private val airBubble = guiRenderer.atlasManager["minecraft:air_bubble"]
private val poppingAirBubble = guiRenderer.atlasManager["minecraft:popping_air_bubble"]
private val atlas = guiRenderer.atlas[ATLAS]
private val airBubble = atlas["bubble"]
private val poppingAirBubble = atlas["popping"]
init {
forceSilentApply()
@ -102,6 +105,7 @@ class HotbarAirElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Pollabl
}
companion object {
private val ATLAS = minecraft("hud/hotbar/air")
private val BUBBLE_SIZE = Vec2i(8, 9)
private const val FULL_AIR = 300
private const val MAX_BUBBLES = 10

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -16,21 +16,24 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.container.types.PlayerInventory
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
import de.bixilon.minosoft.gui.rendering.gui.elements.items.ContainerItemsElement
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
class HotbarBaseElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Pollable {
private val baseAtlasElement = guiRenderer.atlasManager[BASE]!!
private val atlas = guiRenderer.atlas[ATLAS]
private val baseAtlasElement = atlas["base"]
private val base = AtlasImageElement(guiRenderer, baseAtlasElement)
private val frame = AtlasImageElement(guiRenderer, guiRenderer.atlasManager[FRAME]!!, size = Vec2i(FRAME_SIZE))
private val frame = AtlasImageElement(guiRenderer, atlas["frame"]!!, size = Vec2i(FRAME_SIZE))
private val containerElement = ContainerItemsElement(guiRenderer, guiRenderer.context.connection.player.items.inventory, baseAtlasElement.slots)
private val containerElement = ContainerItemsElement(guiRenderer, guiRenderer.context.connection.player.items.inventory, baseAtlasElement?.slots ?: Int2ObjectOpenHashMap())
private var selectedSlot = 0
@ -46,7 +49,7 @@ class HotbarBaseElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Pollab
override fun forceRender(offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
base.render(offset + HORIZONTAL_MARGIN, consumer, options)
baseAtlasElement.slots[selectedSlot + PlayerInventory.HOTBAR_OFFSET]?.let {
baseAtlasElement?.slots?.get(selectedSlot + PlayerInventory.HOTBAR_OFFSET)?.let {
frame.render(offset + it.start - HORIZONTAL_MARGIN + FRAME_OFFSET, consumer, options)
}
@ -70,8 +73,7 @@ class HotbarBaseElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Pollab
}
companion object {
private val BASE = "minecraft:hotbar_base".toResourceLocation()
private val FRAME = "minecraft:hotbar_frame".toResourceLocation()
val ATLAS = minecraft("gui/hotbar/hotbar")
private val HOTBAR_BASE_SIZE = Vec2(182, 22)
private const val FRAME_SIZE = 24

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -23,6 +23,8 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Compa
import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments.Companion.getOffset
import de.bixilon.minosoft.gui.rendering.gui.elements.layout.RowLayout
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar.health.HotbarHealthElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar.health.HotbarVehicleHealthElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -15,10 +15,12 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Companion.getOffset
@ -29,18 +31,19 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
class HotbarExperienceBarElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Pollable {
private val atlas = guiRenderer.atlas[ATLAS]
/**
* [experience|horse_jump][full|empty]
*/
private val atlasElements = arrayOf(
arrayOf(
guiRenderer.atlasManager["minecraft:empty_experience_bar"],
guiRenderer.atlasManager["minecraft:full_experience_bar"],
atlas["empty"],
atlas["full"],
),
arrayOf(
guiRenderer.atlasManager["minecraft:empty_horse_jump_bar"],
guiRenderer.atlasManager["minecraft:full_horse_jump_bar"],
atlas["horse_empty"],
atlas["horse_full"],
),
)
@ -88,6 +91,7 @@ class HotbarExperienceBarElement(guiRenderer: GUIRenderer) : Element(guiRenderer
}
companion object {
private val ATLAS = minecraft("hud/hotbar/experience")
private val TEXT_PROPERTIES = TextRenderProperties(HorizontalAlignments.CENTER, shadow = false)
private val SIZE = Vec2(182, 5)
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -17,7 +17,10 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.minosoft.data.registries.effects.other.OtherEffect
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
@ -31,33 +34,8 @@ class HotbarHungerElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Poll
private val profile = guiRenderer.connection.profiles.gui
private val hungerProfile = profile.hud.hotbar.hunger
private var ticks = 0
private val atlasManager = guiRenderer.atlasManager
private val normalHungerContainer = atlasManager["minecraft:normal_hunger_container"]!!
private val hungerHungerContainer = atlasManager["minecraft:hunger_hunger_container"]!!
/**
* [full|half]
*/
private val saturationHungerContainer = arrayOf(
atlasManager["minosoft:saturation_hunger_container"]!!,
atlasManager["minosoft:half_saturation_hunger_container"]!!,
)
/**
* [normal|hunger][full|half]
*/
private val hungerElements = arrayOf(
arrayOf(
atlasManager["minecraft:normal_hunger"]!!,
atlasManager["minecraft:half_normal_hunger"]!!,
),
arrayOf(
atlasManager["minecraft:hunger_hunger"]!!,
atlasManager["minecraft:half_hunger_hunger"]!!,
)
)
private val atlas = HungerAtlas(guiRenderer.atlas[ATLAS])
private var hungerEffect = false
private var animate = true
@ -90,39 +68,34 @@ class HotbarHungerElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Poll
if (hungerProfile.saturationBar) {
val container = when {
hungerEffect -> hungerHungerContainer
hungerEffect -> atlas.hungerContainer
saturationLeft == 1 -> {
saturationLeft -= 1
saturationHungerContainer[1]
atlas.getSaturationContainer(true)
}
saturationLeft > 1 -> {
saturationLeft -= 2
saturationHungerContainer[0]
atlas.getSaturationContainer(false)
}
else -> normalHungerContainer
else -> atlas.container
}
AtlasImageElement(guiRenderer, container).render(hungerOffset, consumer, options)
}
val selectArray: Array<*> = if (hungerEffect) {
hungerElements[1]
} else {
hungerElements[0]
}
if (hungerLeft <= 0) {
continue
}
val hungerElement: AtlasElement
val hungerElement: AtlasElement?
if (hungerLeft == 1) {
hungerLeft--
hungerElement = selectArray[1] as AtlasElement
hungerElement = atlas.getHunger(true, hungerEffect)
} else {
hungerLeft -= 2
hungerElement = selectArray[0] as AtlasElement
hungerElement = atlas.getHunger(false, hungerEffect)
}
AtlasImageElement(guiRenderer, hungerElement).render(hungerOffset, consumer, options)
@ -160,7 +133,16 @@ class HotbarHungerElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Poll
return true
}
private class HungerAtlas(val atlas: Atlas?) {
val container = atlas["container"]
val hungerContainer = atlas["container_hunger"]
fun getHunger(half: Boolean, hunger: Boolean): AtlasElement = TODO()
fun getSaturationContainer(half: Boolean): AtlasElement = TODO()
}
companion object {
private val ATLAS = minosoft("hud/hotbar/hunger")
const val MAX_HUNGER = 20
private const val HUNGER_CONTAINERS = MAX_HUNGER / 2
private val HUNGER_SIZE = Vec2i(8, 9)

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -17,24 +17,27 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.minosoft.data.entities.entities.player.Arms
import de.bixilon.minosoft.data.entities.entities.player.Arms.Companion.opposite
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.items.ContainerItemsElement
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4Util.marginOf
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
class HotbarOffhandElement(guiRenderer: GUIRenderer) : Element(guiRenderer) {
private val atlas = guiRenderer.atlas[HotbarBaseElement.ATLAS]
private val frames = arrayOf(
guiRenderer.atlasManager["minecraft:offhand_right_arm_frame"],
guiRenderer.atlasManager["minecraft:offhand_left_arm_frame"],
atlas["offhand_right"],
atlas["offhand_left"],
)
val offArm = guiRenderer.context.connection.player.mainArm.opposite // ToDo: Support arm change
private val frame = frames[offArm.ordinal]!!
private var frameImage = AtlasImageElement(guiRenderer, frame)
private val containerElement = ContainerItemsElement(guiRenderer, guiRenderer.context.connection.player.items.inventory, frame.slots)
private val containerElement = ContainerItemsElement(guiRenderer, guiRenderer.context.connection.player.items.inventory, frame.slots ?: Int2ObjectOpenHashMap())
init {
_size = Vec2(frame.size)

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -15,8 +15,11 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.item.items.armor.DefendingArmorItem.Companion.getProtection
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
@ -25,9 +28,7 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
class HotbarProtectionElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Pollable {
private val emptyProtection = guiRenderer.atlasManager["minecraft:empty_protection"]
private val halfProtection = guiRenderer.atlasManager["minecraft:half_protection"]
private val fullProtection = guiRenderer.atlasManager["minecraft:full_protection"]
private val atlas = ProtectionAtlas(guiRenderer.atlas[ATLAS])
init {
forceSilentApply()
@ -44,9 +45,9 @@ class HotbarProtectionElement(guiRenderer: GUIRenderer) : Element(guiRenderer),
for (i in 0 until 10) {
val atlasElement = when {
protectionLeft < 1.0f -> emptyProtection
protectionLeft < 2.0f -> halfProtection
else -> fullProtection
protectionLeft < 1.0f -> atlas.empty
protectionLeft < 2.0f -> atlas.half
else -> atlas.full
}
val image = AtlasImageElement(guiRenderer, atlasElement)
@ -83,7 +84,15 @@ class HotbarProtectionElement(guiRenderer: GUIRenderer) : Element(guiRenderer),
apply()
}
private class ProtectionAtlas(atlas: Atlas?) {
val empty = atlas["empty"]
val half = atlas["half"]
val full = atlas["full"]
}
companion object {
private val ATLAS = minecraft("hud/hotbar/protection")
private val ARMOR_SIZE = Vec2i(8, 9)
private val SIZE = Vec2(10 * ARMOR_SIZE.x, ARMOR_SIZE.y)
}

View File

@ -0,0 +1,36 @@
/*
* Minosoft
* Copyright (C) 2020-2023 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.gui.hud.elements.hotbar.health
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
class HeartAtlas(val atlas: Atlas?) {
val normal = HartType()
val poisoned = HartType()
val withered = HartType()
val absorption = HartType()
val frozen = HartType()
class HartType {
fun get(full: Boolean, hardcore: Boolean, blinking: Boolean): AtlasElement = TODO()
}
companion object {
val ATLAS = minecraft("hud/hotbar/hearts")
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -11,11 +11,10 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar.health
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.math.simple.FloatMath.rounded10
import de.bixilon.kutil.primitive.BooleanUtil.decide
import de.bixilon.minosoft.data.registries.effects.attributes.MinecraftAttributes
@ -25,115 +24,19 @@ import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.RGBColor.Companion.asColor
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar.AbstractHotbarHealthElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import java.lang.Float.max
import java.lang.Float.min
class HotbarHealthElement(guiRenderer: GUIRenderer) : AbstractHotbarHealthElement(guiRenderer), Pollable {
private val atlasManager = guiRenderer.atlasManager
/**
* [normal|hardcore] [normal|poison|wither] [normal|damage] [full|half]
*/
private val hearts = arrayOf(
arrayOf(
arrayOf(
arrayOf(
atlasManager["minecraft:normal_heart"],
atlasManager["minecraft:half_normal_heart"],
),
arrayOf(
atlasManager["minecraft:normal_damage_heart"],
atlasManager["minecraft:half_normal_damage_heart"],
),
),
arrayOf(
arrayOf(
atlasManager["minecraft:poison_heart"],
atlasManager["minecraft:half_poison_heart"],
),
arrayOf(
atlasManager["minecraft:poison_damage_heart"],
atlasManager["minecraft:half_poison_damage_heart"],
),
),
arrayOf(
arrayOf(
atlasManager["minecraft:wither_heart"],
atlasManager["minecraft:half_wither_heart"],
),
arrayOf(
atlasManager["minecraft:wither_damage_heart"],
atlasManager["minecraft:half_wither_damage_heart"],
),
),
),
arrayOf(
arrayOf(
arrayOf(
atlasManager["minecraft:hardcore_normal_heart"],
atlasManager["minecraft:hardcore_half_normal_heart"],
),
arrayOf(
atlasManager["minecraft:hardcore_normal_damage_heart"],
atlasManager["minecraft:hardcore_half_normal_damage_heart"],
),
),
arrayOf(
arrayOf(
atlasManager["minecraft:hardcore_poison_heart"],
atlasManager["minecraft:hardcore_half_poison_heart"],
),
arrayOf(
atlasManager["minecraft:hardcore_poison_damage_heart"],
atlasManager["minecraft:hardcore_half_poison_damage_heart"],
),
),
arrayOf(
arrayOf(
atlasManager["minecraft:hardcore_wither_heart"],
atlasManager["minecraft:hardcore_half_wither_heart"],
),
arrayOf(
atlasManager["minecraft:hardcore_wither_damage_heart"],
atlasManager["minecraft:hardcore_half_wither_damage_heart"],
),
),
),
)
/**
* [normal|hardcore][full|half]
*/
private val absorptionHearts = arrayOf(
arrayOf(
atlasManager["minecraft:absorption_heart"],
atlasManager["minecraft:half_absorption_heart"],
),
arrayOf(
atlasManager["minecraft:hardcore_absorption_heart"],
atlasManager["minecraft:hardcore_half_absorption_heart"],
),
)
/**
* [normal|hardcore][full|half]
*/
private val frozenHearts = arrayOf(
arrayOf(
atlasManager["minecraft:frozen_heart"],
atlasManager["minecraft:half_frozen_heart"],
),
arrayOf(
atlasManager["minecraft:hardcore_frozen_heart"],
atlasManager["minecraft:hardcore_half_frozen_heart"],
),
)
private val blackHeartContainer = atlasManager["minecraft:black_heart_container"]!!
private val atlas = HeartAtlas(guiRenderer.atlas[HeartAtlas.ATLAS])
private val blackHeartContainer = atlas.atlas["container"] // TODO: There are multiple containers
private var hardcode = false
private var poison = false
@ -154,7 +57,6 @@ class HotbarHealthElement(guiRenderer: GUIRenderer) : AbstractHotbarHealthElemen
// ToDo: Damage animation, regeneration, caching, stacking
drawCanisters(offset, consumer, options, blackHeartContainer)
val hardcoreIndex = hardcode.decide(1, 0)
var healthLeft = totalHealth
var heart = 0
@ -164,41 +66,19 @@ class HotbarHealthElement(guiRenderer: GUIRenderer) : AbstractHotbarHealthElemen
val column = heart % HEARTS_PER_ROW
var selectArray: Array<*>?
var normalHeart = false
if (healthLeft <= absorptionsAmount) {
selectArray = absorptionHearts[hardcoreIndex]
} else {
selectArray = hearts[hardcoreIndex]
// heart type
selectArray = selectArray[when {
poison -> 1
wither -> 2
else -> {
normalHeart = true
0
}
}]
// ToDo: damage heart
selectArray = selectArray[0]
}
if (frozen && normalHeart) {
selectArray = frozenHearts[hardcoreIndex]
val heartType = when {
healthLeft <= absorptionsAmount -> atlas.absorption
poison -> atlas.poisoned
wither -> atlas.withered
frozen -> atlas.frozen
else -> atlas.normal
}
val halfHeart = healthLeft < 1.5f
val image = selectArray.unsafeCast<Array<AtlasElement?>>()[when {
halfHeart -> 1
else -> 0
}]?.let { AtlasImageElement(guiRenderer, it) }
val image = heartType.get(!halfHeart, hardcode, false)
image?.render(offset + Vec2i(column, (rows - 1) - row) * HEART_SIZE, consumer, options)
AtlasImageElement(guiRenderer, image).render(offset + Vec2i(column, (rows - 1) - row) * HEART_SIZE, consumer, options)
heart++
healthLeft -= halfHeart.decide(1.0f, 2.0f)

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar.health
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kutil.math.simple.FloatMath.rounded10
@ -24,21 +24,15 @@ import de.bixilon.minosoft.data.text.formatting.color.RGBColor.Companion.asColor
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar.AbstractHotbarHealthElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import java.lang.Float.max
class HotbarVehicleHealthElement(guiRenderer: GUIRenderer) : AbstractHotbarHealthElement(guiRenderer), Pollable {
private val atlasManager = guiRenderer.atlasManager
private val atlasManager = guiRenderer.atlas
/**
* [full|half]
*/
private val hearts = arrayOf(
atlasManager["minecraft:vehicle_heart"],
atlasManager["minecraft:vehicle_half_heart"],
)
private val vehicleHeartContainer = atlasManager["minecraft:vehicle_heart_container"]!!
private val atlas = VehicleHeartAtlas(guiRenderer.atlas[HeartAtlas.ATLAS])
private var shown = false
override var totalHealth = 0.0f
@ -51,7 +45,7 @@ class HotbarVehicleHealthElement(guiRenderer: GUIRenderer) : AbstractHotbarHealt
if (text) {
return super.forceRender(offset, consumer, options)
}
drawCanisters(offset, consumer, options, vehicleHeartContainer)
drawCanisters(offset, consumer, options, atlas.getContainer(false))
var healthLeft = totalHealth
var heart = 0
@ -62,10 +56,7 @@ class HotbarVehicleHealthElement(guiRenderer: GUIRenderer) : AbstractHotbarHealt
val halfHeart = healthLeft < 1.5f
val image = hearts[when {
halfHeart -> 1
else -> 0
}]?.let { AtlasImageElement(guiRenderer, it) }
val image = atlas.getHeart(halfHeart)?.let { AtlasImageElement(guiRenderer, it) }
image?.render(offset + Vec2(column, (rows - 1) - row) * HEART_SIZE, consumer, options)

View File

@ -0,0 +1,24 @@
/*
* Minosoft
* Copyright (C) 2020-2023 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.gui.hud.elements.hotbar.health
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
class VehicleHeartAtlas(val atlas: Atlas?) {
fun getContainer(half: Boolean): AtlasElement = TODO()
fun getHeart(half: Boolean): AtlasElement = TODO()
}

View File

@ -18,7 +18,8 @@ import de.bixilon.minosoft.camera.target.targets.BlockTarget
import de.bixilon.minosoft.camera.target.targets.EntityTarget
import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.registries.blocks.types.pixlyzer.entity.BlockWithEntity
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.gui.LayoutedGUIElement
@ -27,7 +28,6 @@ import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.other.debug.DebugHUDElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.collections.floats.BufferedArrayFloatList
class CrosshairHUDElement(guiRenderer: GUIRenderer) : CustomHUDElement(guiRenderer) {
@ -40,7 +40,7 @@ class CrosshairHUDElement(guiRenderer: GUIRenderer) : CustomHUDElement(guiRender
private var previousNeedsDraw = needsDraw
override fun init() {
crosshairAtlasElement = guiRenderer.atlasManager[ATLAS_NAME]
crosshairAtlasElement = guiRenderer.atlas[ATLAS]?.get("crosshair")
crosshairProfile::color.observe(this) { reapply = true }
}
@ -105,10 +105,10 @@ class CrosshairHUDElement(guiRenderer: GUIRenderer) : CustomHUDElement(guiRender
companion object : HUDBuilder<CrosshairHUDElement> {
private val ATLAS = minecraft("hud/hud")
const val CROSSHAIR_SIZE = 16
override val identifier: ResourceLocation = "minosoft:crosshair".toResourceLocation()
override val identifier = minosoft("crosshair")
private val ATLAS_NAME = "minecraft:crosshair".toResourceLocation()
override fun build(guiRenderer: GUIRenderer): CrosshairHUDElement {
return CrosshairHUDElement(guiRenderer)

View File

@ -0,0 +1,43 @@
/*
* Minosoft
* Copyright (C) 2020-2023 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.gui.hud.elements.tab
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas
import de.bixilon.minosoft.gui.rendering.gui.atlas.Atlas.Companion.get
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
class TabListAtlas(val atlas: Atlas?) {
private val ping = Array(6) { atlas["ping_$it"] }
constructor(gui: GUIRenderer) : this(gui.atlas[ATLAS])
fun getPing(ping: Int): AtlasElement? {
return this.ping[when {
ping < 0 -> 0
ping < 150 -> 5
ping < 300 -> 4
ping < 600 -> 3
ping < 1000 -> 2
else -> 1
}]
}
private companion object {
val ATLAS = minecraft("hud/tab")
}
}

View File

@ -26,7 +26,6 @@ import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Companion.getOffset
@ -63,15 +62,7 @@ class TabListElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedE
override val layoutOffset: Vec2
get() = Vec2((guiRenderer.scaledSize.x - super.size.x) / 2, 20)
private val atlasManager = guiRenderer.atlasManager
val pingBarsAtlasElements: Array<AtlasElement> = arrayOf(
atlasManager["minecraft:tab_list_ping_0"]!!,
atlasManager["minecraft:tab_list_ping_1"]!!,
atlasManager["minecraft:tab_list_ping_2"]!!,
atlasManager["minecraft:tab_list_ping_3"]!!,
atlasManager["minecraft:tab_list_ping_4"]!!,
atlasManager["minecraft:tab_list_ping_5"]!!,
)
val atlas = TabListAtlas(guiRenderer)
init {
super.prefMaxSize = Vec2(-1, -1)

View File

@ -92,16 +92,7 @@ class TabListEntryElement(
override fun forceSilentApply() {
// ToDo (Performance): If something changed, should we just prepare the changed
pingElement = AtlasImageElement(
guiRenderer, tabList.pingBarsAtlasElements[when {
ping < 0 -> 0
ping < 150 -> 5
ping < 300 -> 4
ping < 600 -> 3
ping < 1000 -> 2
else -> 1
}]
)
pingElement = AtlasImageElement(guiRenderer, tabList.atlas.getPing(ping))
nameElement.prefMaxSize = Vec2(maxOf(0.0f, maxSize.x - pingElement.size.x - skinElement.size.x - INNER_MARGIN), HEIGHT)
nameElement.text = displayName

View File

@ -18,7 +18,7 @@ import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties
import de.bixilon.minosoft.gui.rendering.gui.atlas.TexturePart
import de.bixilon.minosoft.gui.rendering.system.base.texture.TexturePart
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderIdentifiable
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.models.loader
import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.identified.ResourceLocationUtil.extend
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.chunk.entities.EntityModels
import de.bixilon.minosoft.util.logging.Log
@ -56,11 +57,11 @@ class ModelLoader(
companion object {
fun ResourceLocation.model(): ResourceLocation {
return ResourceLocation(this.namespace, "models/$path.json")
return this.extend(prefix = "models/", suffix = ".json")
}
fun ResourceLocation.bbModel(): ResourceLocation {
return ResourceLocation(this.namespace, "models/$path.bbmodel")
return this.extend(prefix = "models/", suffix = ".bbmodel")
}
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 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.
*
@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.atlas
package de.bixilon.minosoft.gui.rendering.system.base.texture
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i

View File

@ -15,13 +15,11 @@ package de.bixilon.minosoft.gui.rendering.textures
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.identified.ResourceLocationUtil.extend
import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMesh
import de.bixilon.minosoft.gui.rendering.chunk.mesh.SingleChunkMesh
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
import de.bixilon.minosoft.gui.rendering.system.base.texture.array.StaticTextureArray
import de.bixilon.minosoft.gui.rendering.system.base.texture.data.TextureData
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.matthiasmann.twl.utils.PNGDecoder
import org.lwjgl.BufferUtils
import org.lwjgl.system.MemoryUtil
@ -34,19 +32,7 @@ import javax.imageio.ImageIO
object TextureUtil {
fun ResourceLocation.texture(): ResourceLocation {
var path = ""
if (!this.path.startsWith("textures/")) {
path += "textures/"
}
path += this.path
if (!path.contains(".")) {
// ending
path += ".png"
}
return "$namespace:$path".toResourceLocation()
return this.extend(prefix = "textures/", suffix = ".png")
}
fun TextureTransparencies.getMesh(mesh: ChunkMesh): SingleChunkMesh {

View File

@ -1,5 +1,5 @@
{
"minecraft:sign_front": {
"front": {
"0": {
"texture": "entity/signs/oak",
"resolution": [64, 32],

View File

@ -193,7 +193,7 @@
"texture": "gui/container/enchanting_table"
},
"18": {
"size": [108, 19],
"resolution": [108, 19],
"texture": "gui/sprites/container/enchanting_table/enchantment_slot"
}
},
@ -204,7 +204,7 @@
"texture": "gui/container/enchanting_table"
},
"18": {
"size": [108, 19],
"resolution": [108, 19],
"texture": "gui/sprites/container/enchanting_table/enchantment_slot_disabled"
}
},
@ -215,7 +215,7 @@
"texture": "gui/container/enchanting_table"
},
"18": {
"size": [108, 19],
"resolution": [108, 19],
"texture": "gui/sprites/container/enchanting_table/enchantment_slot_highlighted"
}
},
@ -226,7 +226,7 @@
"texture": "gui/container/enchanting_table"
},
"18": {
"size": [16, 16],
"resolution": [16, 16],
"texture": "gui/sprites/container/enchanting_table/level_1"
}
},
@ -237,7 +237,7 @@
"texture": "gui/container/enchanting_table"
},
"18": {
"size": [16, 16],
"resolution": [16, 16],
"texture": "gui/sprites/container/enchanting_table/level_1_disabled"
}
},
@ -248,7 +248,7 @@
"texture": "gui/container/enchanting_table"
},
"18": {
"size": [16, 16],
"resolution": [16, 16],
"texture": "gui/sprites/container/enchanting_table/level_2"
}
},
@ -259,7 +259,7 @@
"texture": "gui/container/enchanting_table"
},
"18": {
"size": [16, 16],
"resolution": [16, 16],
"texture": "gui/sprites/container/enchanting_table/level_1_disabled"
}
},
@ -270,7 +270,7 @@
"texture": "gui/container/enchanting_table"
},
"18": {
"size": [16, 16],
"resolution": [16, 16],
"texture": "gui/sprites/container/enchanting_table/level_3"
}
},
@ -281,7 +281,7 @@
"texture": "gui/container/enchanting_table"
},
"18": {
"size": [16, 16],
"resolution": [16, 16],
"texture": "gui/sprites/container/enchanting_table/level_3_disabled"
}
}

View File

@ -189,7 +189,7 @@
"texture": "gui/container/furnace"
},
"18": {
"size": [14, 14],
"resolution": [14, 14],
"texture": "gui/sprites/container/furnace/lit_progress"
}
},
@ -200,7 +200,7 @@
"texture": "gui/container/furnace"
},
"18": {
"size": [24, 16],
"resolution": [24, 16],
"texture": "gui/sprites/container/furnace/burn_progress"
}
}

View File

@ -1,5 +1,5 @@
{
"minecraft:inventory_base": {
"container": {
"0": {
"texture": "gui/container/inventory",
"start": [0, 0],

View File

@ -7,7 +7,7 @@
},
"18": {
"texture": "gui/sprites/widget/button_disabled",
"size": [200, 20]
"resolution": [200, 20]
}
},
"normal": {
@ -18,7 +18,7 @@
},
"18": {
"texture": "gui/sprites/widget/button",
"size": [200, 20]
"resolution": [200, 20]
}
},
"hovered": {
@ -29,7 +29,7 @@
},
"18": {
"texture": "gui/sprites/widget/button_highlighted",
"size": [200, 20]
"resolution": [200, 20]
}
}
}

View File

@ -7,7 +7,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/pink_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"pink_full": {
@ -18,7 +18,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/pink_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"blue_empty": {
@ -29,7 +29,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/blue_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"blue_full": {
@ -40,7 +40,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/blue_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"red_empty": {
@ -51,7 +51,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/red_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"red_full": {
@ -62,7 +62,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/red_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"green_empty": {
@ -73,7 +73,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/green_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"green_full": {
@ -84,7 +84,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/green_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"yellow_empty": {
@ -95,7 +95,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/yellow_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"yellow_full": {
@ -106,7 +106,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/yellow_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"purple_empty": {
@ -117,7 +117,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/purple_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"purple_full": {
@ -128,7 +128,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/purple_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"white_empty": {
@ -139,7 +139,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/white_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"white_full": {
@ -150,7 +150,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/white_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"notches_6_empty": {
@ -161,7 +161,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/notched_6_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"notches_6_full": {
@ -172,7 +172,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/notched_6_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"notches_10_empty": {
@ -183,7 +183,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/notched_10_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"notches_10_full": {
@ -194,7 +194,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/notched_10_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"notches_12_empty": {
@ -205,7 +205,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/notched_12_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"notches_12_full": {
@ -216,7 +216,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/notched_12_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"notches_20_empty": {
@ -227,7 +227,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/notched_20_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"notches_20_full": {
@ -238,7 +238,7 @@
},
"18": {
"texture": "gui/sprites/boss_bar/notched_20_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"minecraft:wither_bar_empty": {

View File

@ -7,7 +7,7 @@
},
"18": {
"texture": "gui/sprites/hud/air",
"size": [9, 9]
"resolution": [9, 9]
}
},
"popping": {
@ -18,7 +18,7 @@
},
"18": {
"texture": "gui/sprites/hud/air_bursting",
"size": [9, 9]
"resolution": [9, 9]
}
}
}

View File

@ -6,7 +6,7 @@
},
"18": {
"texture": "gui/sprites/hud/experience_bar_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"full": {
@ -17,7 +17,7 @@
},
"18": {
"texture": "gui/sprites/hud/experience_bar_progress",
"size": [182, 5]
"resolution": [182, 5]
}
},
"horse_empty": {
@ -28,7 +28,7 @@
},
"18": {
"texture": "gui/sprites/hud/jump_bar_background",
"size": [182, 5]
"resolution": [182, 5]
}
},
"horse_full": {
@ -39,7 +39,7 @@
},
"18": {
"texture": "gui/sprites/hud/jump_bar_progress",
"size": [182, 5]
"resolution": [182, 5]
}
}
}

View File

@ -7,25 +7,25 @@
},
"18": {
"texture": "gui/sprites/hud/heart/container",
"size": [9, 9]
"resolution": [9, 9]
}
},
"container_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/container_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"container_hardcore": {
"18": {
"texture": "gui/sprites/hud/heart/container_hardcore",
"size": [9, 9]
"resolution": [9, 9]
}
},
"container_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/container_hardcore_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"container_vehicle": {
@ -36,7 +36,7 @@
},
"18": {
"texture": "gui/sprites/hud/heart/vehicle_container",
"size": [9, 9]
"resolution": [9, 9]
}
},
"full": {
@ -47,13 +47,13 @@
},
"18": {
"texture": "gui/sprites/hud/heart/full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"full_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"full_hardcore": {
@ -64,13 +64,13 @@
},
"18": {
"texture": "gui/sprites/hud/heart/hardcore_full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"full_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/hardcore_full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"half": {
@ -81,7 +81,7 @@
},
"18": {
"texture": "gui/sprites/hud/heart/half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"half_hardcore": {
@ -92,19 +92,19 @@
},
"18": {
"texture": "gui/sprites/hud/heart/hardcore_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"half_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"half_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/hardcore_half_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"poisoned_full": {
@ -115,13 +115,13 @@
},
"18": {
"texture": "gui/sprites/hud/heart/poisoned_full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"poisoned_full_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/poisoned_full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"poisoned_full_hardcore": {
@ -132,13 +132,13 @@
},
"18": {
"texture": "gui/sprites/hud/heart/poisoned_hardcore_full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"poisoned_full_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/poisoned_hardcore_full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"poisoned_half": {
@ -149,7 +149,7 @@
},
"18": {
"texture": "gui/sprites/hud/heart/poisoned_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"poisoned_half_hardcore": {
@ -160,19 +160,19 @@
},
"18": {
"texture": "gui/sprites/hud/heart/poisoned_hardcore_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"poisoned_half_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/poisoned_half_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"poisoned_half_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/poisoned_hardcore_half_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"withered_full": {
@ -183,13 +183,13 @@
},
"18": {
"texture": "gui/sprites/hud/heart/withered_full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"withered_full_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/withered_full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"withered_full_hardcore": {
@ -200,13 +200,13 @@
},
"18": {
"texture": "gui/sprites/hud/heart/withered_hardcore_full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"withered_full_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/withered_hardcore_full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"withered_half": {
@ -217,7 +217,7 @@
},
"18": {
"texture": "gui/sprites/hud/heart/withered_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"withered_half_hardcore": {
@ -228,19 +228,19 @@
},
"18": {
"texture": "gui/sprites/hud/heart/withered_hardcore_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"withered_half_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/withered_half_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"withered_half_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/withered_hardcore_half_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"absorption_full": {
@ -251,13 +251,13 @@
},
"18": {
"texture": "gui/sprites/hud/heart/absorbing_full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"absorption_full_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/absorbing_full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"absorption_full_hardcore": {
@ -268,13 +268,13 @@
},
"18": {
"texture": "gui/sprites/hud/heart/absorbing_hardcore_full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"absorption_full_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/absorbing_hardcore_full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"absorption_half": {
@ -285,7 +285,7 @@
},
"18": {
"texture": "gui/sprites/hud/heart/absorbing_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"absorption_half_hardcore": {
@ -296,19 +296,19 @@
},
"18": {
"texture": "gui/sprites/hud/heart/absorbing_hardcore_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"absorption_half_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/absorbing_half_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"absorption_half_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/absorbing_hardcore_half_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"frozen_full": {
@ -319,13 +319,13 @@
},
"18": {
"texture": "gui/sprites/hud/heart/frozen_full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"frozen_full_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/frozen_full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"frozen_full_hardcore": {
@ -336,13 +336,13 @@
},
"18": {
"texture": "gui/sprites/hud/heart/frozen_hardcore_full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"frozen_full_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/frozen_hardcore_full_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"frozen_half": {
@ -353,7 +353,7 @@
},
"18": {
"texture": "gui/sprites/hud/heart/frozen_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"frozen_half_hardcore": {
@ -364,19 +364,19 @@
},
"18": {
"texture": "gui/sprites/hud/heart/frozen_hardcore_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"frozen_half_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/frozen_half_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"frozen_half_hardcore_blinking": {
"18": {
"texture": "gui/sprites/hud/heart/frozen_hardcore_half_blinking",
"size": [9, 9]
"resolution": [9, 9]
}
},
"half_vehicle": {
@ -387,7 +387,7 @@
},
"18": {
"texture": "gui/sprites/hud/heart/vehicle_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"full_vehicle": {
@ -398,7 +398,7 @@
},
"18": {
"texture": "gui/sprites/hud/heart/vehicle_full",
"size": [9, 9]
"resolution": [9, 9]
}
}
}

View File

@ -1,5 +1,5 @@
{
"minecraft:hotbar_base": {
"base": {
"0": {
"texture": "gui/widgets",
"end": [182, 22],
@ -44,7 +44,7 @@
},
"18": {
"texture": "gui/sprites/hud/hotbar",
"size": [182, 22],
"resolution": [182, 22],
"slots": {
"36": {
"start": [3, 3],
@ -85,7 +85,7 @@
}
}
},
"minecraft:hotbar_frame": {
"frame": {
"0": {
"texture": "gui/widgets",
"start": [0, 0],
@ -93,10 +93,10 @@
},
"18": {
"texture": "gui/sprites/hud/hotbar_selection",
"size": [24, 23]
"resolution": [24, 23]
}
},
"minecraft:offhand_left_arm_frame": {
"offhand_left": {
"0": {
"texture": "gui/widgets",
"start": [24, 23],
@ -110,7 +110,7 @@
},
"18": {
"texture": "gui/sprites/hud/hotbar_offhand_left",
"size": [29, 24],
"resolution": [29, 24],
"slots": {
"45": {
"start": [3, 3],
@ -119,7 +119,7 @@
}
}
},
"minecraft:offhand_right_arm_frame": {
"offhand_right": {
"0": {
"texture": "gui/widgets",
"start": [60, 23],
@ -133,7 +133,7 @@
},
"18": {
"texture": "gui/sprites/hud/hotbar_offhand_right",
"size": [29, 24],
"resolution": [29, 24],
"slots": {
"45": {
"start": [3, 3],

View File

@ -7,7 +7,7 @@
},
"18": {
"texture": "gui/sprites/hud/armor_empty",
"size": [9, 9]
"resolution": [9, 9]
}
},
"half": {
@ -18,7 +18,7 @@
},
"18": {
"texture": "gui/sprites/hud/armor_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"full": {
@ -29,7 +29,7 @@
},
"18": {
"texture": "gui/sprites/hud/armor_full",
"size": [9, 9]
"resolution": [9, 9]
}
}
}

View File

@ -7,7 +7,7 @@
},
"18": {
"texture": "gui/sprites/hud/crosshair",
"size": [15, 15]
"resolution": [15, 15]
}
}
}

View File

@ -7,7 +7,7 @@
},
"18": {
"texture": "gui/sprites/icon/ping_5",
"size": [10, 8]
"resolution": [10, 8]
}
},
"ping_4": {
@ -18,7 +18,7 @@
},
"18": {
"texture": "gui/sprites/icon/ping_4",
"size": [10, 8]
"resolution": [10, 8]
}
},
"ping_3": {
@ -29,7 +29,7 @@
},
"18": {
"texture": "gui/sprites/icon/ping_3",
"size": [10, 8]
"resolution": [10, 8]
}
},
"ping_2": {
@ -40,7 +40,7 @@
},
"18": {
"texture": "gui/sprites/icon/ping_2",
"size": [10, 8]
"resolution": [10, 8]
}
},
"ping_1": {
@ -51,7 +51,7 @@
},
"18": {
"texture": "gui/sprites/icon/ping_1",
"size": [10, 8]
"resolution": [10, 8]
}
},
"ping_0": {
@ -62,7 +62,7 @@
},
"18": {
"texture": "gui/sprites/icon/unrechable",
"size": [10, 8]
"resolution": [10, 8]
}
}
}

View File

@ -7,7 +7,7 @@
},
"18": {
"texture": "minecraft:gui/sprites/hud/food_empty",
"size": [9, 9]
"resolution": [9, 9]
}
},
"container_hunger": {
@ -18,7 +18,7 @@
},
"18": {
"texture": "minecraft:gui/sprites/hud/food_empty_hunger",
"size": [9, 9]
"resolution": [9, 9]
}
},
"container_saturation_half": {
@ -43,7 +43,7 @@
},
"18": {
"texture": "minecraft:gui/sprites/hud/food_full",
"size": [9, 9]
"resolution": [9, 9]
}
},
"half": {
@ -54,7 +54,7 @@
},
"18": {
"texture": "minecraft:gui/sprites/hud/food_half",
"size": [9, 9]
"resolution": [9, 9]
}
},
"full_hunger": {
@ -65,7 +65,7 @@
},
"18": {
"texture": "minecraft:gui/sprites/hud/food_full_hunger",
"size": [9, 9]
"resolution": [9, 9]
}
},
"half_hunger": {
@ -76,7 +76,7 @@
},
"18": {
"texture": "minecraft:gui/sprites/hud/food_half_hunger",
"size": [9, 9]
"resolution": [9, 9]
}
}
}