package net.minecraft.advancements; import com.google.common.collect.Sets; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.function.Predicate; import net.minecraft.network.FriendlyByteBuf; public record AdvancementRequirements(List> requirements) { public static final Codec CODEC = Codec.STRING .listOf() .listOf() .xmap(AdvancementRequirements::new, AdvancementRequirements::requirements); public static final AdvancementRequirements EMPTY = new AdvancementRequirements(List.of()); public AdvancementRequirements(FriendlyByteBuf buffer) { this(buffer.readList(friendlyByteBuf -> friendlyByteBuf.readList(FriendlyByteBuf::readUtf))); } public void write(FriendlyByteBuf buffer) { buffer.writeCollection(this.requirements, (friendlyByteBuf, list) -> friendlyByteBuf.writeCollection(list, FriendlyByteBuf::writeUtf)); } public static AdvancementRequirements allOf(Collection requirements) { return new AdvancementRequirements(requirements.stream().map(List::of).toList()); } public static AdvancementRequirements anyOf(Collection criteria) { return new AdvancementRequirements(List.of(List.copyOf(criteria))); } public int size() { return this.requirements.size(); } public boolean test(Predicate predicate) { if (this.requirements.isEmpty()) { return false; } else { for (List list : this.requirements) { if (!anyMatch(list, predicate)) { return false; } } return true; } } public int count(Predicate filter) { int i = 0; for (List list : this.requirements) { if (anyMatch(list, filter)) { i++; } } return i; } private static boolean anyMatch(List requirements, Predicate predicate) { for (String string : requirements) { if (predicate.test(string)) { return true; } } return false; } public DataResult validate(Set requirements) { Set set = new ObjectOpenHashSet<>(); for (List list : this.requirements) { if (list.isEmpty() && requirements.isEmpty()) { return DataResult.error(() -> "Requirement entry cannot be empty"); } set.addAll(list); } if (!requirements.equals(set)) { Set set2 = Sets.difference(requirements, set); Set set3 = Sets.difference(set, requirements); return DataResult.error(() -> "Advancement completion requirements did not exactly match specified criteria. Missing: " + set2 + ". Unknown: " + set3); } else { return DataResult.success(this); } } public boolean isEmpty() { return this.requirements.isEmpty(); } public String toString() { return this.requirements.toString(); } public Set names() { Set set = new ObjectOpenHashSet<>(); for (List list : this.requirements) { set.addAll(list); } return set; } public interface Strategy { AdvancementRequirements.Strategy AND = AdvancementRequirements::allOf; AdvancementRequirements.Strategy OR = AdvancementRequirements::anyOf; AdvancementRequirements create(Collection collection); } }