feat: Add generic component matcher
This commit is contained in:
@@ -17,6 +17,7 @@ import moe.nea.firmament.features.texturepack.predicates.AndPredicate
|
|||||||
import moe.nea.firmament.features.texturepack.predicates.CastPredicate
|
import moe.nea.firmament.features.texturepack.predicates.CastPredicate
|
||||||
import moe.nea.firmament.features.texturepack.predicates.DisplayNamePredicate
|
import moe.nea.firmament.features.texturepack.predicates.DisplayNamePredicate
|
||||||
import moe.nea.firmament.features.texturepack.predicates.ExtraAttributesPredicate
|
import moe.nea.firmament.features.texturepack.predicates.ExtraAttributesPredicate
|
||||||
|
import moe.nea.firmament.features.texturepack.predicates.GenericComponentPredicate
|
||||||
import moe.nea.firmament.features.texturepack.predicates.ItemPredicate
|
import moe.nea.firmament.features.texturepack.predicates.ItemPredicate
|
||||||
import moe.nea.firmament.features.texturepack.predicates.LorePredicate
|
import moe.nea.firmament.features.texturepack.predicates.LorePredicate
|
||||||
import moe.nea.firmament.features.texturepack.predicates.NotPredicate
|
import moe.nea.firmament.features.texturepack.predicates.NotPredicate
|
||||||
@@ -63,6 +64,7 @@ object CustomModelOverrideParser {
|
|||||||
registerPredicateParser("item", ItemPredicate.Parser)
|
registerPredicateParser("item", ItemPredicate.Parser)
|
||||||
registerPredicateParser("extra_attributes", ExtraAttributesPredicate.Parser)
|
registerPredicateParser("extra_attributes", ExtraAttributesPredicate.Parser)
|
||||||
registerPredicateParser("pet", PetPredicate.Parser)
|
registerPredicateParser("pet", PetPredicate.Parser)
|
||||||
|
registerPredicateParser("component", GenericComponentPredicate.Parser)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val neverPredicate = listOf(
|
private val neverPredicate = listOf(
|
||||||
|
|||||||
@@ -22,194 +22,200 @@ import net.minecraft.nbt.NbtString
|
|||||||
import moe.nea.firmament.util.extraAttributes
|
import moe.nea.firmament.util.extraAttributes
|
||||||
|
|
||||||
fun interface NbtMatcher {
|
fun interface NbtMatcher {
|
||||||
fun matches(nbt: NbtElement): Boolean
|
fun matches(nbt: NbtElement): Boolean
|
||||||
|
|
||||||
object Parser {
|
object Parser {
|
||||||
fun parse(jsonElement: JsonElement): NbtMatcher? {
|
fun parse(jsonElement: JsonElement): NbtMatcher? {
|
||||||
if (jsonElement is JsonPrimitive) {
|
if (jsonElement is JsonPrimitive) {
|
||||||
if (jsonElement.isString) {
|
if (jsonElement.isString) {
|
||||||
val string = jsonElement.asString
|
val string = jsonElement.asString
|
||||||
return MatchStringExact(string)
|
return MatchStringExact(string)
|
||||||
}
|
}
|
||||||
if (jsonElement.isNumber) {
|
if (jsonElement.isNumber) {
|
||||||
return MatchNumberExact(jsonElement.asLong) //TODO: parse generic number
|
return MatchNumberExact(jsonElement.asLong) // TODO: parse generic number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jsonElement is JsonObject) {
|
if (jsonElement is JsonObject) {
|
||||||
var encounteredParser: NbtMatcher? = null
|
var encounteredParser: NbtMatcher? = null
|
||||||
for (entry in ExclusiveParserType.entries) {
|
for (entry in ExclusiveParserType.entries) {
|
||||||
val data = jsonElement[entry.key] ?: continue
|
val data = jsonElement[entry.key] ?: continue
|
||||||
if (encounteredParser != null) {
|
if (encounteredParser != null) {
|
||||||
// TODO: warn
|
// TODO: warn
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
encounteredParser = entry.parse(data) ?: return null
|
encounteredParser = entry.parse(data) ?: return null
|
||||||
}
|
}
|
||||||
return encounteredParser
|
return encounteredParser
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class ExclusiveParserType(val key: String) {
|
enum class ExclusiveParserType(val key: String) {
|
||||||
STRING("string") {
|
STRING("string") {
|
||||||
override fun parse(element: JsonElement): NbtMatcher? {
|
override fun parse(element: JsonElement): NbtMatcher? {
|
||||||
return MatchString(StringMatcher.parse(element))
|
return MatchString(StringMatcher.parse(element))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
INT("int") {
|
INT("int") {
|
||||||
override fun parse(element: JsonElement): NbtMatcher? {
|
override fun parse(element: JsonElement): NbtMatcher? {
|
||||||
return parseGenericNumber(element,
|
return parseGenericNumber(
|
||||||
{ it.asInt },
|
element,
|
||||||
{ (it as? NbtInt)?.intValue() },
|
{ it.asInt },
|
||||||
{ a, b ->
|
{ (it as? NbtInt)?.intValue() },
|
||||||
if (a == b) Comparison.EQUAL
|
{ a, b ->
|
||||||
else if (a < b) Comparison.LESS_THAN
|
if (a == b) Comparison.EQUAL
|
||||||
else Comparison.GREATER
|
else if (a < b) Comparison.LESS_THAN
|
||||||
})
|
else Comparison.GREATER
|
||||||
}
|
})
|
||||||
},
|
}
|
||||||
FLOAT("float") {
|
},
|
||||||
override fun parse(element: JsonElement): NbtMatcher? {
|
FLOAT("float") {
|
||||||
return parseGenericNumber(element,
|
override fun parse(element: JsonElement): NbtMatcher? {
|
||||||
{ it.asFloat },
|
return parseGenericNumber(
|
||||||
{ (it as? NbtFloat)?.floatValue() },
|
element,
|
||||||
{ a, b ->
|
{ it.asFloat },
|
||||||
if (a == b) Comparison.EQUAL
|
{ (it as? NbtFloat)?.floatValue() },
|
||||||
else if (a < b) Comparison.LESS_THAN
|
{ a, b ->
|
||||||
else Comparison.GREATER
|
if (a == b) Comparison.EQUAL
|
||||||
})
|
else if (a < b) Comparison.LESS_THAN
|
||||||
}
|
else Comparison.GREATER
|
||||||
},
|
})
|
||||||
DOUBLE("double") {
|
}
|
||||||
override fun parse(element: JsonElement): NbtMatcher? {
|
},
|
||||||
return parseGenericNumber(element,
|
DOUBLE("double") {
|
||||||
{ it.asDouble },
|
override fun parse(element: JsonElement): NbtMatcher? {
|
||||||
{ (it as? NbtDouble)?.doubleValue() },
|
return parseGenericNumber(
|
||||||
{ a, b ->
|
element,
|
||||||
if (a == b) Comparison.EQUAL
|
{ it.asDouble },
|
||||||
else if (a < b) Comparison.LESS_THAN
|
{ (it as? NbtDouble)?.doubleValue() },
|
||||||
else Comparison.GREATER
|
{ a, b ->
|
||||||
})
|
if (a == b) Comparison.EQUAL
|
||||||
}
|
else if (a < b) Comparison.LESS_THAN
|
||||||
},
|
else Comparison.GREATER
|
||||||
LONG("long") {
|
})
|
||||||
override fun parse(element: JsonElement): NbtMatcher? {
|
}
|
||||||
return parseGenericNumber(element,
|
},
|
||||||
{ it.asLong },
|
LONG("long") {
|
||||||
{ (it as? NbtLong)?.longValue() },
|
override fun parse(element: JsonElement): NbtMatcher? {
|
||||||
{ a, b ->
|
return parseGenericNumber(
|
||||||
if (a == b) Comparison.EQUAL
|
element,
|
||||||
else if (a < b) Comparison.LESS_THAN
|
{ it.asLong },
|
||||||
else Comparison.GREATER
|
{ (it as? NbtLong)?.longValue() },
|
||||||
})
|
{ a, b ->
|
||||||
}
|
if (a == b) Comparison.EQUAL
|
||||||
},
|
else if (a < b) Comparison.LESS_THAN
|
||||||
SHORT("short") {
|
else Comparison.GREATER
|
||||||
override fun parse(element: JsonElement): NbtMatcher? {
|
})
|
||||||
return parseGenericNumber(element,
|
}
|
||||||
{ it.asShort },
|
},
|
||||||
{ (it as? NbtShort)?.shortValue() },
|
SHORT("short") {
|
||||||
{ a, b ->
|
override fun parse(element: JsonElement): NbtMatcher? {
|
||||||
if (a == b) Comparison.EQUAL
|
return parseGenericNumber(
|
||||||
else if (a < b) Comparison.LESS_THAN
|
element,
|
||||||
else Comparison.GREATER
|
{ it.asShort },
|
||||||
})
|
{ (it as? NbtShort)?.shortValue() },
|
||||||
}
|
{ a, b ->
|
||||||
},
|
if (a == b) Comparison.EQUAL
|
||||||
BYTE("byte") {
|
else if (a < b) Comparison.LESS_THAN
|
||||||
override fun parse(element: JsonElement): NbtMatcher? {
|
else Comparison.GREATER
|
||||||
return parseGenericNumber(element,
|
})
|
||||||
{ it.asByte },
|
}
|
||||||
{ (it as? NbtByte)?.byteValue() },
|
},
|
||||||
{ a, b ->
|
BYTE("byte") {
|
||||||
if (a == b) Comparison.EQUAL
|
override fun parse(element: JsonElement): NbtMatcher? {
|
||||||
else if (a < b) Comparison.LESS_THAN
|
return parseGenericNumber(
|
||||||
else Comparison.GREATER
|
element,
|
||||||
})
|
{ it.asByte },
|
||||||
}
|
{ (it as? NbtByte)?.byteValue() },
|
||||||
},
|
{ a, b ->
|
||||||
;
|
if (a == b) Comparison.EQUAL
|
||||||
|
else if (a < b) Comparison.LESS_THAN
|
||||||
|
else Comparison.GREATER
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
;
|
||||||
|
|
||||||
abstract fun parse(element: JsonElement): NbtMatcher?
|
abstract fun parse(element: JsonElement): NbtMatcher?
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Comparison {
|
enum class Comparison {
|
||||||
LESS_THAN, EQUAL, GREATER
|
LESS_THAN, EQUAL, GREATER
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T : Any> parseGenericNumber(
|
inline fun <T : Any> parseGenericNumber(
|
||||||
jsonElement: JsonElement,
|
jsonElement: JsonElement,
|
||||||
primitiveExtractor: (JsonPrimitive) -> T?,
|
primitiveExtractor: (JsonPrimitive) -> T?,
|
||||||
crossinline nbtExtractor: (NbtElement) -> T?,
|
crossinline nbtExtractor: (NbtElement) -> T?,
|
||||||
crossinline compare: (T, T) -> Comparison
|
crossinline compare: (T, T) -> Comparison
|
||||||
): NbtMatcher? {
|
): NbtMatcher? {
|
||||||
if (jsonElement is JsonPrimitive) {
|
if (jsonElement is JsonPrimitive) {
|
||||||
val expected = primitiveExtractor(jsonElement) ?: return null
|
val expected = primitiveExtractor(jsonElement) ?: return null
|
||||||
return NbtMatcher {
|
return NbtMatcher {
|
||||||
val actual = nbtExtractor(it) ?: return@NbtMatcher false
|
val actual = nbtExtractor(it) ?: return@NbtMatcher false
|
||||||
compare(actual, expected) == Comparison.EQUAL
|
compare(actual, expected) == Comparison.EQUAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jsonElement is JsonObject) {
|
if (jsonElement is JsonObject) {
|
||||||
val minElement = jsonElement.getAsJsonPrimitive("min")
|
val minElement = jsonElement.getAsJsonPrimitive("min")
|
||||||
val min = if (minElement != null) primitiveExtractor(minElement) ?: return null else null
|
val min = if (minElement != null) primitiveExtractor(minElement) ?: return null else null
|
||||||
val minExclusive = jsonElement.get("minExclusive")?.asBoolean ?: false
|
val minExclusive = jsonElement.get("minExclusive")?.asBoolean ?: false
|
||||||
val maxElement = jsonElement.getAsJsonPrimitive("max")
|
val maxElement = jsonElement.getAsJsonPrimitive("max")
|
||||||
val max = if (maxElement != null) primitiveExtractor(maxElement) ?: return null else null
|
val max = if (maxElement != null) primitiveExtractor(maxElement) ?: return null else null
|
||||||
val maxExclusive = jsonElement.get("maxExclusive")?.asBoolean ?: true
|
val maxExclusive = jsonElement.get("maxExclusive")?.asBoolean ?: true
|
||||||
if (min == null && max == null) return null
|
if (min == null && max == null) return null
|
||||||
return NbtMatcher {
|
return NbtMatcher {
|
||||||
val actual = nbtExtractor(it) ?: return@NbtMatcher false
|
val actual = nbtExtractor(it) ?: return@NbtMatcher false
|
||||||
if (max != null) {
|
if (max != null) {
|
||||||
val comp = compare(actual, max)
|
val comp = compare(actual, max)
|
||||||
if (comp == Comparison.GREATER) return@NbtMatcher false
|
if (comp == Comparison.GREATER) return@NbtMatcher false
|
||||||
if (comp == Comparison.EQUAL && maxExclusive) return@NbtMatcher false
|
if (comp == Comparison.EQUAL && maxExclusive) return@NbtMatcher false
|
||||||
}
|
}
|
||||||
if (min != null) {
|
if (min != null) {
|
||||||
val comp = compare(actual, min)
|
val comp = compare(actual, min)
|
||||||
if (comp == Comparison.LESS_THAN) return@NbtMatcher false
|
if (comp == Comparison.LESS_THAN) return@NbtMatcher false
|
||||||
if (comp == Comparison.EQUAL && minExclusive) return@NbtMatcher false
|
if (comp == Comparison.EQUAL && minExclusive) return@NbtMatcher false
|
||||||
}
|
}
|
||||||
return@NbtMatcher true
|
return@NbtMatcher true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MatchNumberExact(val number: Long) : NbtMatcher {
|
class MatchNumberExact(val number: Long) : NbtMatcher {
|
||||||
override fun matches(nbt: NbtElement): Boolean {
|
override fun matches(nbt: NbtElement): Boolean {
|
||||||
return when (nbt) {
|
return when (nbt) {
|
||||||
is NbtByte -> nbt.byteValue().toLong() == number
|
is NbtByte -> nbt.byteValue().toLong() == number
|
||||||
is NbtInt -> nbt.intValue().toLong() == number
|
is NbtInt -> nbt.intValue().toLong() == number
|
||||||
is NbtShort -> nbt.shortValue().toLong() == number
|
is NbtShort -> nbt.shortValue().toLong() == number
|
||||||
is NbtLong -> nbt.longValue().toLong() == number
|
is NbtLong -> nbt.longValue().toLong() == number
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MatchStringExact(val string: String) : NbtMatcher {
|
class MatchStringExact(val string: String) : NbtMatcher {
|
||||||
override fun matches(nbt: NbtElement): Boolean {
|
override fun matches(nbt: NbtElement): Boolean {
|
||||||
return nbt is NbtString && nbt.asString() == string
|
return nbt.asString() == string
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "MatchNbtStringExactly($string)"
|
return "MatchNbtStringExactly($string)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MatchString(val string: StringMatcher) : NbtMatcher {
|
class MatchString(val string: StringMatcher) : NbtMatcher {
|
||||||
override fun matches(nbt: NbtElement): Boolean {
|
override fun matches(nbt: NbtElement): Boolean {
|
||||||
return nbt is NbtString && string.matches(nbt.asString())
|
return nbt.asString().let(string::matches)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "MatchNbtString($string)"
|
return "MatchNbtString($string)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ExtraAttributesPredicate(
|
data class ExtraAttributesPredicate(
|
||||||
@@ -217,55 +223,63 @@ data class ExtraAttributesPredicate(
|
|||||||
val matcher: NbtMatcher,
|
val matcher: NbtMatcher,
|
||||||
) : FirmamentModelPredicate {
|
) : FirmamentModelPredicate {
|
||||||
|
|
||||||
object Parser : FirmamentModelPredicateParser {
|
object Parser : FirmamentModelPredicateParser {
|
||||||
override fun parse(jsonElement: JsonElement): FirmamentModelPredicate? {
|
override fun parse(jsonElement: JsonElement): FirmamentModelPredicate? {
|
||||||
if (jsonElement !is JsonObject) return null
|
if (jsonElement !is JsonObject) return null
|
||||||
val path = jsonElement.get("path") ?: return null
|
val path = jsonElement.get("path") ?: return null
|
||||||
val pathSegments = if (path is JsonArray) {
|
val prism = NbtPrism.fromElement(path) ?: return null
|
||||||
path.map { (it as JsonPrimitive).asString }
|
val matcher = NbtMatcher.Parser.parse(jsonElement.get("match") ?: jsonElement)
|
||||||
} else if (path is JsonPrimitive && path.isString) {
|
?: return null
|
||||||
path.asString.split(".")
|
return ExtraAttributesPredicate(prism, matcher)
|
||||||
} else return null
|
}
|
||||||
val matcher = NbtMatcher.Parser.parse(jsonElement.get("match") ?: jsonElement)
|
}
|
||||||
?: return null
|
|
||||||
return ExtraAttributesPredicate(NbtPrism(pathSegments), matcher)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun test(stack: ItemStack): Boolean {
|
override fun test(stack: ItemStack): Boolean {
|
||||||
return path.access(stack.extraAttributes)
|
return path.access(stack.extraAttributes)
|
||||||
.any { matcher.matches(it) }
|
.any { matcher.matches(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NbtPrism(val path: List<String>) {
|
class NbtPrism(val path: List<String>) {
|
||||||
override fun toString(): String {
|
companion object {
|
||||||
return "Prism($path)"
|
fun fromElement(path: JsonElement): NbtPrism? {
|
||||||
}
|
if (path is JsonArray) {
|
||||||
fun access(root: NbtElement): Collection<NbtElement> {
|
return NbtPrism(path.map { (it as JsonPrimitive).asString })
|
||||||
var rootSet = mutableListOf(root)
|
} else if (path is JsonPrimitive && path.isString) {
|
||||||
var switch = mutableListOf<NbtElement>()
|
return NbtPrism(path.asString.split("."))
|
||||||
for (pathSegment in path) {
|
}
|
||||||
if (pathSegment == ".") continue
|
return null
|
||||||
for (element in rootSet) {
|
}
|
||||||
if (element is NbtList) {
|
}
|
||||||
if (pathSegment == "*")
|
|
||||||
switch.addAll(element)
|
override fun toString(): String {
|
||||||
val index = pathSegment.toIntOrNull() ?: continue
|
return "Prism($path)"
|
||||||
if (index !in element.indices) continue
|
}
|
||||||
switch.add(element[index])
|
|
||||||
}
|
fun access(root: NbtElement): Collection<NbtElement> {
|
||||||
if (element is NbtCompound) {
|
var rootSet = mutableListOf(root)
|
||||||
if (pathSegment == "*")
|
var switch = mutableListOf<NbtElement>()
|
||||||
element.keys.mapTo(switch) { element.get(it)!! }
|
for (pathSegment in path) {
|
||||||
switch.add(element.get(pathSegment) ?: continue)
|
if (pathSegment == ".") continue
|
||||||
}
|
for (element in rootSet) {
|
||||||
}
|
if (element is NbtList) {
|
||||||
val temp = switch
|
if (pathSegment == "*")
|
||||||
switch = rootSet
|
switch.addAll(element)
|
||||||
rootSet = temp
|
val index = pathSegment.toIntOrNull() ?: continue
|
||||||
switch.clear()
|
if (index !in element.indices) continue
|
||||||
}
|
switch.add(element[index])
|
||||||
return rootSet
|
}
|
||||||
}
|
if (element is NbtCompound) {
|
||||||
|
if (pathSegment == "*")
|
||||||
|
element.keys.mapTo(switch) { element.get(it)!! }
|
||||||
|
switch.add(element.get(pathSegment) ?: continue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val temp = switch
|
||||||
|
switch = rootSet
|
||||||
|
rootSet = temp
|
||||||
|
switch.clear()
|
||||||
|
}
|
||||||
|
return rootSet
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package moe.nea.firmament.features.texturepack.predicates
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import com.mojang.serialization.Codec
|
||||||
|
import kotlin.jvm.optionals.getOrNull
|
||||||
|
import net.minecraft.component.ComponentType
|
||||||
|
import net.minecraft.component.type.NbtComponent
|
||||||
|
import net.minecraft.entity.LivingEntity
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.nbt.NbtOps
|
||||||
|
import net.minecraft.registry.RegistryKey
|
||||||
|
import net.minecraft.registry.RegistryKeys
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||||
|
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||||
|
import moe.nea.firmament.util.MC
|
||||||
|
|
||||||
|
data class GenericComponentPredicate<T>(
|
||||||
|
val componentType: ComponentType<T>,
|
||||||
|
val codec: Codec<T>,
|
||||||
|
val path: NbtPrism,
|
||||||
|
val matcher: NbtMatcher,
|
||||||
|
) : FirmamentModelPredicate {
|
||||||
|
constructor(componentType: ComponentType<T>, path: NbtPrism, matcher: NbtMatcher)
|
||||||
|
: this(componentType, componentType.codecOrThrow, path, matcher)
|
||||||
|
|
||||||
|
override fun test(stack: ItemStack, holder: LivingEntity?): Boolean {
|
||||||
|
val component = stack.get(componentType) ?: return false
|
||||||
|
// TODO: cache this
|
||||||
|
val nbt =
|
||||||
|
if (component is NbtComponent) component.nbt
|
||||||
|
else codec.encodeStart(NbtOps.INSTANCE, component)
|
||||||
|
.resultOrPartial().getOrNull() ?: return false
|
||||||
|
return path.access(nbt).any { matcher.matches(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
object Parser : FirmamentModelPredicateParser {
|
||||||
|
override fun parse(jsonElement: JsonElement): GenericComponentPredicate<*>? {
|
||||||
|
if (jsonElement !is JsonObject) return null
|
||||||
|
val path = jsonElement.get("path") ?: return null
|
||||||
|
val prism = NbtPrism.fromElement(path) ?: return null
|
||||||
|
val matcher = NbtMatcher.Parser.parse(jsonElement.get("match") ?: jsonElement)
|
||||||
|
?: return null
|
||||||
|
val component = MC.currentOrDefaultRegistries
|
||||||
|
.getOrThrow(RegistryKeys.DATA_COMPONENT_TYPE)
|
||||||
|
.getOrThrow(
|
||||||
|
RegistryKey.of(
|
||||||
|
RegistryKeys.DATA_COMPONENT_TYPE,
|
||||||
|
Identifier.of(jsonElement.get("component").asString)
|
||||||
|
)
|
||||||
|
).value()
|
||||||
|
return GenericComponentPredicate(component, prism, matcher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -167,6 +167,32 @@ Sub object match:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
|
||||||
|
You can match generic components similarly to [extra attributes](#extra-attributes). If you want to match an extra
|
||||||
|
attribute match directly using that, for better performance.
|
||||||
|
|
||||||
|
You can specify a `path` and match similar to extra attributes, but in addition you can also specify a `component`. This
|
||||||
|
variable is the identifier of a component type that will then be encoded to nbt and matched according to the `match`
|
||||||
|
using a [nbt matcher](#nbt-matcher).
|
||||||
|
|
||||||
|
```json5
|
||||||
|
"firmament:component": {
|
||||||
|
"path": "rgb",
|
||||||
|
"component": "minecraft:dyed_color",
|
||||||
|
"int": 255
|
||||||
|
}
|
||||||
|
// Alternatively
|
||||||
|
"firmament:component": {
|
||||||
|
"path": "rgb",
|
||||||
|
"component": "minecraft:dyed_color",
|
||||||
|
"match": {
|
||||||
|
"int": 255
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Pet Data
|
#### Pet Data
|
||||||
|
|
||||||
Filter by pet information. While you can already filter by the skyblock id for pet type and tier, this allows you to
|
Filter by pet information. While you can already filter by the skyblock id for pet type and tier, this allows you to
|
||||||
|
|||||||
Reference in New Issue
Block a user