From 8b410fbdf2cffb3ceaa51bbea150f5165848bc37 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Fri, 1 Nov 2024 23:00:53 +0100 Subject: Add tint override to texture packs --- .../kotlin/features/texturepack/TintOverrides.kt | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/main/kotlin/features/texturepack/TintOverrides.kt (limited to 'src/main/kotlin/features/texturepack/TintOverrides.kt') diff --git a/src/main/kotlin/features/texturepack/TintOverrides.kt b/src/main/kotlin/features/texturepack/TintOverrides.kt new file mode 100644 index 0000000..8006db8 --- /dev/null +++ b/src/main/kotlin/features/texturepack/TintOverrides.kt @@ -0,0 +1,75 @@ +package moe.nea.firmament.features.texturepack + +import com.google.gson.JsonObject +import com.google.gson.JsonPrimitive +import moe.nea.firmament.util.ErrorUtil +import moe.nea.firmament.util.assertNotNullOr + +data class TintOverrides( + val layerMap: Map = mapOf() +) { + val hasOverrides by lazy { layerMap.values.any { it !is Reset } } + + companion object { + val EMPTY = TintOverrides() + private val threadLocal = object : ThreadLocal() {} + fun enter(overrides: TintOverrides?) { + ErrorUtil.softCheck("Double entered tintOverrides") { + threadLocal.get() == null + } + threadLocal.set(overrides ?: EMPTY) + } + + fun exit(overrides: TintOverrides?) { + ErrorUtil.softCheck("Exited with non matching enter tintOverrides") { + threadLocal.get() == (overrides ?: EMPTY) + } + threadLocal.remove() + } + + fun getCurrentOverrides() = + assertNotNullOr(threadLocal.get(), "Got current tintOverrides without entering") { EMPTY } + + fun parse(jsonObject: JsonObject): TintOverrides { + val map = mutableMapOf() + for ((key, value) in jsonObject.entrySet()) { + val layerIndex = + ErrorUtil.notNullOr(key.toIntOrNull(), + "Unknown layer index $value. Should be integer") { continue } + if (value.isJsonNull) { + map[layerIndex] = Reset + continue + } + val override = (value as? JsonPrimitive) + ?.takeIf(JsonPrimitive::isNumber) + ?.asInt + ?.let(::Fixed) + if (override == null) { + ErrorUtil.softError("Invalid tint override for a layer: $value") + continue + } + map[layerIndex] = override + } + return TintOverrides(map) + } + } + + fun mergeWithParent(parent: TintOverrides): TintOverrides { + val mergedMap = parent.layerMap.toMutableMap() + mergedMap.putAll(this.layerMap) + return TintOverrides(mergedMap) + } + + fun hasOverrides(): Boolean = hasOverrides + fun getOverride(tintIndex: Int): Int? { + return when (val tint = layerMap[tintIndex]) { + is Reset -> null + is Fixed -> tint.color + null -> null + } + } + + sealed interface TintOverride + data object Reset : TintOverride + data class Fixed(val color: Int) : TintOverride +} -- cgit