367 lines
15 KiB
Java
367 lines
15 KiB
Java
package net.minecraft.advancements;
|
|
|
|
import org.apache.commons.lang3.ArrayUtils;
|
|
import com.google.gson.JsonSyntaxException;
|
|
import net.minecraft.util.GsonHelper;
|
|
import com.google.gson.JsonDeserializationContext;
|
|
import net.minecraft.network.FriendlyByteBuf;
|
|
import java.util.Iterator;
|
|
import com.google.gson.JsonArray;
|
|
import com.google.gson.JsonElement;
|
|
import com.google.gson.JsonObject;
|
|
import java.util.function.Consumer;
|
|
import java.util.Collection;
|
|
import java.util.function.Function;
|
|
import net.minecraft.world.level.ItemLike;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import com.google.common.collect.Maps;
|
|
import net.minecraft.network.chat.Style;
|
|
import java.util.Arrays;
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.network.chat.HoverEvent;
|
|
import net.minecraft.network.chat.TextComponent;
|
|
import com.google.common.collect.ImmutableMap;
|
|
import com.google.common.collect.Sets;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.network.chat.Component;
|
|
import java.util.Set;
|
|
import java.util.Map;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
|
|
public class Advancement {
|
|
private final Advancement parent;
|
|
private final DisplayInfo display;
|
|
private final AdvancementRewards rewards;
|
|
private final ResourceLocation id;
|
|
private final Map<String, Criterion> criteria;
|
|
private final String[][] requirements;
|
|
private final Set<Advancement> children;
|
|
private final Component chatComponent;
|
|
|
|
public Advancement(final ResourceLocation sm, @Nullable final Advancement u, @Nullable final DisplayInfo ad, final AdvancementRewards x, final Map<String, Criterion> map, final String[][] arr) {
|
|
this.children = Sets.newLinkedHashSet();
|
|
this.id = sm;
|
|
this.display = ad;
|
|
this.criteria = ImmutableMap.copyOf(map);
|
|
this.parent = u;
|
|
this.rewards = x;
|
|
this.requirements = arr;
|
|
if (u != null) {
|
|
u.addChild(this);
|
|
}
|
|
if (ad == null) {
|
|
this.chatComponent = new TextComponent(sm.toString());
|
|
}
|
|
else {
|
|
final Component lf8 = ad.getTitle();
|
|
final ChatFormatting g9 = ad.getFrame().getChatColor();
|
|
final Component lf9 = lf8.deepCopy().withStyle(g9).append("\n").append(ad.getDescription());
|
|
final Component lf10 = lf8.deepCopy().withStyle(ln -> ln.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, lf9)));
|
|
this.chatComponent = new TextComponent("[").append(lf10).append("]").withStyle(g9);
|
|
}
|
|
}
|
|
|
|
public Builder deconstruct() {
|
|
return new Builder((this.parent == null) ? null : this.parent.getId(), this.display, this.rewards, (Map)this.criteria, this.requirements);
|
|
}
|
|
|
|
@Nullable
|
|
public Advancement getParent() {
|
|
return this.parent;
|
|
}
|
|
|
|
@Nullable
|
|
public DisplayInfo getDisplay() {
|
|
return this.display;
|
|
}
|
|
|
|
public AdvancementRewards getRewards() {
|
|
return this.rewards;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "SimpleAdvancement{id=" + this.getId() + ", parent=" + ((this.parent == null) ? "null" : this.parent.getId()) + ", display=" + this.display + ", rewards=" + this.rewards + ", criteria=" + this.criteria + ", requirements=" + Arrays.deepToString(this.requirements) + '}';
|
|
}
|
|
|
|
public Iterable<Advancement> getChildren() {
|
|
return this.children;
|
|
}
|
|
|
|
public Map<String, Criterion> getCriteria() {
|
|
return this.criteria;
|
|
}
|
|
|
|
public int getMaxCriteraRequired() {
|
|
return this.requirements.length;
|
|
}
|
|
|
|
public void addChild(final Advancement u) {
|
|
this.children.add(u);
|
|
}
|
|
|
|
public ResourceLocation getId() {
|
|
return this.id;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(final Object object) {
|
|
if (this == object) {
|
|
return true;
|
|
}
|
|
if (!(object instanceof Advancement)) {
|
|
return false;
|
|
}
|
|
final Advancement u3 = (Advancement)object;
|
|
return this.id.equals(u3.id);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return this.id.hashCode();
|
|
}
|
|
|
|
public String[][] getRequirements() {
|
|
return this.requirements;
|
|
}
|
|
|
|
public Component getChatComponent() {
|
|
return this.chatComponent;
|
|
}
|
|
|
|
public static class Builder {
|
|
private ResourceLocation parentId;
|
|
private Advancement parent;
|
|
private DisplayInfo display;
|
|
private AdvancementRewards rewards;
|
|
private Map<String, Criterion> criteria;
|
|
private String[][] requirements;
|
|
private RequirementsStrategy requirementsStrategy;
|
|
|
|
private Builder(@Nullable final ResourceLocation sm, @Nullable final DisplayInfo ad, final AdvancementRewards x, final Map<String, Criterion> map, final String[][] arr) {
|
|
this.rewards = AdvancementRewards.EMPTY;
|
|
this.criteria = Maps.newLinkedHashMap();
|
|
this.requirementsStrategy = RequirementsStrategy.AND;
|
|
this.parentId = sm;
|
|
this.display = ad;
|
|
this.rewards = x;
|
|
this.criteria = map;
|
|
this.requirements = arr;
|
|
}
|
|
|
|
private Builder() {
|
|
this.rewards = AdvancementRewards.EMPTY;
|
|
this.criteria = Maps.newLinkedHashMap();
|
|
this.requirementsStrategy = RequirementsStrategy.AND;
|
|
}
|
|
|
|
public static Builder advancement() {
|
|
return new Builder();
|
|
}
|
|
|
|
public Builder parent(final Advancement u) {
|
|
this.parent = u;
|
|
return this;
|
|
}
|
|
|
|
public Builder parent(final ResourceLocation sm) {
|
|
this.parentId = sm;
|
|
return this;
|
|
}
|
|
|
|
public Builder display(final ItemStack ben, final Component lf2, final Component lf3, @Nullable final ResourceLocation sm, final FrameType ae, final boolean boolean6, final boolean boolean7, final boolean boolean8) {
|
|
return this.display(new DisplayInfo(ben, lf2, lf3, sm, ae, boolean6, boolean7, boolean8));
|
|
}
|
|
|
|
public Builder display(final ItemLike bjv, final Component lf2, final Component lf3, @Nullable final ResourceLocation sm, final FrameType ae, final boolean boolean6, final boolean boolean7, final boolean boolean8) {
|
|
return this.display(new DisplayInfo(new ItemStack(bjv.asItem()), lf2, lf3, sm, ae, boolean6, boolean7, boolean8));
|
|
}
|
|
|
|
public Builder display(final DisplayInfo ad) {
|
|
this.display = ad;
|
|
return this;
|
|
}
|
|
|
|
public Builder rewards(final AdvancementRewards.Builder a) {
|
|
return this.rewards(a.build());
|
|
}
|
|
|
|
public Builder rewards(final AdvancementRewards x) {
|
|
this.rewards = x;
|
|
return this;
|
|
}
|
|
|
|
public Builder addCriterion(final String string, final CriterionTriggerInstance ac) {
|
|
return this.addCriterion(string, new Criterion(ac));
|
|
}
|
|
|
|
public Builder addCriterion(final String string, final Criterion z) {
|
|
if (this.criteria.containsKey(string)) {
|
|
throw new IllegalArgumentException("Duplicate criterion " + string);
|
|
}
|
|
this.criteria.put(string, z);
|
|
return this;
|
|
}
|
|
|
|
public Builder requirements(final RequirementsStrategy af) {
|
|
this.requirementsStrategy = af;
|
|
return this;
|
|
}
|
|
|
|
public boolean canBuild(final Function<ResourceLocation, Advancement> function) {
|
|
if (this.parentId == null) {
|
|
return true;
|
|
}
|
|
if (this.parent == null) {
|
|
this.parent = function.apply(this.parentId);
|
|
}
|
|
return this.parent != null;
|
|
}
|
|
|
|
public Advancement build(final ResourceLocation sm) {
|
|
if (!this.canBuild(sm -> null)) {
|
|
throw new IllegalStateException("Tried to build incomplete advancement!");
|
|
}
|
|
if (this.requirements == null) {
|
|
this.requirements = this.requirementsStrategy.createRequirements(this.criteria.keySet());
|
|
}
|
|
return new Advancement(sm, this.parent, this.display, this.rewards, this.criteria, this.requirements);
|
|
}
|
|
|
|
public Advancement save(final Consumer<Advancement> consumer, final String string) {
|
|
final Advancement u4 = this.build(new ResourceLocation(string));
|
|
consumer.accept(u4);
|
|
return u4;
|
|
}
|
|
|
|
public JsonObject serializeToJson() {
|
|
if (this.requirements == null) {
|
|
this.requirements = this.requirementsStrategy.createRequirements(this.criteria.keySet());
|
|
}
|
|
final JsonObject jsonObject2 = new JsonObject();
|
|
if (this.parent != null) {
|
|
jsonObject2.addProperty("parent", this.parent.getId().toString());
|
|
}
|
|
else if (this.parentId != null) {
|
|
jsonObject2.addProperty("parent", this.parentId.toString());
|
|
}
|
|
if (this.display != null) {
|
|
jsonObject2.add("display", this.display.serializeToJson());
|
|
}
|
|
jsonObject2.add("rewards", this.rewards.serializeToJson());
|
|
final JsonObject jsonObject3 = new JsonObject();
|
|
for (final Map.Entry<String, Criterion> entry5 : this.criteria.entrySet()) {
|
|
jsonObject3.add(entry5.getKey(), entry5.getValue().serializeToJson());
|
|
}
|
|
jsonObject2.add("criteria", jsonObject3);
|
|
final JsonArray jsonArray4 = new JsonArray();
|
|
for (final String[] arr8 : this.requirements) {
|
|
final JsonArray jsonArray5 = new JsonArray();
|
|
for (final String string13 : arr8) {
|
|
jsonArray5.add(string13);
|
|
}
|
|
jsonArray4.add(jsonArray5);
|
|
}
|
|
jsonObject2.add("requirements", jsonArray4);
|
|
return jsonObject2;
|
|
}
|
|
|
|
public void serializeToNetwork(final FriendlyByteBuf kv) {
|
|
if (this.parentId == null) {
|
|
kv.writeBoolean(false);
|
|
}
|
|
else {
|
|
kv.writeBoolean(true);
|
|
kv.writeResourceLocation(this.parentId);
|
|
}
|
|
if (this.display == null) {
|
|
kv.writeBoolean(false);
|
|
}
|
|
else {
|
|
kv.writeBoolean(true);
|
|
this.display.serializeToNetwork(kv);
|
|
}
|
|
Criterion.serializeToNetwork(this.criteria, kv);
|
|
kv.writeVarInt(this.requirements.length);
|
|
for (final String[] arr6 : this.requirements) {
|
|
kv.writeVarInt(arr6.length);
|
|
for (final String string10 : arr6) {
|
|
kv.writeUtf(string10);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Task Advancement{parentId=" + this.parentId + ", display=" + this.display + ", rewards=" + this.rewards + ", criteria=" + this.criteria + ", requirements=" + Arrays.deepToString(this.requirements) + '}';
|
|
}
|
|
|
|
public static Builder fromJson(final JsonObject jsonObject, final JsonDeserializationContext jsonDeserializationContext) {
|
|
final ResourceLocation sm3 = jsonObject.has("parent") ? new ResourceLocation(GsonHelper.getAsString(jsonObject, "parent")) : null;
|
|
final DisplayInfo ad4 = jsonObject.has("display") ? DisplayInfo.fromJson(GsonHelper.getAsJsonObject(jsonObject, "display"), jsonDeserializationContext) : null;
|
|
final AdvancementRewards x5 = GsonHelper.<AdvancementRewards>getAsObject(jsonObject, "rewards", AdvancementRewards.EMPTY, jsonDeserializationContext, AdvancementRewards.class);
|
|
final Map<String, Criterion> map6 = Criterion.criteriaFromJson(GsonHelper.getAsJsonObject(jsonObject, "criteria"), jsonDeserializationContext);
|
|
if (map6.isEmpty()) {
|
|
throw new JsonSyntaxException("Advancement criteria cannot be empty");
|
|
}
|
|
final JsonArray jsonArray7 = GsonHelper.getAsJsonArray(jsonObject, "requirements", new JsonArray());
|
|
String[][] arr8 = new String[jsonArray7.size()][];
|
|
for (int integer9 = 0; integer9 < jsonArray7.size(); ++integer9) {
|
|
final JsonArray jsonArray8 = GsonHelper.convertToJsonArray(jsonArray7.get(integer9), "requirements[" + integer9 + "]");
|
|
arr8[integer9] = new String[jsonArray8.size()];
|
|
for (int integer10 = 0; integer10 < jsonArray8.size(); ++integer10) {
|
|
arr8[integer9][integer10] = GsonHelper.convertToString(jsonArray8.get(integer10), "requirements[" + integer9 + "][" + integer10 + "]");
|
|
}
|
|
}
|
|
if (arr8.length == 0) {
|
|
arr8 = new String[map6.size()][];
|
|
int integer9 = 0;
|
|
for (final String string11 : map6.keySet()) {
|
|
arr8[integer9++] = new String[] { string11 };
|
|
}
|
|
}
|
|
for (final String[] arr9 : arr8) {
|
|
if (arr9.length == 0 && map6.isEmpty()) {
|
|
throw new JsonSyntaxException("Requirement entry cannot be empty");
|
|
}
|
|
for (final String string12 : arr9) {
|
|
if (!map6.containsKey(string12)) {
|
|
throw new JsonSyntaxException("Unknown required criterion '" + string12 + "'");
|
|
}
|
|
}
|
|
}
|
|
for (final String string13 : map6.keySet()) {
|
|
boolean boolean11 = false;
|
|
for (final String[] arr10 : arr8) {
|
|
if (ArrayUtils.contains((Object[])arr10, string13)) {
|
|
boolean11 = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!boolean11) {
|
|
throw new JsonSyntaxException("Criterion '" + string13 + "' isn't a requirement for completion. This isn't supported behaviour, all criteria must be required.");
|
|
}
|
|
}
|
|
return new Builder(sm3, ad4, x5, map6, arr8);
|
|
}
|
|
|
|
public static Builder fromNetwork(final FriendlyByteBuf kv) {
|
|
final ResourceLocation sm2 = kv.readBoolean() ? kv.readResourceLocation() : null;
|
|
final DisplayInfo ad3 = kv.readBoolean() ? DisplayInfo.fromNetwork(kv) : null;
|
|
final Map<String, Criterion> map4 = Criterion.criteriaFromNetwork(kv);
|
|
final String[][] arr5 = new String[kv.readVarInt()][];
|
|
for (int integer6 = 0; integer6 < arr5.length; ++integer6) {
|
|
arr5[integer6] = new String[kv.readVarInt()];
|
|
for (int integer7 = 0; integer7 < arr5[integer6].length; ++integer7) {
|
|
arr5[integer6][integer7] = kv.readUtf(32767);
|
|
}
|
|
}
|
|
return new Builder(sm2, ad3, AdvancementRewards.EMPTY, map4, arr5);
|
|
}
|
|
|
|
public Map<String, Criterion> getCriteria() {
|
|
return this.criteria;
|
|
}
|
|
}
|
|
}
|