Add tint override to texture packs
This commit is contained in:
@@ -4,6 +4,8 @@ package moe.nea.firmament.features.texturepack
|
||||
import net.minecraft.client.render.model.BakedModel
|
||||
|
||||
interface BakedModelExtra {
|
||||
fun getHeadModel_firmament(): BakedModel?
|
||||
var tintOverrides_firmament: TintOverrides?
|
||||
|
||||
fun getHeadModel_firmament(): BakedModel?
|
||||
fun setHeadModel_firmament(headModel: BakedModel?)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,14 @@ import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import moe.nea.firmament.features.texturepack.predicates.AndPredicate
|
||||
import moe.nea.firmament.features.texturepack.predicates.DisplayNamePredicate
|
||||
import moe.nea.firmament.features.texturepack.predicates.ExtraAttributesPredicate
|
||||
import moe.nea.firmament.features.texturepack.predicates.ItemPredicate
|
||||
import moe.nea.firmament.features.texturepack.predicates.LorePredicate
|
||||
import moe.nea.firmament.features.texturepack.predicates.NotPredicate
|
||||
import moe.nea.firmament.features.texturepack.predicates.OrPredicate
|
||||
import moe.nea.firmament.features.texturepack.predicates.PetPredicate
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
|
||||
@@ -7,4 +7,8 @@ interface JsonUnbakedModelFirmExtra {
|
||||
|
||||
fun setHeadModel_firmament(identifier: Identifier?)
|
||||
fun getHeadModel_firmament(): Identifier?
|
||||
|
||||
fun setTintOverrides_firmament(tintOverrides: TintOverrides?)
|
||||
fun getTintOverrides_firmament(): TintOverrides
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
package moe.nea.firmament.features.texturepack
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import moe.nea.firmament.util.filter.IteratorFilterSet
|
||||
|
||||
class ModelOverrideFilterSet(original: java.util.Set<Map.Entry<String, JsonElement>>) :
|
||||
IteratorFilterSet<Map.Entry<String, JsonElement>>(original) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createFilterSet(set: java.util.Set<*>): java.util.Set<*> {
|
||||
return ModelOverrideFilterSet(set as java.util.Set<Map.Entry<String, JsonElement>>) as java.util.Set<*>
|
||||
}
|
||||
}
|
||||
|
||||
override fun shouldKeepElement(element: Map.Entry<String, JsonElement>): Boolean {
|
||||
return !element.key.startsWith("firmament:")
|
||||
}
|
||||
}
|
||||
75
src/main/kotlin/features/texturepack/TintOverrides.kt
Normal file
75
src/main/kotlin/features/texturepack/TintOverrides.kt
Normal file
@@ -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<Int, TintOverride> = mapOf()
|
||||
) {
|
||||
val hasOverrides by lazy { layerMap.values.any { it !is Reset } }
|
||||
|
||||
companion object {
|
||||
val EMPTY = TintOverrides()
|
||||
private val threadLocal = object : ThreadLocal<TintOverrides>() {}
|
||||
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<Int, TintOverride>()
|
||||
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
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
|
||||
package moe.nea.firmament.features.texturepack
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
object AlwaysPredicate : FirmamentModelPredicate {
|
||||
@@ -1,8 +1,11 @@
|
||||
package moe.nea.firmament.features.texturepack
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import moe.nea.firmament.features.texturepack.CustomModelOverrideParser
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
class AndPredicate(val children: Array<FirmamentModelPredicate>) : FirmamentModelPredicate {
|
||||
@@ -15,7 +18,7 @@ class AndPredicate(val children: Array<FirmamentModelPredicate>) : FirmamentMode
|
||||
val children =
|
||||
(jsonElement as JsonArray)
|
||||
.flatMap {
|
||||
CustomModelOverrideParser.parsePredicates(it as JsonObject)
|
||||
CustomModelOverrideParser.parsePredicates(it as JsonObject)
|
||||
}
|
||||
.toTypedArray()
|
||||
return AndPredicate(children)
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
package moe.nea.firmament.features.texturepack
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||
import moe.nea.firmament.features.texturepack.StringMatcher
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NbtElement
|
||||
import net.minecraft.nbt.NbtString
|
||||
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
||||
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
||||
|
||||
data class DisplayNamePredicate(val stringMatcher: StringMatcher) : FirmamentModelPredicate {
|
||||
override fun test(stack: ItemStack): Boolean {
|
||||
@@ -1,10 +1,13 @@
|
||||
|
||||
package moe.nea.firmament.features.texturepack
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonPrimitive
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||
import moe.nea.firmament.features.texturepack.StringMatcher
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NbtByte
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
@@ -210,8 +213,8 @@ fun interface NbtMatcher {
|
||||
}
|
||||
|
||||
data class ExtraAttributesPredicate(
|
||||
val path: NbtPrism,
|
||||
val matcher: NbtMatcher,
|
||||
val path: NbtPrism,
|
||||
val matcher: NbtMatcher,
|
||||
) : FirmamentModelPredicate {
|
||||
|
||||
object Parser : FirmamentModelPredicateParser {
|
||||
@@ -1,8 +1,10 @@
|
||||
|
||||
package moe.nea.firmament.features.texturepack
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonPrimitive
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
@@ -1,7 +1,10 @@
|
||||
|
||||
package moe.nea.firmament.features.texturepack
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||
import moe.nea.firmament.features.texturepack.StringMatcher
|
||||
import net.minecraft.item.ItemStack
|
||||
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
|
||||
package moe.nea.firmament.features.texturepack
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import moe.nea.firmament.features.texturepack.CustomModelOverrideParser
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
class NotPredicate(val children: Array<FirmamentModelPredicate>) : FirmamentModelPredicate {
|
||||
@@ -1,4 +1,4 @@
|
||||
package moe.nea.firmament.features.texturepack
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonPrimitive
|
||||
@@ -1,9 +1,12 @@
|
||||
|
||||
package moe.nea.firmament.features.texturepack
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import moe.nea.firmament.features.texturepack.CustomModelOverrideParser
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
class OrPredicate(val children: Array<FirmamentModelPredicate>) : FirmamentModelPredicate {
|
||||
@@ -16,7 +19,7 @@ class OrPredicate(val children: Array<FirmamentModelPredicate>) : FirmamentModel
|
||||
val children =
|
||||
(jsonElement as JsonArray)
|
||||
.flatMap {
|
||||
CustomModelOverrideParser.parsePredicates(it as JsonObject)
|
||||
CustomModelOverrideParser.parsePredicates(it as JsonObject)
|
||||
}
|
||||
.toTypedArray()
|
||||
return OrPredicate(children)
|
||||
@@ -1,18 +1,22 @@
|
||||
|
||||
package moe.nea.firmament.features.texturepack
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||
import moe.nea.firmament.features.texturepack.RarityMatcher
|
||||
import moe.nea.firmament.features.texturepack.StringMatcher
|
||||
import net.minecraft.item.ItemStack
|
||||
import moe.nea.firmament.repo.ExpLadders
|
||||
import moe.nea.firmament.util.petData
|
||||
|
||||
class PetPredicate(
|
||||
val petId: StringMatcher?,
|
||||
val tier: RarityMatcher?,
|
||||
val exp: NumberMatcher?,
|
||||
val candyUsed: NumberMatcher?,
|
||||
val level: NumberMatcher?,
|
||||
data class PetPredicate(
|
||||
val petId: StringMatcher?,
|
||||
val tier: RarityMatcher?,
|
||||
val exp: NumberMatcher?,
|
||||
val candyUsed: NumberMatcher?,
|
||||
val level: NumberMatcher?,
|
||||
) : FirmamentModelPredicate {
|
||||
|
||||
override fun test(stack: ItemStack): Boolean {
|
||||
@@ -59,8 +63,4 @@ class PetPredicate(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return super.toString()
|
||||
}
|
||||
}
|
||||
@@ -9,13 +9,13 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
|
||||
import kotlinx.coroutines.launch
|
||||
import net.minecraft.client.MinecraftClient
|
||||
import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket
|
||||
import net.minecraft.text.Text
|
||||
import moe.nea.firmament.Firmament
|
||||
import moe.nea.firmament.Firmament.logger
|
||||
import moe.nea.firmament.events.ReloadRegistrationEvent
|
||||
import moe.nea.firmament.gui.config.ManagedConfig
|
||||
import moe.nea.firmament.util.MinecraftDispatcher
|
||||
import moe.nea.firmament.util.SkyblockId
|
||||
import moe.nea.firmament.util.tr
|
||||
|
||||
object RepoManager {
|
||||
object Config : ManagedConfig("repo", Category.META) {
|
||||
@@ -108,12 +108,13 @@ object RepoManager {
|
||||
try {
|
||||
ItemCache.ReloadProgressHud.reportProgress("Reloading from Disk",
|
||||
0,
|
||||
-1) // TODO: replace with a proper boundy bar
|
||||
-1) // TODO: replace with a proper bouncy bar
|
||||
ItemCache.ReloadProgressHud.isEnabled = true
|
||||
neuRepo.reload()
|
||||
} catch (exc: NEURepositoryException) {
|
||||
MinecraftClient.getInstance().player?.sendMessage(
|
||||
Text.literal("Failed to reload repository. This will result in some mod features not working.")
|
||||
tr("firmament.repo.reloadfail",
|
||||
"Failed to reload repository. This will result in some mod features not working.")
|
||||
)
|
||||
ItemCache.ReloadProgressHud.isEnabled = false
|
||||
exc.printStackTrace()
|
||||
|
||||
@@ -7,10 +7,24 @@ object ErrorUtil {
|
||||
Thread.currentThread().stackTrace.any { it.className.startsWith("org.junit.") } || Firmament.DEBUG
|
||||
}
|
||||
|
||||
inline fun softCheck(message: String, func: () -> Boolean) {
|
||||
if (!aggressiveErrors) return
|
||||
if (func()) return
|
||||
error(message)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE") // Suppressed since i want the logger to not pick up the ErrorUtil stack-frame
|
||||
inline fun softError(message: String) {
|
||||
if (aggressiveErrors) error(message)
|
||||
else Firmament.logger.error(message)
|
||||
}
|
||||
|
||||
inline fun <T : Any> notNullOr(nullable: T?, message: String, orElse: () -> T): T {
|
||||
if (nullable == null) {
|
||||
softError(message)
|
||||
return orElse()
|
||||
}
|
||||
return nullable
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
|
||||
package moe.nea.firmament.util.filter
|
||||
|
||||
abstract class IteratorFilterSet<K>(val original: java.util.Set<K>) : java.util.Set<K> by original {
|
||||
abstract fun shouldKeepElement(element: K): Boolean
|
||||
|
||||
override fun iterator(): MutableIterator<K> {
|
||||
val parentIterator = original.iterator()
|
||||
return object : MutableIterator<K> {
|
||||
var lastEntry: K? = null
|
||||
override fun hasNext(): Boolean {
|
||||
while (lastEntry == null) {
|
||||
if (!parentIterator.hasNext())
|
||||
break
|
||||
val element = parentIterator.next()
|
||||
if (!shouldKeepElement(element)) continue
|
||||
lastEntry = element
|
||||
}
|
||||
return lastEntry != null
|
||||
}
|
||||
|
||||
override fun next(): K {
|
||||
if (!hasNext()) throw NoSuchElementException()
|
||||
return lastEntry ?: throw NoSuchElementException()
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user