File size: 10,066 Bytes
d46f4a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
package net.minecraft.advancements;

import com.google.common.collect.ImmutableMap;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.mojang.serialization.codecs.RecordCodecBuilder.Instance;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import net.minecraft.ChatFormatting;
import net.minecraft.advancements.critereon.CriterionValidator;
import net.minecraft.core.HolderGetter;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.Style;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;

public record Advancement(
    Optional<ResourceLocation> parent,
    Optional<DisplayInfo> display,
    AdvancementRewards rewards,
    Map<String, Criterion<?>> criteria,
    AdvancementRequirements requirements,
    boolean sendsTelemetryEvent,
    Optional<Component> name
) {
    private static final Codec<Map<String, Criterion<?>>> CRITERIA_CODEC = Codec.unboundedMap(Codec.STRING, Criterion.CODEC)
        .validate(p_308091_ -> p_308091_.isEmpty() ? DataResult.error(() -> "Advancement criteria cannot be empty") : DataResult.success(p_308091_));
    public static final Codec<Advancement> CODEC = RecordCodecBuilder.<Advancement>create(
            p_325179_ -> p_325179_.group(
                        ResourceLocation.CODEC.optionalFieldOf("parent").forGetter(Advancement::parent),
                        DisplayInfo.CODEC.optionalFieldOf("display").forGetter(Advancement::display),
                        AdvancementRewards.CODEC.optionalFieldOf("rewards", AdvancementRewards.EMPTY).forGetter(Advancement::rewards),
                        CRITERIA_CODEC.fieldOf("criteria").forGetter(Advancement::criteria),
                        AdvancementRequirements.CODEC.optionalFieldOf("requirements").forGetter(p_308099_ -> Optional.of(p_308099_.requirements())),
                        Codec.BOOL.optionalFieldOf("sends_telemetry_event", Boolean.valueOf(false)).forGetter(Advancement::sendsTelemetryEvent)
                    )
                    .apply(p_325179_, (p_308085_, p_308086_, p_308087_, p_308088_, p_308089_, p_308090_) -> {
                        AdvancementRequirements advancementrequirements = p_308089_.orElseGet(() -> AdvancementRequirements.allOf(p_308088_.keySet()));
                        return new Advancement(p_308085_, p_308086_, p_308087_, p_308088_, advancementrequirements, p_308090_);
                    })
        )
        .validate(Advancement::validate);
    public static final StreamCodec<RegistryFriendlyByteBuf, Advancement> STREAM_CODEC = StreamCodec.ofMember(Advancement::write, Advancement::read);

    public Advancement(
        Optional<ResourceLocation> p_299284_,
        Optional<DisplayInfo> p_301017_,
        AdvancementRewards p_286389_,
        Map<String, Criterion<?>> p_286635_,
        AdvancementRequirements p_300504_,
        boolean p_286478_
    ) {
        this(p_299284_, p_301017_, p_286389_, Map.copyOf(p_286635_), p_300504_, p_286478_, p_301017_.map(Advancement::decorateName));
    }

    private static DataResult<Advancement> validate(Advancement p_312373_) {
        return p_312373_.requirements().validate(p_312373_.criteria().keySet()).map(p_308094_ -> p_312373_);
    }

    private static Component decorateName(DisplayInfo p_300038_) {
        Component component = p_300038_.getTitle();
        ChatFormatting chatformatting = p_300038_.getType().getChatColor();
        Component component1 = ComponentUtils.mergeStyles(component.copy(), Style.EMPTY.withColor(chatformatting))
            .append("\n")
            .append(p_300038_.getDescription());
        Component component2 = component.copy().withStyle(p_138316_ -> p_138316_.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, component1)));
        return ComponentUtils.wrapInSquareBrackets(component2).withStyle(chatformatting);
    }

    public static Component name(AdvancementHolder p_297556_) {
        return p_297556_.value().name().orElseGet(() -> Component.literal(p_297556_.id().toString()));
    }

    private void write(RegistryFriendlyByteBuf p_328062_) {
        p_328062_.writeOptional(this.parent, FriendlyByteBuf::writeResourceLocation);
        DisplayInfo.STREAM_CODEC.apply(ByteBufCodecs::optional).encode(p_328062_, this.display);
        this.requirements.write(p_328062_);
        p_328062_.writeBoolean(this.sendsTelemetryEvent);
    }

    private static Advancement read(RegistryFriendlyByteBuf p_328348_) {
        return new Advancement(
            p_328348_.readOptional(FriendlyByteBuf::readResourceLocation),
            (Optional<DisplayInfo>)DisplayInfo.STREAM_CODEC.apply(ByteBufCodecs::optional).decode(p_328348_),
            AdvancementRewards.EMPTY,
            Map.of(),
            new AdvancementRequirements(p_328348_),
            p_328348_.readBoolean()
        );
    }

    public boolean isRoot() {
        return this.parent.isEmpty();
    }

    public void validate(ProblemReporter p_310503_, HolderGetter.Provider p_335087_) {
        this.criteria.forEach((p_325177_, p_325178_) -> {
            CriterionValidator criterionvalidator = new CriterionValidator(p_310503_.forChild(p_325177_), p_335087_);
            p_325178_.triggerInstance().validate(criterionvalidator);
        });
    }

    public static class Builder {
        private Optional<ResourceLocation> parent = Optional.empty();
        private Optional<DisplayInfo> display = Optional.empty();
        private AdvancementRewards rewards = AdvancementRewards.EMPTY;
        private final ImmutableMap.Builder<String, Criterion<?>> criteria = ImmutableMap.builder();
        private Optional<AdvancementRequirements> requirements = Optional.empty();
        private AdvancementRequirements.Strategy requirementsStrategy = AdvancementRequirements.Strategy.AND;
        private boolean sendsTelemetryEvent;

        public static Advancement.Builder advancement() {
            return new Advancement.Builder().sendsTelemetryEvent();
        }

        public static Advancement.Builder recipeAdvancement() {
            return new Advancement.Builder();
        }

        public Advancement.Builder parent(AdvancementHolder p_300513_) {
            this.parent = Optional.of(p_300513_.id());
            return this;
        }

        @Deprecated(
            forRemoval = true
        )
        public Advancement.Builder parent(ResourceLocation p_138397_) {
            this.parent = Optional.of(p_138397_);
            return this;
        }

        public Advancement.Builder display(
            ItemStack p_138363_,
            Component p_138364_,
            Component p_138365_,
            @Nullable ResourceLocation p_138366_,
            AdvancementType p_310090_,
            boolean p_138368_,
            boolean p_138369_,
            boolean p_138370_
        ) {
            return this.display(new DisplayInfo(p_138363_, p_138364_, p_138365_, Optional.ofNullable(p_138366_), p_310090_, p_138368_, p_138369_, p_138370_));
        }

        public Advancement.Builder display(
            ItemLike p_138372_,
            Component p_138373_,
            Component p_138374_,
            @Nullable ResourceLocation p_138375_,
            AdvancementType p_309840_,
            boolean p_138377_,
            boolean p_138378_,
            boolean p_138379_
        ) {
            return this.display(
                new DisplayInfo(
                    new ItemStack(p_138372_.asItem()), p_138373_, p_138374_, Optional.ofNullable(p_138375_), p_309840_, p_138377_, p_138378_, p_138379_
                )
            );
        }

        public Advancement.Builder display(DisplayInfo p_138359_) {
            this.display = Optional.of(p_138359_);
            return this;
        }

        public Advancement.Builder rewards(AdvancementRewards.Builder p_138355_) {
            return this.rewards(p_138355_.build());
        }

        public Advancement.Builder rewards(AdvancementRewards p_138357_) {
            this.rewards = p_138357_;
            return this;
        }

        public Advancement.Builder addCriterion(String p_138384_, Criterion<?> p_138385_) {
            this.criteria.put(p_138384_, p_138385_);
            return this;
        }

        public Advancement.Builder requirements(AdvancementRequirements.Strategy p_298091_) {
            this.requirementsStrategy = p_298091_;
            return this;
        }

        public Advancement.Builder requirements(AdvancementRequirements p_300756_) {
            this.requirements = Optional.of(p_300756_);
            return this;
        }

        public Advancement.Builder sendsTelemetryEvent() {
            this.sendsTelemetryEvent = true;
            return this;
        }

        public AdvancementHolder build(ResourceLocation p_138404_) {
            Map<String, Criterion<?>> map = this.criteria.buildOrThrow();
            AdvancementRequirements advancementrequirements = this.requirements.orElseGet(() -> this.requirementsStrategy.create(map.keySet()));
            return new AdvancementHolder(
                p_138404_, new Advancement(this.parent, this.display, this.rewards, map, advancementrequirements, this.sendsTelemetryEvent)
            );
        }

        public AdvancementHolder save(Consumer<AdvancementHolder> p_138390_, String p_138391_) {
            AdvancementHolder advancementholder = this.build(ResourceLocation.parse(p_138391_));
            p_138390_.accept(advancementholder);
            return advancementholder;
        }
    }
}