bring back advancements
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -24,6 +24,7 @@ hs_err_pid*
|
||||
.idea
|
||||
.gradle
|
||||
build
|
||||
runs
|
||||
run
|
||||
|
||||
.DS_Store
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
package dev.xkmc.l2core.serial.advancements;
|
||||
|
||||
import com.tterrag.registrate.providers.RegistrateAdvancementProvider;
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.advancements.AdvancementHolder;
|
||||
import net.minecraft.advancements.AdvancementType;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class AdvancementGenerator {
|
||||
|
||||
private final RegistrateAdvancementProvider pvd;
|
||||
private final String modid;
|
||||
|
||||
public AdvancementGenerator(RegistrateAdvancementProvider pvd, String modid) {
|
||||
this.pvd = pvd;
|
||||
this.modid = modid;
|
||||
}
|
||||
|
||||
public class TabBuilder {
|
||||
|
||||
private final String tab;
|
||||
private final ResourceLocation bg;
|
||||
|
||||
private Entry root;
|
||||
|
||||
public TabBuilder(String tab) {
|
||||
this.tab = tab;
|
||||
this.bg = ResourceLocation.fromNamespaceAndPath(modid, "textures/gui/advancements/backgrounds/" + tab + ".png");
|
||||
}
|
||||
|
||||
public void build() {
|
||||
root.build();
|
||||
}
|
||||
|
||||
public Entry root(String id, Item item, CriterionBuilder builder, String title, String desc) {
|
||||
return root(id, item.getDefaultInstance(), builder, title, desc);
|
||||
}
|
||||
|
||||
public Entry root(String id, ItemStack item, CriterionBuilder builder, String title, String desc) {
|
||||
if (root == null) {
|
||||
root = new Entry(new EntryData(id, item, builder, title, desc), null);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
public Entry hidden(String id, CriterionBuilder builder) {
|
||||
return new Entry(new EntryData(id, ItemStack.EMPTY, builder, "", ""), null);
|
||||
}
|
||||
|
||||
public class Entry {
|
||||
|
||||
private final List<Entry> children = new ArrayList<>();
|
||||
private final EntryData data;
|
||||
private final ResourceLocation rl;
|
||||
private final Entry parent;
|
||||
|
||||
private AdvancementType type = AdvancementType.TASK;
|
||||
private boolean showToast = true, announce = true, hidden = false;
|
||||
private AdvancementHolder result;
|
||||
|
||||
private Entry(EntryData data, @Nullable Entry parent) {
|
||||
this.data = data;
|
||||
this.parent = parent;
|
||||
if (parent == null) {
|
||||
showToast = false;
|
||||
announce = false;
|
||||
rl = bg;
|
||||
} else {
|
||||
rl = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Entry create(String id, Item item, CriterionBuilder builder, String title, String desc) {
|
||||
return create(id, item.getDefaultInstance(), builder, title, desc);
|
||||
}
|
||||
|
||||
public Entry create(String id, ItemStack item, CriterionBuilder builder, String title, String desc) {
|
||||
Entry sub = new Entry(new EntryData(id, item, builder, title, desc), this);
|
||||
children.add(sub);
|
||||
return sub;
|
||||
}
|
||||
|
||||
/*TODO
|
||||
public Entry patchouli(L2Registrate reg, CriterionBuilder builder, ResourceLocation book, String title, String desc) {
|
||||
ItemStack stack = PatchouliHelper.getBook(book);
|
||||
return create("patchouli", stack, builder, title, desc)
|
||||
.add(new ModLoadedAdv("patchouli"))
|
||||
.add(new RewardBuilder(reg, 0, book, () -> PatchouliHelper.getBookLoot(book)));
|
||||
}*/
|
||||
|
||||
public Entry root() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public Entry enter() {
|
||||
return children.getLast();
|
||||
}
|
||||
|
||||
public Entry type(AdvancementType type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Entry type(AdvancementType type, boolean showToast, boolean announce, boolean hidden) {
|
||||
this.type = type;
|
||||
this.showToast = showToast;
|
||||
this.announce = announce;
|
||||
this.hidden = hidden;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Entry add(IAdvBuilder builder) {
|
||||
data.builder.add(builder);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void build() {
|
||||
var builder = Advancement.Builder.advancement();
|
||||
if (!data.item.isEmpty()) {
|
||||
builder.display(data.item,
|
||||
pvd.title(modid, "advancements." + tab + "." + data.id, data.title),
|
||||
pvd.desc(modid, "advancements." + tab + "." + data.id, data.desc),
|
||||
rl, type, showToast, announce, hidden);
|
||||
}
|
||||
if (parent != null) {
|
||||
builder.parent(parent.result);
|
||||
}
|
||||
|
||||
String uid = modid + ":" + tab + "/" + data.id;
|
||||
for (var e : data.builder) {
|
||||
e.modify(uid, builder);
|
||||
e.onBuild();
|
||||
}
|
||||
result = builder.save(pvd, uid);
|
||||
for (Entry e : children) {
|
||||
e.build();
|
||||
}
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
TabBuilder.this.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private record EntryData(String id, ItemStack item, List<IAdvBuilder> builder, String title, String desc) {
|
||||
|
||||
EntryData(String id, ItemStack item, IAdvBuilder builder, String title, String desc) {
|
||||
this(id, item, new ArrayList<>(List.of(builder)), title, desc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package dev.xkmc.l2core.serial.advancements;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import dev.xkmc.l2serial.serialization.codec.CodecAdaptor;
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate;
|
||||
import net.minecraft.advancements.critereon.SimpleCriterionTrigger;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class BaseCriterion<T extends BaseCriterionInstance<T, R>, R extends BaseCriterion<T, R>> extends SimpleCriterionTrigger<T> {
|
||||
|
||||
private final Codec<T> codec;
|
||||
|
||||
public BaseCriterion(Class<T> cls) {
|
||||
this.codec = new CodecAdaptor<>(cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec<T> codec() {
|
||||
return codec;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.xkmc.l2core.serial.advancements;
|
||||
|
||||
import dev.xkmc.l2serial.serialization.marker.SerialClass;
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate;
|
||||
import net.minecraft.advancements.critereon.SimpleCriterionTrigger;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@SerialClass
|
||||
public class BaseCriterionInstance<T extends BaseCriterionInstance<T, R>, R extends BaseCriterion<T, R>>
|
||||
implements SimpleCriterionTrigger.SimpleInstance {
|
||||
|
||||
@Override
|
||||
public Optional<ContextAwarePredicate> player() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package dev.xkmc.l2core.serial.advancements;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.advancements.AdvancementRequirements;
|
||||
import net.minecraft.advancements.Criterion;
|
||||
import net.minecraft.advancements.critereon.*;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.component.DataComponentPredicate;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.enchantment.Enchantment;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CriterionBuilder implements IAdvBuilder {
|
||||
|
||||
@Deprecated
|
||||
public static CriterionBuilder none() {
|
||||
return one(InventoryChangeTrigger.TriggerInstance.hasItems(ItemPredicate.Builder.item()));
|
||||
}
|
||||
|
||||
public static CriterionBuilder item(Item item) {
|
||||
return one(InventoryChangeTrigger.TriggerInstance.hasItems(item));
|
||||
}
|
||||
|
||||
public static CriterionBuilder item(TagKey<Item> item, DataComponentPredicate tag) {
|
||||
return one(InventoryChangeTrigger.TriggerInstance.hasItems(ItemPredicate.Builder.item().of(item).hasComponents(tag).build()));
|
||||
}
|
||||
|
||||
public static CriterionBuilder item(ItemLike item, DataComponentPredicate tag) {
|
||||
return one(InventoryChangeTrigger.TriggerInstance.hasItems(ItemPredicate.Builder.item().of(item).hasComponents(tag).build()));
|
||||
}
|
||||
|
||||
public static CriterionBuilder items(Item... item) {
|
||||
return one(InventoryChangeTrigger.TriggerInstance.hasItems(ItemPredicate.Builder.item().of(item).build()));
|
||||
}
|
||||
|
||||
public static CriterionBuilder item(TagKey<Item> item) {
|
||||
return one(InventoryChangeTrigger.TriggerInstance.hasItems(ItemPredicate.Builder.item().of(item).build()));
|
||||
}
|
||||
|
||||
public static CriterionBuilder book(Holder<Enchantment> enchantment) {
|
||||
return one(InventoryChangeTrigger.TriggerInstance.hasItems(ItemPredicate.Builder.item()
|
||||
.withSubPredicate(ItemSubPredicates.STORED_ENCHANTMENTS,
|
||||
ItemEnchantmentsPredicate.storedEnchantments(List.of(
|
||||
new EnchantmentPredicate(enchantment, MinMaxBounds.Ints.ANY))))));
|
||||
}
|
||||
|
||||
public static CriterionBuilder enchanted(Holder<Enchantment> enchantment) {
|
||||
return one(InventoryChangeTrigger.TriggerInstance.hasItems(ItemPredicate.Builder.item()
|
||||
.withSubPredicate(ItemSubPredicates.ENCHANTMENTS,
|
||||
ItemEnchantmentsPredicate.enchantments(List.of(
|
||||
new EnchantmentPredicate(enchantment, MinMaxBounds.Ints.ANY))))));
|
||||
}
|
||||
|
||||
public static CriterionBuilder enchanted(ItemLike item, Holder<Enchantment> enchantment) {
|
||||
return one(InventoryChangeTrigger.TriggerInstance.hasItems(ItemPredicate.Builder.item().of(item)
|
||||
.withSubPredicate(ItemSubPredicates.ENCHANTMENTS,
|
||||
ItemEnchantmentsPredicate.enchantments(List.of(
|
||||
new EnchantmentPredicate(enchantment, MinMaxBounds.Ints.ANY))))));
|
||||
}
|
||||
|
||||
public static CriterionBuilder enchanted(TagKey<Item> item, Holder<Enchantment> enchantment) {
|
||||
return one(InventoryChangeTrigger.TriggerInstance.hasItems(ItemPredicate.Builder.item().of(item)
|
||||
.withSubPredicate(ItemSubPredicates.ENCHANTMENTS,
|
||||
ItemEnchantmentsPredicate.enchantments(List.of(
|
||||
new EnchantmentPredicate(enchantment, MinMaxBounds.Ints.ANY))))));
|
||||
}
|
||||
|
||||
public static CriterionBuilder one(Criterion<?> instance) {
|
||||
return new CriterionBuilder(RequirementsStrategy.AND).add(instance);
|
||||
}
|
||||
|
||||
public enum RequirementsStrategy {
|
||||
AND, OR;
|
||||
}
|
||||
|
||||
public static CriterionBuilder and() {
|
||||
return new CriterionBuilder(RequirementsStrategy.AND);
|
||||
}
|
||||
|
||||
public static CriterionBuilder or() {
|
||||
return new CriterionBuilder(RequirementsStrategy.OR);
|
||||
}
|
||||
|
||||
private final RequirementsStrategy req;
|
||||
private final List<Pair<String, Criterion<?>>> list = new ArrayList<>();
|
||||
|
||||
private CriterionBuilder(RequirementsStrategy req) {
|
||||
this.req = req;
|
||||
}
|
||||
|
||||
public CriterionBuilder add(Criterion<?> instance) {
|
||||
return add(list.size() + "", instance);
|
||||
}
|
||||
|
||||
public CriterionBuilder add(String str, Criterion<?> instance) {
|
||||
list.add(Pair.of(str, instance));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void modify(String id, Advancement.Builder builder) {
|
||||
if (list.size() > 1) {
|
||||
var ids = list.stream().map(Pair::getFirst).toList();
|
||||
builder.requirements(req == RequirementsStrategy.AND ?
|
||||
AdvancementRequirements.allOf(ids) :
|
||||
AdvancementRequirements.anyOf(ids)
|
||||
);
|
||||
}
|
||||
for (var c : list) {
|
||||
builder.addCriterion(c.getFirst(), c.getSecond());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.xkmc.l2core.serial.advancements;
|
||||
|
||||
import net.minecraft.advancements.Advancement;
|
||||
|
||||
public interface IAdvBuilder {
|
||||
|
||||
default void modify(String id, Advancement.Builder builder) {
|
||||
|
||||
}
|
||||
|
||||
default void onBuild() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.xkmc.l2core.serial.advancements;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public record ModLoadedAdv(String... modid) implements IAdvBuilder {
|
||||
|
||||
@Override
|
||||
public void addConditions(JsonArray conditions) {
|
||||
for (String str : modid) {
|
||||
JsonObject condition = new JsonObject();
|
||||
condition.addProperty("type", "forge:mod_loaded");
|
||||
condition.addProperty("modid", str);
|
||||
conditions.add(condition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.xkmc.l2core.serial.advancements;
|
||||
|
||||
import com.tterrag.registrate.providers.ProviderType;
|
||||
import dev.xkmc.l2core.init.reg.registrate.L2Registrate;
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.advancements.AdvancementRewards;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.storage.loot.LootTable;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public record RewardBuilder(L2Registrate reg, int exp, ResourceKey<LootTable> loot,
|
||||
Supplier<LootTable.Builder> sup) implements IAdvBuilder {
|
||||
|
||||
@Override
|
||||
public void modify(String id, Advancement.Builder builder) {
|
||||
builder.rewards(AdvancementRewards.Builder.loot(loot).addExperience(exp).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBuild() {
|
||||
reg.addDataGenerator(ProviderType.LOOT, e -> e.addLootAction(LootContextParamSets.EMPTY,
|
||||
x -> x.accept(loot, sup.get())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
|
||||
package dev.xkmc.l2core.serial.advancements;
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
Reference in New Issue
Block a user