Backport MCriterionTrigger to 1.20.1
This commit is contained in:
parent
5453c8c793
commit
520112df77
@ -17,6 +17,7 @@ import net.minecraft.advancements.CriterionTriggerInstance
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||
import net.minecraft.advancements.critereon.DeserializationContext
|
||||
import net.minecraft.advancements.critereon.EntityPredicate
|
||||
import net.minecraft.advancements.critereon.SerializationContext
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.PlayerAdvancements
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
@ -30,6 +31,10 @@ import java.util.function.Predicate
|
||||
// allows to support both 1.20.1 and 1.20.2 with ease
|
||||
// and has slightly less memory footprint than vanilla SimpleCriterionTrigger
|
||||
abstract class MCriterionTrigger<T : MCriterionTrigger<T>.AbstractInstance>(val id: ResourceLocation) : CriterionTrigger<T> {
|
||||
override fun getId(): ResourceLocation {
|
||||
return id
|
||||
}
|
||||
|
||||
private val listeners = Reference2ObjectOpenHashMap<PlayerAdvancements, ObjectOpenHashSet<CriterionTrigger.Listener<T>>>()
|
||||
|
||||
override fun addPlayerListener(advancements: PlayerAdvancements, listener: CriterionTrigger.Listener<T>) {
|
||||
@ -62,16 +67,25 @@ abstract class MCriterionTrigger<T : MCriterionTrigger<T>.AbstractInstance>(val
|
||||
val context = EntityPredicate.createContext(player, player)
|
||||
|
||||
listeners.iterator()
|
||||
.filter { predicate.test(it.trigger) && it.trigger.playerPredicate.map { it.matches(context) }.orElse(true) }
|
||||
.filter { predicate.test(it.triggerInstance) && it.triggerInstance.playerPredicate.map { it.matches(context) }.orElse(true) }
|
||||
.toImmutableList()
|
||||
.forEach { it.run(advancements) }
|
||||
}
|
||||
|
||||
abstract inner class AbstractInstance(val playerPredicate: Optional<ContextAwarePredicate>) : CriterionTriggerInstance {
|
||||
fun criterion() = Criterion(this@MCriterionTrigger, this as T)
|
||||
fun criterion() = this as T
|
||||
|
||||
final override fun serializeToJson(): JsonObject {
|
||||
return codec.toJsonStrict(this as T) as JsonObject
|
||||
override fun getCriterion(): ResourceLocation {
|
||||
return id
|
||||
}
|
||||
|
||||
final override fun serializeToJson(context: SerializationContext): JsonObject {
|
||||
return try {
|
||||
serializationContext.get().addLast(context)
|
||||
codec.toJsonStrict(this as T) as JsonObject
|
||||
} finally {
|
||||
serializationContext.get().removeLast()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,17 +96,23 @@ abstract class MCriterionTrigger<T : MCriterionTrigger<T>.AbstractInstance>(val
|
||||
}
|
||||
}
|
||||
|
||||
protected val serializationContext = object : ThreadLocal<ArrayDeque<SerializationContext>>() {
|
||||
override fun initialValue(): ArrayDeque<SerializationContext> {
|
||||
return ArrayDeque()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
protected val predicateCodec: Codec<ContextAwarePredicate> = object : Codec<ContextAwarePredicate> {
|
||||
override fun <T : Any?> encode(input: ContextAwarePredicate, ops: DynamicOps<T>, prefix: T): DataResult<T> {
|
||||
return DataResult.success(JsonOps.INSTANCE.convertTo(ops, input.toJson()))
|
||||
return DataResult.success(JsonOps.INSTANCE.convertTo(ops, input.toJson(serializationContext.get().lastOrNull() ?: return DataResult.error { "Not serializing trigger instance" })))
|
||||
}
|
||||
|
||||
override fun <T : Any?> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<ContextAwarePredicate, T>> {
|
||||
val context = deserializationContext.get().lastOrNull() ?: return DataResult.error { "Not current deserializing trigger instance" }
|
||||
|
||||
return try {
|
||||
DataResult.success(Pair.of(EntityPredicate.fromJson(JsonObject().also { it["a"] = ops.convertTo(JsonOps.INSTANCE, input) }, "a", context).get(), ops.empty()))
|
||||
DataResult.success(Pair.of(EntityPredicate.fromJson(JsonObject().also { it["a"] = ops.convertTo(JsonOps.INSTANCE, input) }, "a", context), ops.empty()))
|
||||
} catch (err: Exception) {
|
||||
DataResult.error { "Failed to deserialize ContextAwarePredicate: " + err.message }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user