patchouli template
This commit is contained in:
		@@ -0,0 +1,8 @@
 | 
			
		||||
@MethodsReturnNonnullByDefault
 | 
			
		||||
@ParametersAreNonnullByDefault
 | 
			
		||||
 | 
			
		||||
package dev.xkmc.l2core.compat.curios;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.MethodsReturnNonnullByDefault;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.ParametersAreNonnullByDefault;
 | 
			
		||||
@@ -0,0 +1,53 @@
 | 
			
		||||
package dev.xkmc.l2core.compat.jei;
 | 
			
		||||
 | 
			
		||||
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
 | 
			
		||||
import mezz.jei.api.gui.drawable.IDrawable;
 | 
			
		||||
import mezz.jei.api.recipe.IFocusGroup;
 | 
			
		||||
import mezz.jei.api.recipe.RecipeType;
 | 
			
		||||
import mezz.jei.api.recipe.category.IRecipeCategory;
 | 
			
		||||
import net.minecraft.MethodsReturnNonnullByDefault;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.ParametersAreNonnullByDefault;
 | 
			
		||||
 | 
			
		||||
@ParametersAreNonnullByDefault
 | 
			
		||||
@MethodsReturnNonnullByDefault
 | 
			
		||||
public abstract class BaseRecipeCategory<T, C extends BaseRecipeCategory<T, C>> implements IRecipeCategory<T> {
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public static <T extends R, R> Class<T> cast(Class<R> cls) {
 | 
			
		||||
		return (Class<T>) cls;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private final RecipeType<T> type;
 | 
			
		||||
 | 
			
		||||
	protected IDrawable background, icon;
 | 
			
		||||
 | 
			
		||||
	public BaseRecipeCategory(ResourceLocation name, Class<T> cls) {
 | 
			
		||||
		this.type = new RecipeType<>(name, cls);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public final C getThis() {
 | 
			
		||||
		return (C) this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public final RecipeType<T> getRecipeType() {
 | 
			
		||||
		return type;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public final IDrawable getBackground() {
 | 
			
		||||
		return background;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public final IDrawable getIcon() {
 | 
			
		||||
		return icon;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public abstract void setRecipe(IRecipeLayoutBuilder builder, T recipe, IFocusGroup focuses);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,8 @@
 | 
			
		||||
@MethodsReturnNonnullByDefault
 | 
			
		||||
@ParametersAreNonnullByDefault
 | 
			
		||||
 | 
			
		||||
package dev.xkmc.l2core.compat.jei;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.MethodsReturnNonnullByDefault;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.ParametersAreNonnullByDefault;
 | 
			
		||||
@@ -0,0 +1,99 @@
 | 
			
		||||
package dev.xkmc.l2core.compat.patchouli;
 | 
			
		||||
 | 
			
		||||
import com.tterrag.registrate.providers.ProviderType;
 | 
			
		||||
import com.tterrag.registrate.util.DataIngredient;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.registrate.L2Registrate;
 | 
			
		||||
import dev.xkmc.l2core.serial.recipe.ConditionalRecipeWrapper;
 | 
			
		||||
import net.minecraft.Util;
 | 
			
		||||
import net.minecraft.data.recipes.RecipeBuilder;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.resources.ResourceKey;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.CreativeModeTab;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.LootPool;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.LootTable;
 | 
			
		||||
import net.neoforged.neoforge.client.model.generators.ModelFile;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Consumer;
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
public class PatchouliHelper {
 | 
			
		||||
 | 
			
		||||
	public static final ProviderType<PatchouliProvider> PATCHOULI = ProviderType.register("patchouli", (p, e) -> new PatchouliProvider(p, e.getLookupProvider(), e.getGenerator()));
 | 
			
		||||
 | 
			
		||||
	public static ItemStack getBook(ResourceLocation book) {
 | 
			
		||||
		return ItemStack.EMPTY; // TODO ItemModBook.forBook(book);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static LootTable.Builder getBookLoot(ResourceLocation book) {
 | 
			
		||||
		CompoundTag tag = new CompoundTag();
 | 
			
		||||
		tag.putString("patchouli:book", book.toString());
 | 
			
		||||
		return LootTable.lootTable().withPool(
 | 
			
		||||
				LootPool.lootPool()//TODO .add(LootItem.lootTableItem(PatchouliItems.BOOK).apply(SetNbtFunction.setTag(tag)))
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private final L2Registrate reg;
 | 
			
		||||
	private final ResourceLocation book;
 | 
			
		||||
 | 
			
		||||
	private ResourceLocation model;
 | 
			
		||||
 | 
			
		||||
	public PatchouliHelper(L2Registrate reg, String name) {
 | 
			
		||||
		this.reg = reg;
 | 
			
		||||
		book = ResourceLocation.fromNamespaceAndPath(reg.getModid(), name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public PatchouliHelper buildModel() {
 | 
			
		||||
		return buildModel("book");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public PatchouliHelper buildModel(String path) {
 | 
			
		||||
		model = ResourceLocation.fromNamespaceAndPath(reg.getModid(), path);
 | 
			
		||||
		reg.addDataGenerator(ProviderType.ITEM_MODEL, pvd -> pvd.getBuilder(path)
 | 
			
		||||
				.parent(new ModelFile.UncheckedModelFile("item/generated"))
 | 
			
		||||
				.texture("layer0", "item/" + path));
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* TODO
 | 
			
		||||
	public PatchouliHelper buildShapelessRecipe(Consumer<ShapelessPatchouliBuilder> cons, Supplier<Item> unlock) {
 | 
			
		||||
		return buildRecipe(() -> Util.make(new ShapelessPatchouliBuilder(book), cons), unlock);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public PatchouliHelper buildShapedRecipe(Consumer<ShapedPatchouliBuilder> cons, Supplier<Item> unlock) {
 | 
			
		||||
		return buildRecipe(() -> Util.make(new ShapedPatchouliBuilder(book), cons), unlock);
 | 
			
		||||
	}
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	private PatchouliHelper buildRecipe(Supplier<RecipeBuilder> cons, Supplier<Item> unlock) {
 | 
			
		||||
		reg.addDataGenerator(ProviderType.RECIPE, pvd -> {
 | 
			
		||||
			var builder = cons.get();
 | 
			
		||||
			builder.unlockedBy("has_" + pvd.safeName(unlock.get()),
 | 
			
		||||
					DataIngredient.items(unlock.get()).getCriterion(pvd));
 | 
			
		||||
			builder.save(ConditionalRecipeWrapper.mod(pvd, "patchouli"),
 | 
			
		||||
					ResourceLocation.fromNamespaceAndPath(reg.getModid(), "book"));
 | 
			
		||||
		});
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public PatchouliHelper buildBook(String title, String landing, int ver, ResourceKey<CreativeModeTab> tab) {
 | 
			
		||||
		if (model == null) {
 | 
			
		||||
			throw new IllegalStateException("Patchouli Book must have a model first");
 | 
			
		||||
		}
 | 
			
		||||
		String titleId = "patchouli." + reg.getModid() + ".title";
 | 
			
		||||
		String descId = "patchouli." + reg.getModid() + ".landing";
 | 
			
		||||
		reg.addRawLang(titleId, title);
 | 
			
		||||
		reg.addRawLang(descId, landing);
 | 
			
		||||
		reg.addDataGenerator(PATCHOULI, pvd -> pvd.accept(reg.getModid() + "/patchouli_books/" + book.getPath() + "/book",
 | 
			
		||||
				new BookEntry(titleId, descId, ver, model, tab.location(), true)));
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public record BookEntry(String name, String landing_text, int version,
 | 
			
		||||
							ResourceLocation model, ResourceLocation creative_tab,
 | 
			
		||||
							boolean use_resource_pack) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,43 @@
 | 
			
		||||
package dev.xkmc.l2core.compat.patchouli;
 | 
			
		||||
 | 
			
		||||
import com.tterrag.registrate.AbstractRegistrate;
 | 
			
		||||
import com.tterrag.registrate.providers.RegistrateProvider;
 | 
			
		||||
import dev.xkmc.l2core.serial.config.RecordDataProvider;
 | 
			
		||||
import net.minecraft.core.HolderLookup;
 | 
			
		||||
import net.minecraft.data.DataGenerator;
 | 
			
		||||
import net.neoforged.fml.LogicalSide;
 | 
			
		||||
 | 
			
		||||
import java.util.concurrent.CompletableFuture;
 | 
			
		||||
import java.util.function.BiConsumer;
 | 
			
		||||
 | 
			
		||||
public class PatchouliProvider extends RecordDataProvider implements RegistrateProvider, BiConsumer<String, Record> {
 | 
			
		||||
 | 
			
		||||
	private final AbstractRegistrate<?> owner;
 | 
			
		||||
 | 
			
		||||
	private BiConsumer<String, Record> map;
 | 
			
		||||
 | 
			
		||||
	public PatchouliProvider(AbstractRegistrate<?> owner, CompletableFuture<HolderLookup.Provider> pvd, DataGenerator gen) {
 | 
			
		||||
		super(gen, pvd, "Patchouli Provider");
 | 
			
		||||
		this.owner = owner;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void accept(String path, Record rec) {
 | 
			
		||||
		if (map == null) {
 | 
			
		||||
			throw new IllegalStateException("Cannot accept recipes outside of a call to registerRecipes");
 | 
			
		||||
		}
 | 
			
		||||
		map.accept(path, rec);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public LogicalSide getSide() {
 | 
			
		||||
		return LogicalSide.SERVER;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void add(BiConsumer<String, Record> map) {
 | 
			
		||||
		this.map = map;
 | 
			
		||||
		owner.genData(PatchouliHelper.PATCHOULI, this);
 | 
			
		||||
		this.map = null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,83 @@
 | 
			
		||||
package dev.xkmc.l2core.compat.patchouli;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonArray;
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import net.minecraft.advancements.Advancement;
 | 
			
		||||
import net.minecraft.advancements.AdvancementRewards;
 | 
			
		||||
import net.minecraft.advancements.RequirementsStrategy;
 | 
			
		||||
import net.minecraft.advancements.critereon.RecipeUnlockedTrigger;
 | 
			
		||||
import net.minecraft.data.recipes.FinishedRecipe;
 | 
			
		||||
import net.minecraft.data.recipes.RecipeCategory;
 | 
			
		||||
import net.minecraft.data.recipes.RecipeOutput;
 | 
			
		||||
import net.minecraft.data.recipes.ShapedRecipeBuilder;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.crafting.Ingredient;
 | 
			
		||||
import net.minecraft.world.item.crafting.RecipeSerializer;
 | 
			
		||||
import vazkii.patchouli.common.item.PatchouliItems;
 | 
			
		||||
import vazkii.patchouli.common.recipe.ShapedBookRecipe;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
public class ShapedPatchouliBuilder extends ShapedRecipeBuilder {
 | 
			
		||||
 | 
			
		||||
	private final ResourceLocation book;
 | 
			
		||||
 | 
			
		||||
	public ShapedPatchouliBuilder(ResourceLocation book) {
 | 
			
		||||
		super(RecipeCategory.MISC, PatchouliItems.BOOK, 1);
 | 
			
		||||
		this.book = book;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void save(RecipeOutput pvd, ResourceLocation id) {
 | 
			
		||||
		this.ensureValid(id);
 | 
			
		||||
		this.advancement.parent(ROOT_RECIPE_ADVANCEMENT)
 | 
			
		||||
				.addCriterion("has_the_recipe", RecipeUnlockedTrigger.unlocked(id))
 | 
			
		||||
				.rewards(AdvancementRewards.Builder.recipe(id))
 | 
			
		||||
				.requirements(RequirementsStrategy.OR);
 | 
			
		||||
		pvd.accept(new Result(book, id, this.rows, this.key, this.advancement, id.withPrefix("recipes/")));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public record Result(ResourceLocation book, ResourceLocation id, List<String> pattern,
 | 
			
		||||
						 Map<Character, Ingredient> key, Advancement.Builder advancement,
 | 
			
		||||
						 ResourceLocation advancementId) implements FinishedRecipe {
 | 
			
		||||
 | 
			
		||||
		public void serializeRecipeData(JsonObject json) {
 | 
			
		||||
			JsonArray jsonarray = new JsonArray();
 | 
			
		||||
			for (String s : this.pattern) {
 | 
			
		||||
				jsonarray.add(s);
 | 
			
		||||
			}
 | 
			
		||||
			json.add("pattern", jsonarray);
 | 
			
		||||
			JsonObject jsonobject = new JsonObject();
 | 
			
		||||
			for (Map.Entry<Character, Ingredient> entry : this.key.entrySet()) {
 | 
			
		||||
				jsonobject.add(String.valueOf(entry.getKey()), entry.getValue().toJson());
 | 
			
		||||
			}
 | 
			
		||||
			json.add("key", jsonobject);
 | 
			
		||||
			json.addProperty("book", book.toString());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public RecipeSerializer<?> getType() {
 | 
			
		||||
			return ShapedBookRecipe.SERIALIZER;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ResourceLocation getId() {
 | 
			
		||||
			return this.id;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public JsonObject serializeAdvancement() {
 | 
			
		||||
			return this.advancement.serializeToJson();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Nullable
 | 
			
		||||
		public ResourceLocation getAdvancementId() {
 | 
			
		||||
			return this.advancementId;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
@@ -0,0 +1,76 @@
 | 
			
		||||
package dev.xkmc.l2core.compat.patchouli;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
import com.google.gson.JsonArray;
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import net.minecraft.advancements.Advancement;
 | 
			
		||||
import net.minecraft.advancements.AdvancementRewards;
 | 
			
		||||
import net.minecraft.advancements.RequirementsStrategy;
 | 
			
		||||
import net.minecraft.advancements.critereon.RecipeUnlockedTrigger;
 | 
			
		||||
import net.minecraft.data.recipes.FinishedRecipe;
 | 
			
		||||
import net.minecraft.data.recipes.RecipeCategory;
 | 
			
		||||
import net.minecraft.data.recipes.ShapelessRecipeBuilder;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.crafting.Ingredient;
 | 
			
		||||
import net.minecraft.world.item.crafting.RecipeSerializer;
 | 
			
		||||
import vazkii.patchouli.common.item.PatchouliItems;
 | 
			
		||||
import vazkii.patchouli.common.recipe.ShapelessBookRecipe;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.function.Consumer;
 | 
			
		||||
 | 
			
		||||
public class ShapelessPatchouliBuilder extends ShapelessRecipeBuilder {
 | 
			
		||||
 | 
			
		||||
	private final ResourceLocation book;
 | 
			
		||||
 | 
			
		||||
	public ShapelessPatchouliBuilder(ResourceLocation book) {
 | 
			
		||||
		super(RecipeCategory.MISC, PatchouliItems.BOOK, 1);
 | 
			
		||||
		this.book = book;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void save(Consumer<FinishedRecipe> pvd, ResourceLocation id) {
 | 
			
		||||
		this.ensureValid(id);
 | 
			
		||||
		this.advancement.parent(ROOT_RECIPE_ADVANCEMENT)
 | 
			
		||||
				.addCriterion("has_the_recipe", RecipeUnlockedTrigger.unlocked(id))
 | 
			
		||||
				.rewards(AdvancementRewards.Builder.recipe(id))
 | 
			
		||||
				.requirements(RequirementsStrategy.OR);
 | 
			
		||||
		pvd.accept(new Shapeless(book, id, this.ingredients, this.advancement, id.withPrefix("recipes/")));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public record Shapeless(ResourceLocation book, ResourceLocation id, List<Ingredient> ingredients,
 | 
			
		||||
							Advancement.Builder advancement, ResourceLocation advId) implements FinishedRecipe {
 | 
			
		||||
 | 
			
		||||
		public void serializeRecipeData(JsonObject json) {
 | 
			
		||||
			JsonArray jsonarray = new JsonArray();
 | 
			
		||||
			for (Ingredient ingredient : this.ingredients) {
 | 
			
		||||
				jsonarray.add(ingredient.toJson());
 | 
			
		||||
			}
 | 
			
		||||
			json.add("ingredients", jsonarray);
 | 
			
		||||
			json.addProperty("book", book.toString());
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public RecipeSerializer<?> getType() {
 | 
			
		||||
			return ShapelessBookRecipe.SERIALIZER;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ResourceLocation getId() {
 | 
			
		||||
			return this.id;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public JsonObject serializeAdvancement() {
 | 
			
		||||
			return this.advancement.serializeToJson();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Nullable
 | 
			
		||||
		public ResourceLocation getAdvancementId() {
 | 
			
		||||
			return this.advId;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 */
 | 
			
		||||
@@ -0,0 +1,8 @@
 | 
			
		||||
@MethodsReturnNonnullByDefault
 | 
			
		||||
@ParametersAreNonnullByDefault
 | 
			
		||||
 | 
			
		||||
package dev.xkmc.l2core.compat.patchouli;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.MethodsReturnNonnullByDefault;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.ParametersAreNonnullByDefault;
 | 
			
		||||
@@ -1,9 +1,13 @@
 | 
			
		||||
package dev.xkmc.l2core.serial.advancements;
 | 
			
		||||
 | 
			
		||||
import com.tterrag.registrate.providers.RegistrateAdvancementProvider;
 | 
			
		||||
import dev.xkmc.l2core.compat.patchouli.PatchouliHelper;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.registrate.L2Registrate;
 | 
			
		||||
import net.minecraft.advancements.Advancement;
 | 
			
		||||
import net.minecraft.advancements.AdvancementHolder;
 | 
			
		||||
import net.minecraft.advancements.AdvancementType;
 | 
			
		||||
import net.minecraft.core.registries.Registries;
 | 
			
		||||
import net.minecraft.resources.ResourceKey;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
@@ -17,152 +21,151 @@ import java.util.function.Consumer;
 | 
			
		||||
@SuppressWarnings("unused")
 | 
			
		||||
public class AdvancementGenerator {
 | 
			
		||||
 | 
			
		||||
    private final RegistrateAdvancementProvider pvd;
 | 
			
		||||
    private final String modid;
 | 
			
		||||
	private final RegistrateAdvancementProvider pvd;
 | 
			
		||||
	private final String modid;
 | 
			
		||||
 | 
			
		||||
    public AdvancementGenerator(RegistrateAdvancementProvider pvd, String modid) {
 | 
			
		||||
        this.pvd = pvd;
 | 
			
		||||
        this.modid = modid;
 | 
			
		||||
    }
 | 
			
		||||
	public AdvancementGenerator(RegistrateAdvancementProvider pvd, String modid) {
 | 
			
		||||
		this.pvd = pvd;
 | 
			
		||||
		this.modid = modid;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    public class TabBuilder {
 | 
			
		||||
	public class TabBuilder {
 | 
			
		||||
 | 
			
		||||
        private final String tab;
 | 
			
		||||
        private final ResourceLocation bg;
 | 
			
		||||
		private final String tab;
 | 
			
		||||
		private final ResourceLocation bg;
 | 
			
		||||
 | 
			
		||||
        private Entry root;
 | 
			
		||||
		private Entry root;
 | 
			
		||||
 | 
			
		||||
        public TabBuilder(String tab) {
 | 
			
		||||
            this.tab = tab;
 | 
			
		||||
            this.bg = ResourceLocation.fromNamespaceAndPath(modid, "textures/gui/advancements/backgrounds/" + tab + ".png");
 | 
			
		||||
        }
 | 
			
		||||
		public TabBuilder(String tab) {
 | 
			
		||||
			this.tab = tab;
 | 
			
		||||
			this.bg = ResourceLocation.fromNamespaceAndPath(modid, "textures/gui/advancements/backgrounds/" + tab + ".png");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public void build() {
 | 
			
		||||
            root.build();
 | 
			
		||||
        }
 | 
			
		||||
		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, 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 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 Entry hidden(String id, CriterionBuilder builder) {
 | 
			
		||||
			return new Entry(new EntryData(id, ItemStack.EMPTY, builder, "", ""), null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public class Entry {
 | 
			
		||||
		public class Entry {
 | 
			
		||||
 | 
			
		||||
            private final List<Entry> children = new ArrayList<>();
 | 
			
		||||
            private final EntryData data;
 | 
			
		||||
            private final ResourceLocation rl;
 | 
			
		||||
            private final Entry parent;
 | 
			
		||||
			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 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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
			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, 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;
 | 
			
		||||
            }
 | 
			
		||||
			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)));
 | 
			
		||||
			}*/
 | 
			
		||||
						.add(new RewardBuilder(reg, 0, ResourceKey.create(Registries.LOOT_TABLE, book), () -> PatchouliHelper.getBookLoot(book)));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            public Entry root() {
 | 
			
		||||
                return root;
 | 
			
		||||
            }
 | 
			
		||||
			public Entry root() {
 | 
			
		||||
				return root;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            public Entry enter() {
 | 
			
		||||
                return children.getLast();
 | 
			
		||||
            }
 | 
			
		||||
			public Entry enter() {
 | 
			
		||||
				return children.getLast();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            public Entry type(AdvancementType type) {
 | 
			
		||||
                this.type = type;
 | 
			
		||||
                return this;
 | 
			
		||||
            }
 | 
			
		||||
			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 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 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, tab + "." + data.id, data.title),
 | 
			
		||||
                        pvd.desc(modid, tab + "." + data.id, data.desc),
 | 
			
		||||
                        rl, type, showToast, announce, hidden
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                if (parent != null) {
 | 
			
		||||
                    builder.parent(parent.result);
 | 
			
		||||
                }
 | 
			
		||||
			public void build() {
 | 
			
		||||
				var builder = Advancement.Builder.advancement();
 | 
			
		||||
				if (!data.item.isEmpty()) {
 | 
			
		||||
					builder.display(data.item,
 | 
			
		||||
							pvd.title(modid, tab + "." + data.id, data.title),
 | 
			
		||||
							pvd.desc(modid, tab + "." + data.id, data.desc),
 | 
			
		||||
							rl, type, showToast, announce, hidden
 | 
			
		||||
					);
 | 
			
		||||
				}
 | 
			
		||||
				if (parent != null) {
 | 
			
		||||
					builder.parent(parent.result);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                String uid = modid + ":" + tab + "/" + data.id;
 | 
			
		||||
                List<ICondition> conditions = new ArrayList<>();
 | 
			
		||||
                for (var e : data.builder) {
 | 
			
		||||
                    e.onBuild(uid, builder, conditions);
 | 
			
		||||
                }
 | 
			
		||||
                Consumer<AdvancementHolder> cons = conditions.isEmpty() ? pvd :
 | 
			
		||||
                    e -> pvd.withConditions(e, conditions);
 | 
			
		||||
                result = builder.save(cons, uid);
 | 
			
		||||
                for (Entry e : children) {
 | 
			
		||||
                    e.build();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
				String uid = modid + ":" + tab + "/" + data.id;
 | 
			
		||||
				List<ICondition> conditions = new ArrayList<>();
 | 
			
		||||
				for (var e : data.builder) {
 | 
			
		||||
					e.onBuild(uid, builder, conditions);
 | 
			
		||||
				}
 | 
			
		||||
				Consumer<AdvancementHolder> cons = conditions.isEmpty() ? pvd :
 | 
			
		||||
						e -> pvd.withConditions(e, conditions);
 | 
			
		||||
				result = builder.save(cons, uid);
 | 
			
		||||
				for (Entry e : children) {
 | 
			
		||||
					e.build();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            public void finish() {
 | 
			
		||||
                TabBuilder.this.build();
 | 
			
		||||
            }
 | 
			
		||||
			public void finish() {
 | 
			
		||||
				TabBuilder.this.build();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private record EntryData(String id, ItemStack item, List<IAdvBuilder> builder, String title, String desc) {
 | 
			
		||||
	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);
 | 
			
		||||
        }
 | 
			
		||||
		EntryData(String id, ItemStack item, IAdvBuilder builder, String title, String desc) {
 | 
			
		||||
			this(id, item, new ArrayList<>(List.of(builder)), title, desc);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,11 +17,11 @@ import java.util.function.BiConsumer;
 | 
			
		||||
 | 
			
		||||
public abstract class RecordDataProvider implements DataProvider {
 | 
			
		||||
	private final DataGenerator generator;
 | 
			
		||||
	private final HolderLookup.Provider pvd;
 | 
			
		||||
	private final CompletableFuture<HolderLookup.Provider> pvd;
 | 
			
		||||
	private final String name;
 | 
			
		||||
	private final Map<String, Record> map = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
	public RecordDataProvider(DataGenerator generator, HolderLookup.Provider pvd, String name) {
 | 
			
		||||
	public RecordDataProvider(DataGenerator generator, CompletableFuture<HolderLookup.Provider> pvd, String name) {
 | 
			
		||||
		this.generator = generator;
 | 
			
		||||
		this.pvd = pvd;
 | 
			
		||||
		this.name = name;
 | 
			
		||||
@@ -30,18 +30,19 @@ public abstract class RecordDataProvider implements DataProvider {
 | 
			
		||||
	public abstract void add(BiConsumer<String, Record> map);
 | 
			
		||||
 | 
			
		||||
	public CompletableFuture<?> run(CachedOutput cache) {
 | 
			
		||||
		Path folder = this.generator.getPackOutput().getOutputFolder();
 | 
			
		||||
		this.add(this.map::put);
 | 
			
		||||
		List<CompletableFuture<?>> list = new ArrayList<>();
 | 
			
		||||
		this.map.forEach((k, v) -> {
 | 
			
		||||
			JsonElement elem = new JsonCodec(pvd).toJson(v);
 | 
			
		||||
			if (elem != null) {
 | 
			
		||||
				Path path = folder.resolve("data/" + k + ".json");
 | 
			
		||||
				list.add(DataProvider.saveStable(cache, elem, path));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		return pvd.thenCompose(pvd -> {
 | 
			
		||||
			Path folder = this.generator.getPackOutput().getOutputFolder();
 | 
			
		||||
			this.add(this.map::put);
 | 
			
		||||
			List<CompletableFuture<?>> list = new ArrayList<>();
 | 
			
		||||
			this.map.forEach((k, v) -> {
 | 
			
		||||
				JsonElement elem = new JsonCodec(pvd).toJson(v);
 | 
			
		||||
				if (elem != null) {
 | 
			
		||||
					Path path = folder.resolve("data/" + k + ".json");
 | 
			
		||||
					list.add(DataProvider.saveStable(cache, elem, path));
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
			return CompletableFuture.allOf(list.toArray(CompletableFuture[]::new));
 | 
			
		||||
		});
 | 
			
		||||
		return CompletableFuture.allOf(list.toArray(CompletableFuture[]::new));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String getName() {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user