More work on texture atlas
This commit is contained in:
parent
9bf31d2af0
commit
23227e21e5
@ -23,6 +23,7 @@ import net.minecraft.world.level.ItemLike
|
||||
import net.minecraftforge.registries.ForgeRegistries
|
||||
import ru.dbotthepony.mc.otm.client.render.AbstractSkinElement
|
||||
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
||||
import ru.dbotthepony.mc.otm.client.render.SkinElementType
|
||||
import ru.dbotthepony.mc.otm.core.ListSet
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.isActuallyEmpty
|
||||
@ -92,7 +93,7 @@ class AndroidResearchType(
|
||||
private val customName: Component? = null,
|
||||
|
||||
// ok
|
||||
val skinIcon: JsonElement? = null,
|
||||
val skinIcon: JsonObject? = null,
|
||||
val itemIcon: Item? = null,
|
||||
iconText: Component? = null,
|
||||
) {
|
||||
@ -102,7 +103,7 @@ class AndroidResearchType(
|
||||
val resolvedSkinIcon by lazy {
|
||||
check(isClient) { "Invalid realm" }
|
||||
if (skinIcon != null)
|
||||
AbstractSkinElement.fromJson(skinIcon)
|
||||
SkinElementType.fromJson(skinIcon)
|
||||
else
|
||||
null
|
||||
}
|
||||
@ -550,7 +551,7 @@ class AndroidResearchType(
|
||||
}
|
||||
|
||||
val skinIcon = if (buff.readBoolean()) {
|
||||
TypeAdapters.JSON_ELEMENT.fromJson(buff.readUtf())
|
||||
TypeAdapters.JSON_ELEMENT.fromJson(buff.readUtf()) as JsonObject
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@ -591,7 +592,7 @@ class AndroidResearchType(
|
||||
val experience = value["experience"]?.asInt ?: 0
|
||||
val customName = value["custom_name"]?.let(Component.Serializer::fromJson)
|
||||
val iconText = value["icon_text"]?.let(Component.Serializer::fromJson)
|
||||
val skinIcon = value["skin_icon"]
|
||||
val skinIcon = value["skin_icon"] as JsonObject?
|
||||
val itemIcon = value["item_icon"]?.let { ForgeRegistries.ITEMS.getValue(ResourceLocation(it.asString)).let { if (it == Items.AIR) null else it } }
|
||||
|
||||
return AndroidResearchType(
|
||||
|
@ -30,11 +30,11 @@ import java.util.*
|
||||
import kotlin.math.ceil
|
||||
|
||||
object MatteryGUI {
|
||||
val CHARGE = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_charge/android_charge"))
|
||||
val CHARGE_BG = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_charge/android_charge_bg"))
|
||||
val CHARGE = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_charge/android_charge"), 80f, 9f)
|
||||
val CHARGE_BG = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_charge/android_charge_bg"), 80f, 9f)
|
||||
|
||||
val CHARGE_HUNGER = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_charge/android_charge_hunger"))
|
||||
val CHARGE_HUNGER_BG = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_charge/android_charge_hunger_bg"))
|
||||
val CHARGE_HUNGER = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_charge/android_charge_hunger"), 80f, 9f)
|
||||
val CHARGE_HUNGER_BG = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_charge/android_charge_hunger_bg"), 80f, 9f)
|
||||
|
||||
private var originalBedButtonX = -1
|
||||
private var originalBedButtonY = -1
|
||||
|
@ -22,14 +22,25 @@ import ru.dbotthepony.mc.otm.core.linearInterpolation
|
||||
import java.lang.reflect.Type
|
||||
|
||||
sealed class AbstractSkinElement {
|
||||
abstract val x: Float
|
||||
abstract val y: Float
|
||||
/**
|
||||
* Expected image width in pixels, used in calculations
|
||||
* and as default width argument in render methods
|
||||
*/
|
||||
abstract val width: Float
|
||||
|
||||
/**
|
||||
* Expected image height in pixels, used in calculations
|
||||
* and as default height argument in render methods
|
||||
*/
|
||||
abstract val height: Float
|
||||
|
||||
abstract val u0: Float
|
||||
abstract val v0: Float
|
||||
abstract val u1: Float
|
||||
abstract val v1: Float
|
||||
|
||||
abstract val type: SkinElementType
|
||||
|
||||
open val winding: UVWindingOrder get() = UVWindingOrder.NORMAL
|
||||
|
||||
abstract val texture: ResourceLocation
|
||||
@ -290,55 +301,11 @@ sealed class AbstractSkinElement {
|
||||
uploadOnto(pose, builder, x, y, width, height, z, color, winding)
|
||||
}
|
||||
|
||||
abstract fun toJson(): JsonElement
|
||||
abstract fun toNetwork(buff: FriendlyByteBuf)
|
||||
|
||||
companion object : TypeAdapter<AbstractSkinElement>(), JsonSerializer<AbstractSkinElement>, JsonDeserializer<AbstractSkinElement> {
|
||||
fun toNetwork(value: AbstractSkinElement, buff: FriendlyByteBuf) {
|
||||
buff.writeBoolean(value is AtlasSkinElement)
|
||||
value.toNetwork(buff)
|
||||
fun toJson(): JsonObject {
|
||||
return type.toActualJson(this)
|
||||
}
|
||||
|
||||
fun fromNetwork(buff: FriendlyByteBuf): AbstractSkinElement {
|
||||
if (buff.readBoolean()) {
|
||||
return AtlasSkinElement.fromNetwork(buff)
|
||||
}
|
||||
|
||||
return SkinElement.fromNetwork(buff)
|
||||
}
|
||||
|
||||
fun fromJson(json: JsonElement): AbstractSkinElement {
|
||||
if (json is JsonPrimitive) {
|
||||
return AtlasSkinElement.fromJson(json)
|
||||
} else if (json is JsonObject) {
|
||||
return SkinElement.fromJson(json)
|
||||
} else {
|
||||
throw JsonSyntaxException("Unknown element type ${json::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun write(out: JsonWriter, value: AbstractSkinElement) {
|
||||
TypeAdapters.JSON_ELEMENT.write(out, value.toJson())
|
||||
}
|
||||
|
||||
override fun read(`in`: JsonReader): AbstractSkinElement {
|
||||
return fromJson(TypeAdapters.JSON_ELEMENT.read(`in`))
|
||||
}
|
||||
|
||||
override fun serialize(
|
||||
src: AbstractSkinElement,
|
||||
typeOfSrc: Type,
|
||||
context: JsonSerializationContext
|
||||
): JsonElement {
|
||||
return src.toJson()
|
||||
}
|
||||
|
||||
override fun deserialize(
|
||||
json: JsonElement,
|
||||
typeOfT: Type,
|
||||
context: JsonDeserializationContext
|
||||
): AbstractSkinElement {
|
||||
return fromJson(json)
|
||||
}
|
||||
fun toNetwork(buff: FriendlyByteBuf) {
|
||||
type.toActualNetwork(this, buff)
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,9 @@ import java.lang.reflect.Type
|
||||
import java.util.stream.Stream
|
||||
|
||||
class AtlasSkinElement(
|
||||
val location: ResourceLocation
|
||||
val location: ResourceLocation,
|
||||
override val width: Float,
|
||||
override val height: Float,
|
||||
) : AbstractSkinElement() {
|
||||
init {
|
||||
synchronized(keys) {
|
||||
@ -46,7 +48,7 @@ class AtlasSkinElement(
|
||||
check(isClient) { "Invalid realm" }
|
||||
val _textureAtlasSprite = _textureAtlasSprite
|
||||
|
||||
if (_textureAtlasSprite == null || changeset != WidgetAtlasHolder.INSTANCE.changeset || (WidgetAtlasHolder.INSTANCE.demandsRebuild && isClientThread())) {
|
||||
if (_textureAtlasSprite == null || _textureAtlasSprite.name.let { it.namespace == "minecraft" && it.path == "missingno" } || changeset != WidgetAtlasHolder.INSTANCE.changeset || WidgetAtlasHolder.INSTANCE.speculateIfMinecraftEngineIsDumDum()) {
|
||||
val get = WidgetAtlasHolder.INSTANCE.getSprite(location)
|
||||
this._textureAtlasSprite = get
|
||||
changeset = WidgetAtlasHolder.INSTANCE.changeset
|
||||
@ -61,11 +63,6 @@ class AtlasSkinElement(
|
||||
return textureAtlasSpriteImpl
|
||||
}
|
||||
|
||||
override val x get() = textureAtlasSprite.x.toFloat()
|
||||
override val y get() = textureAtlasSprite.y.toFloat()
|
||||
override val width get() = textureAtlasSprite.width.toFloat()
|
||||
override val height get() = textureAtlasSprite.height.toFloat()
|
||||
|
||||
override val u0 get() = textureAtlasSprite.u0
|
||||
override val v0 get() = textureAtlasSprite.v0
|
||||
override val u1 get() = textureAtlasSprite.u1
|
||||
@ -87,15 +84,10 @@ class AtlasSkinElement(
|
||||
return "AtlasSkinElement[$location]"
|
||||
}
|
||||
|
||||
override fun toJson(): JsonElement {
|
||||
return JsonPrimitive(location.toString())
|
||||
}
|
||||
override val type: SkinElementType
|
||||
get() = SkinElementType.ATLAS
|
||||
|
||||
override fun toNetwork(buff: FriendlyByteBuf) {
|
||||
buff.writeResourceLocation(location)
|
||||
}
|
||||
|
||||
companion object : TypeAdapter<AtlasSkinElement>(), JsonSerializer<AtlasSkinElement>, JsonDeserializer<AtlasSkinElement> {
|
||||
companion object {
|
||||
private val keys = HashSet<ResourceLocation>()
|
||||
val keysStream: Stream<ResourceLocation> get() = keys.stream()
|
||||
|
||||
@ -103,38 +95,6 @@ class AtlasSkinElement(
|
||||
WidgetAtlasHolder.INSTANCE.queueRebuild()
|
||||
}
|
||||
|
||||
fun fromNetwork(buff: FriendlyByteBuf): AtlasSkinElement {
|
||||
return AtlasSkinElement(buff.readResourceLocation())
|
||||
}
|
||||
|
||||
fun fromJson(element: JsonElement): AtlasSkinElement {
|
||||
return AtlasSkinElement(ResourceLocation.tryParse(element.asString) ?: ResourceLocation("missing"))
|
||||
}
|
||||
|
||||
override fun write(out: JsonWriter, value: AtlasSkinElement) {
|
||||
TypeAdapters.JSON_ELEMENT.write(out, value.toJson())
|
||||
}
|
||||
|
||||
override fun read(`in`: JsonReader): AtlasSkinElement {
|
||||
return fromJson(TypeAdapters.JSON_ELEMENT.read(`in`))
|
||||
}
|
||||
|
||||
override fun serialize(
|
||||
src: AtlasSkinElement,
|
||||
typeOfSrc: Type,
|
||||
context: JsonSerializationContext
|
||||
): JsonElement {
|
||||
return src.toJson()
|
||||
}
|
||||
|
||||
override fun deserialize(
|
||||
json: JsonElement,
|
||||
typeOfT: Type,
|
||||
context: JsonDeserializationContext
|
||||
): AtlasSkinElement {
|
||||
return fromJson(json)
|
||||
}
|
||||
|
||||
val renderTypeGUI by lazy {
|
||||
val builder = RenderType.CompositeState.builder()
|
||||
|
||||
|
@ -36,28 +36,28 @@ object ResearchIcons {
|
||||
init {
|
||||
var i = 0
|
||||
|
||||
ICON_TRANSFER = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_ATTACK_BOOST = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_PLASMA_SHIELD_BOOST = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_CLOAK = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_GRAVITATIONAL_STABILIZER = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_AIR_BAGS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_JUMP_BOOST = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_FEATHER_FALLING = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_ITEM_MAGNET = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_ARROW = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_ARMOR = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_NANOBOTS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_NIGHT_VISION = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_OXYGEN_SUPPLY = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_PLASMA_SHIELD = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_SHOCKWAVE = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_LIMB_OVERCLOCKING = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_STEP_ASSIST = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_ENDER_TELEPORT = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_WIRELESS_CHARGING = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_UNKNOWN = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_EXTENDED_REACH = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_PHANTOM_ATTRACTOR = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"))
|
||||
ICON_TRANSFER = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_ATTACK_BOOST = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_PLASMA_SHIELD_BOOST = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_CLOAK = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_GRAVITATIONAL_STABILIZER = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_AIR_BAGS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_JUMP_BOOST = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_FEATHER_FALLING = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_ITEM_MAGNET = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_ARROW = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_ARMOR = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_NANOBOTS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_NIGHT_VISION = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_OXYGEN_SUPPLY = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_PLASMA_SHIELD = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_SHOCKWAVE = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_LIMB_OVERCLOCKING = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_STEP_ASSIST = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_ENDER_TELEPORT = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_WIRELESS_CHARGING = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_UNKNOWN = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_EXTENDED_REACH = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
ICON_PHANTOM_ATTRACTOR = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research/android_stuff-${i++}"), 18f, 18f)
|
||||
}
|
||||
}
|
||||
|
@ -52,91 +52,14 @@ fun ResourceLocation.vLine(
|
||||
@Suppress("unused")
|
||||
data class SkinElement @JvmOverloads constructor(
|
||||
override val texture: ResourceLocation,
|
||||
override val x: Float,
|
||||
override val y: Float,
|
||||
val x: Float,
|
||||
val y: Float,
|
||||
override val width: Float,
|
||||
override val height: Float,
|
||||
val imageWidth: Float = 256f,
|
||||
val imageHeight: Float = 256f,
|
||||
override val winding: UVWindingOrder = UVWindingOrder.NORMAL,
|
||||
) : AbstractSkinElement() {
|
||||
override fun toJson(): JsonObject {
|
||||
return JsonObject().also {
|
||||
it["texture"] = JsonPrimitive(texture.toString())
|
||||
it["x"] = JsonPrimitive(x)
|
||||
it["y"] = JsonPrimitive(y)
|
||||
it["width"] = JsonPrimitive(width)
|
||||
it["height"] = JsonPrimitive(height)
|
||||
it["imageWidth"] = JsonPrimitive(imageWidth)
|
||||
it["imageHeight"] = JsonPrimitive(imageHeight)
|
||||
it["winding"] = JsonPrimitive(winding.name)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toNetwork(buff: FriendlyByteBuf) {
|
||||
buff.writeUtf(texture.toString())
|
||||
buff.writeFloat(x)
|
||||
buff.writeFloat(y)
|
||||
buff.writeFloat(width)
|
||||
buff.writeFloat(height)
|
||||
buff.writeFloat(imageWidth)
|
||||
buff.writeFloat(imageHeight)
|
||||
buff.writeEnum(winding)
|
||||
}
|
||||
|
||||
companion object : TypeAdapter<SkinElement>(), JsonSerializer<SkinElement>, JsonDeserializer<SkinElement> {
|
||||
fun fromNetwork(buff: FriendlyByteBuf): SkinElement {
|
||||
val texture = ResourceLocation(buff.readUtf())
|
||||
val x = buff.readFloat()
|
||||
val y = buff.readFloat()
|
||||
val width = buff.readFloat()
|
||||
val height = buff.readFloat()
|
||||
val imageWidth = buff.readFloat()
|
||||
val imageHeight = buff.readFloat()
|
||||
val winding = buff.readEnum(UVWindingOrder::class.java)
|
||||
|
||||
return SkinElement(texture, x, y, width, height, imageWidth, imageHeight, winding)
|
||||
}
|
||||
|
||||
fun fromJson(value: JsonObject): SkinElement {
|
||||
val texture = value["texture"]?.asString ?: throw JsonSyntaxException("Missing texture element")
|
||||
val x = value["x"]?.asFloat ?: throw JsonSyntaxException("Missing x element")
|
||||
val y = value["y"]?.asFloat ?: throw JsonSyntaxException("Missing y element")
|
||||
val width = value["width"]?.asFloat ?: throw JsonSyntaxException("Missing width element")
|
||||
val height = value["height"]?.asFloat ?: throw JsonSyntaxException("Missing height element")
|
||||
val imageWidth = value["imageWidth"]?.asFloat ?: throw JsonSyntaxException("Missing imageWidth element")
|
||||
val imageHeight = value["imageHeight"]?.asFloat ?: throw JsonSyntaxException("Missing imageHeight element")
|
||||
val winding = value["winding"]?.asString ?: throw JsonSyntaxException("Missing winding element")
|
||||
|
||||
return SkinElement(ResourceLocation(texture), x, y, width, height, imageWidth, imageHeight, UVWindingOrder.valueOf(winding))
|
||||
}
|
||||
|
||||
fun fromJson(value: JsonElement): SkinElement {
|
||||
return fromJson(value as? JsonObject ?: throw JsonSyntaxException("Expected JsonObject, got ${value::class.qualifiedName}"))
|
||||
}
|
||||
|
||||
override fun write(out: JsonWriter, value: SkinElement) {
|
||||
TypeAdapters.JSON_ELEMENT.write(out, value.toJson())
|
||||
}
|
||||
|
||||
override fun read(reader: JsonReader): SkinElement {
|
||||
val read = TypeAdapters.JSON_ELEMENT.read(reader)
|
||||
return fromJson(read as? JsonObject ?: throw JsonSyntaxException("Expected JsonObject, got ${read::class.qualifiedName}"))
|
||||
}
|
||||
|
||||
override fun serialize(src: SkinElement, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
|
||||
return src.toJson()
|
||||
}
|
||||
|
||||
override fun deserialize(
|
||||
json: JsonElement,
|
||||
typeOfT: Type,
|
||||
context: JsonDeserializationContext
|
||||
): SkinElement {
|
||||
return fromJson(json as? JsonObject ?: throw JsonSyntaxException("Expected JsonObject, got ${json::class.qualifiedName}"))
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
require(x >= 0f) { "Invalid x $x" }
|
||||
require(y >= 0f) { "Invalid y $y" }
|
||||
@ -150,4 +73,7 @@ data class SkinElement @JvmOverloads constructor(
|
||||
override val v0 = this.y / imageHeight
|
||||
override val u1 = (this.x + width) / imageWidth
|
||||
override val v1 = (this.y + height) / imageHeight
|
||||
|
||||
override val type: SkinElementType
|
||||
get() = SkinElementType.SINGLE
|
||||
}
|
||||
|
@ -0,0 +1,172 @@
|
||||
package ru.dbotthepony.mc.otm.client.render
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
|
||||
enum class SkinElementType {
|
||||
SINGLE {
|
||||
override fun toJson(value: AbstractSkinElement): JsonObject {
|
||||
require(value is SkinElement) { "Invalid skin element provided, expected SkinElement, got ${value::class.qualifiedName}" }
|
||||
|
||||
return JsonObject().also {
|
||||
it["texture"] = JsonPrimitive(value.texture.toString())
|
||||
it["x"] = JsonPrimitive(value.x)
|
||||
it["y"] = JsonPrimitive(value.y)
|
||||
it["width"] = JsonPrimitive(value.width)
|
||||
it["height"] = JsonPrimitive(value.height)
|
||||
it["imageWidth"] = JsonPrimitive(value.imageWidth)
|
||||
it["imageHeight"] = JsonPrimitive(value.imageHeight)
|
||||
it["winding"] = JsonPrimitive(value.winding.name)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toNetwork(value: AbstractSkinElement, buff: FriendlyByteBuf) {
|
||||
require(value is SkinElement) { "Invalid skin element provided, expected SkinElement, got ${value::class.qualifiedName}" }
|
||||
|
||||
buff.writeUtf(value.texture.toString())
|
||||
buff.writeFloat(value.x)
|
||||
buff.writeFloat(value.y)
|
||||
buff.writeFloat(value.width)
|
||||
buff.writeFloat(value.height)
|
||||
buff.writeFloat(value.imageWidth)
|
||||
buff.writeFloat(value.imageHeight)
|
||||
buff.writeEnum(value.winding)
|
||||
}
|
||||
|
||||
override fun fromNetwork(buff: FriendlyByteBuf): AbstractSkinElement {
|
||||
val texture = ResourceLocation(buff.readUtf())
|
||||
val x = buff.readFloat()
|
||||
val y = buff.readFloat()
|
||||
val width = buff.readFloat()
|
||||
val height = buff.readFloat()
|
||||
val imageWidth = buff.readFloat()
|
||||
val imageHeight = buff.readFloat()
|
||||
val winding = buff.readEnum(UVWindingOrder::class.java)
|
||||
|
||||
return SkinElement(texture, x, y, width, height, imageWidth, imageHeight, winding)
|
||||
}
|
||||
|
||||
override fun fromJson(element: JsonObject): AbstractSkinElement {
|
||||
val texture = element["texture"]?.asString ?: throw JsonSyntaxException("Missing texture element")
|
||||
val x = element["x"]?.asFloat ?: throw JsonSyntaxException("Missing x element")
|
||||
val y = element["y"]?.asFloat ?: throw JsonSyntaxException("Missing y element")
|
||||
val width = element["width"]?.asFloat ?: throw JsonSyntaxException("Missing width element")
|
||||
val height = element["height"]?.asFloat ?: throw JsonSyntaxException("Missing height element")
|
||||
val imageWidth = element["imageWidth"]?.asFloat ?: throw JsonSyntaxException("Missing imageWidth element")
|
||||
val imageHeight = element["imageHeight"]?.asFloat ?: throw JsonSyntaxException("Missing imageHeight element")
|
||||
val winding = element["winding"]?.asString ?: throw JsonSyntaxException("Missing winding element")
|
||||
|
||||
return SkinElement(ResourceLocation.tryParse(texture) ?: throw JsonSyntaxException("Invalid resource location: $texture"), x, y, width, height, imageWidth, imageHeight, UVWindingOrder.valueOf(winding))
|
||||
}
|
||||
},
|
||||
ATLAS {
|
||||
override fun toJson(value: AbstractSkinElement): JsonObject {
|
||||
require(value is AtlasSkinElement) { "Invalid skin element provided, expected AtlasSkinElement, got ${value::class.qualifiedName}" }
|
||||
|
||||
return JsonObject().also {
|
||||
it["location"] = JsonPrimitive(value.location.toString())
|
||||
it["width"] = JsonPrimitive(value.width)
|
||||
it["height"] = JsonPrimitive(value.height)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toNetwork(value: AbstractSkinElement, buff: FriendlyByteBuf) {
|
||||
require(value is AtlasSkinElement) { "Invalid skin element provided, expected AtlasSkinElement, got ${value::class.qualifiedName}" }
|
||||
|
||||
buff.writeResourceLocation(value.location)
|
||||
buff.writeFloat(value.width)
|
||||
buff.writeFloat(value.height)
|
||||
}
|
||||
|
||||
override fun fromNetwork(buff: FriendlyByteBuf): AbstractSkinElement {
|
||||
val location = ResourceLocation(buff.readUtf())
|
||||
val width = buff.readFloat()
|
||||
val height = buff.readFloat()
|
||||
|
||||
return AtlasSkinElement(location, width, height)
|
||||
}
|
||||
|
||||
override fun fromJson(element: JsonObject): AbstractSkinElement {
|
||||
val location = element["location"]?.asString ?: throw JsonSyntaxException("Missing location element")
|
||||
val width = element["width"]?.asFloat ?: throw JsonSyntaxException("Missing width element")
|
||||
val height = element["height"]?.asFloat ?: throw JsonSyntaxException("Missing height element")
|
||||
|
||||
return AtlasSkinElement(ResourceLocation.tryParse(location) ?: throw JsonSyntaxException("Invalid resource location: $location"), width, height)
|
||||
}
|
||||
},
|
||||
SUBELEMENT {
|
||||
override fun toJson(value: AbstractSkinElement): JsonObject {
|
||||
require(value is SubSkinElement) { "Invalid skin element provided, expected SubSkinElement, got ${value::class.qualifiedName}" }
|
||||
|
||||
return JsonObject().also {
|
||||
it["parent"] = value.parent.toJson()
|
||||
it["xOffset"] = JsonPrimitive(value.xOffset)
|
||||
it["yOffset"] = JsonPrimitive(value.yOffset)
|
||||
it["subWidth"] = JsonPrimitive(value.subWidth)
|
||||
it["subHeight"] = JsonPrimitive(value.subHeight)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toNetwork(value: AbstractSkinElement, buff: FriendlyByteBuf) {
|
||||
require(value is SubSkinElement) { "Invalid skin element provided, expected SubSkinElement, got ${value::class.qualifiedName}" }
|
||||
|
||||
value.parent.toNetwork(buff)
|
||||
buff.writeFloat(value.xOffset)
|
||||
buff.writeFloat(value.yOffset)
|
||||
buff.writeFloat(value.subWidth)
|
||||
buff.writeFloat(value.subHeight)
|
||||
}
|
||||
|
||||
override fun fromNetwork(buff: FriendlyByteBuf): AbstractSkinElement {
|
||||
val parent = fromNetwork(buff)
|
||||
val xOffset = buff.readFloat()
|
||||
val yOffset = buff.readFloat()
|
||||
val subWidth = buff.readFloat()
|
||||
val subHeight = buff.readFloat()
|
||||
|
||||
return SubSkinElement(parent, xOffset, yOffset, subWidth, subHeight)
|
||||
}
|
||||
|
||||
override fun fromJson(element: JsonObject): AbstractSkinElement {
|
||||
val parent = element["parent"] as? JsonObject ?: throw JsonSyntaxException("Invalid parent")
|
||||
val xOffset = element["xOffset"].asFloat
|
||||
val yOffset = element["yOffset"].asFloat
|
||||
val subWidth = element["subWidth"].asFloat
|
||||
val subHeight = element["subHeight"].asFloat
|
||||
|
||||
return SubSkinElement(fromJson(parent), xOffset, yOffset, subWidth, subHeight)
|
||||
}
|
||||
};
|
||||
|
||||
protected abstract fun toJson(value: AbstractSkinElement): JsonObject
|
||||
protected abstract fun toNetwork(value: AbstractSkinElement, buff: FriendlyByteBuf)
|
||||
protected abstract fun fromNetwork(buff: FriendlyByteBuf): AbstractSkinElement
|
||||
protected abstract fun fromJson(element: JsonObject): AbstractSkinElement
|
||||
|
||||
fun toActualJson(value: AbstractSkinElement): JsonObject {
|
||||
return toJson(value).also {
|
||||
it["type"] = JsonPrimitive(name)
|
||||
}
|
||||
}
|
||||
|
||||
fun toActualNetwork(value: AbstractSkinElement, buff: FriendlyByteBuf) {
|
||||
buff.writeEnum(this)
|
||||
toNetwork(value, buff)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromNetwork(buff: FriendlyByteBuf): AbstractSkinElement {
|
||||
val type = buff.readEnum(SkinElementType::class.java)
|
||||
return type.fromNetwork(buff)
|
||||
}
|
||||
|
||||
fun fromJson(element: JsonObject): AbstractSkinElement {
|
||||
val type = SkinElementType.valueOf(element["type"].asString)
|
||||
return type.fromJson(element)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package ru.dbotthepony.mc.otm.client.render
|
||||
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
class SubSkinElement(
|
||||
val parent: AbstractSkinElement,
|
||||
val xOffset: Float = 0f,
|
||||
val yOffset: Float = 0f,
|
||||
val subWidth: Float = parent.width,
|
||||
val subHeight: Float = parent.height,
|
||||
) : AbstractSkinElement() {
|
||||
override val width: Float
|
||||
get() = subWidth
|
||||
override val height: Float
|
||||
get() = subHeight
|
||||
|
||||
override val u0: Float
|
||||
get() = parent.u0 + (xOffset / parent.width) * (parent.u1 - parent.u0)
|
||||
override val v0: Float
|
||||
get() = parent.v0 + (yOffset / parent.height) * (parent.v1 - parent.v0)
|
||||
|
||||
override val u1: Float
|
||||
get() = parent.u1 + ((xOffset + subWidth) / parent.width) * (parent.u1 - parent.u0)
|
||||
override val v1: Float
|
||||
get() = parent.v1 + ((yOffset + subHeight) / parent.height) * (parent.v1 - parent.v0)
|
||||
|
||||
override val texture: ResourceLocation
|
||||
get() = parent.texture
|
||||
|
||||
override val type: SkinElementType
|
||||
get() = SkinElementType.SUBELEMENT
|
||||
}
|
||||
|
||||
fun AbstractSkinElement.subElement(
|
||||
x: Float = 0f,
|
||||
y: Float = 0f,
|
||||
width: Float = this.width,
|
||||
height: Float = this.height,
|
||||
) = SubSkinElement(this, x, y, width, height)
|
@ -28,6 +28,10 @@ class WidgetAtlasHolder private constructor(manager: TextureManager) : TextureAt
|
||||
private set
|
||||
var demandsRebuild = false
|
||||
private set
|
||||
var demandsRebuildAt = 0L
|
||||
private set
|
||||
var dirtyUntil = 0L
|
||||
private set
|
||||
|
||||
private var resourceManager by Delegates.notNull<ResourceManager>()
|
||||
private var profileManager by Delegates.notNull<ProfilerFiller>()
|
||||
@ -38,23 +42,46 @@ class WidgetAtlasHolder private constructor(manager: TextureManager) : TextureAt
|
||||
resourceManager = p_118891_
|
||||
profileManager = p_118892_
|
||||
changeset++
|
||||
dirtyUntil = System.nanoTime() + 1_000_000_000L
|
||||
return super.prepare(p_118891_, p_118892_)
|
||||
}
|
||||
|
||||
override fun apply(p_118894_: TextureAtlas.Preparations, p_118895_: ResourceManager, p_118896_: ProfilerFiller) {
|
||||
once = true
|
||||
demandsRebuild = false
|
||||
resourceManager = p_118895_
|
||||
profileManager = p_118896_
|
||||
changeset++
|
||||
dirtyUntil = System.nanoTime() + 1_000_000_000L
|
||||
super.apply(p_118894_, p_118895_, p_118896_)
|
||||
}
|
||||
|
||||
fun rebuildIfRequired(): Boolean {
|
||||
if (once && demandsRebuild && demandsRebuildAt <= System.nanoTime() && isClientThread()) {
|
||||
apply(prepare(resourceManager, profileManager), resourceManager, profileManager)
|
||||
}
|
||||
|
||||
return demandsRebuild
|
||||
}
|
||||
|
||||
fun speculateIfMinecraftEngineIsDumDum(): Boolean {
|
||||
return demandsRebuild || dirtyUntil >= System.nanoTime()
|
||||
}
|
||||
|
||||
public override fun getSprite(p_118902_: ResourceLocation): TextureAtlasSprite {
|
||||
if (!once) {
|
||||
throw IllegalStateException("Trying to get sprite too early")
|
||||
}
|
||||
|
||||
if (demandsRebuild && isClientThread()) {
|
||||
apply(prepare(resourceManager, profileManager), resourceManager, profileManager)
|
||||
}
|
||||
|
||||
rebuildIfRequired()
|
||||
return super.getSprite(p_118902_)
|
||||
}
|
||||
|
||||
fun queueRebuild() {
|
||||
if (!demandsRebuild) {
|
||||
demandsRebuild = true
|
||||
demandsRebuildAt = System.nanoTime() + 1_000_000_000L
|
||||
}
|
||||
}
|
||||
|
||||
override fun getResourcesToLoad(): Stream<ResourceLocation> {
|
||||
|
@ -5,6 +5,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.client.render.AtlasSkinElement
|
||||
import ru.dbotthepony.mc.otm.client.render.WidgetLocation
|
||||
import ru.dbotthepony.mc.otm.client.render.element
|
||||
import ru.dbotthepony.mc.otm.client.render.subElement
|
||||
|
||||
object ScrollBarConstants {
|
||||
const val WIDTH = 14f
|
||||
@ -12,21 +13,24 @@ object ScrollBarConstants {
|
||||
const val TEXTURE_WIDTH = 22f
|
||||
const val TEXTURE_HEIGHT = 68f
|
||||
|
||||
val TOP = WidgetLocation.SCROLL.element(0f, 45f, 14f, 2f, TEXTURE_WIDTH, TEXTURE_HEIGHT)
|
||||
val BODY = WidgetLocation.SCROLL.element(0f, 46f, 14f, 6f, TEXTURE_WIDTH, TEXTURE_HEIGHT)
|
||||
val BOTTOM = WidgetLocation.SCROLL.element(0f, 51f, 14f, 2f, TEXTURE_WIDTH, TEXTURE_HEIGHT)
|
||||
val BACKGROUND = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/background"), 14f, 8f)
|
||||
val BACKGROUND_SLIM = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/background"), 8f, 8f)
|
||||
|
||||
val BUTTON = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/idle"))
|
||||
val BUTTON_HOVER = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/hovered"))
|
||||
val BUTTON_PRESS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/pressed"))
|
||||
val BUTTON_DISABLED = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/disabled"))
|
||||
val TOP = BACKGROUND.subElement(height = 2f)
|
||||
val BODY = BACKGROUND.subElement(x = 2f, height = 6f)
|
||||
val BOTTOM = BACKGROUND.subElement(x = 7f, height = 2f)
|
||||
|
||||
val SLIM_TOP = WidgetLocation.SCROLL.element(14f, 45f, 8f, 2f, TEXTURE_WIDTH, TEXTURE_HEIGHT)
|
||||
val SLIM_BODY = WidgetLocation.SCROLL.element(14f, 46f, 8f, 6f, TEXTURE_WIDTH, TEXTURE_HEIGHT)
|
||||
val SLIM_BOTTOM = WidgetLocation.SCROLL.element(14f, 51f, 8f, 2f, TEXTURE_WIDTH, TEXTURE_HEIGHT)
|
||||
val BUTTON = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/idle"), 12f, 15f)
|
||||
val BUTTON_HOVER = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/hovered"), 12f, 15f)
|
||||
val BUTTON_PRESS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/pressed"), 12f, 15f)
|
||||
val BUTTON_DISABLED = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar/disabled"), 12f, 15f)
|
||||
|
||||
val SLIM_BUTTON = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/idle"))
|
||||
val SLIM_BUTTON_HOVER = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/hovered"))
|
||||
val SLIM_BUTTON_PRESS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/pressed"))
|
||||
val SLIM_BUTTON_DISABLED = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/disabled"))
|
||||
val SLIM_TOP = BACKGROUND_SLIM.subElement(height = 2f)
|
||||
val SLIM_BODY = BACKGROUND_SLIM.subElement(x = 2f, height = 6f)
|
||||
val SLIM_BOTTOM = BACKGROUND_SLIM.subElement(x = 7f, height = 2f)
|
||||
|
||||
val SLIM_BUTTON = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/idle"), 6f, 15f)
|
||||
val SLIM_BUTTON_HOVER = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/hovered"), 6f, 15f)
|
||||
val SLIM_BUTTON_PRESS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/pressed"), 6f, 15f)
|
||||
val SLIM_BUTTON_DISABLED = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "widgets/scrollbar_slim/disabled"), 6f, 15f)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user