From 35c023692c41a1d3641bfd425b73c1ebb3ea49d0 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 1 Aug 2022 18:35:32 +0200 Subject: [PATCH] [Change] Refactored Recipe-Advancement API to prevent #29 --- .../v2/advancement/AdvancementManager.java | 50 +++++--- .../common/ServerAdvancementManagerMixin.java | 2 +- .../recipes/AbstractAdvancementRecipe.java | 107 ++++++++++++++++++ .../betterx/bclib/recipes/AlloyingRecipe.java | 5 +- .../betterx/bclib/recipes/AnvilRecipe.java | 5 +- .../bclib/recipes/BCLRecipeManager.java | 3 + .../bclib/recipes/CraftingRecipes.java | 10 +- .../betterx/bclib/recipes/FurnaceRecipe.java | 18 ++- .../org/betterx/bclib/recipes/GridRecipe.java | 14 ++- .../bclib/recipes/SmithingTableRecipe.java | 12 +- 10 files changed, 187 insertions(+), 39 deletions(-) create mode 100644 src/main/java/org/betterx/bclib/recipes/AbstractAdvancementRecipe.java diff --git a/src/main/java/org/betterx/bclib/api/v2/advancement/AdvancementManager.java b/src/main/java/org/betterx/bclib/api/v2/advancement/AdvancementManager.java index c2885530..92a03afa 100644 --- a/src/main/java/org/betterx/bclib/api/v2/advancement/AdvancementManager.java +++ b/src/main/java/org/betterx/bclib/api/v2/advancement/AdvancementManager.java @@ -6,15 +6,13 @@ import org.betterx.bclib.complexmaterials.WoodenComplexMaterial; import org.betterx.bclib.items.complex.EquipmentSet; import net.minecraft.advancements.*; -import net.minecraft.advancements.critereon.InventoryChangeTrigger; -import net.minecraft.advancements.critereon.LocationPredicate; -import net.minecraft.advancements.critereon.PlayerTrigger; -import net.minecraft.advancements.critereon.RecipeUnlockedTrigger; +import net.minecraft.advancements.critereon.*; import net.minecraft.core.Registry; import net.minecraft.data.recipes.RecipeBuilder; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; import net.minecraft.world.Container; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -116,6 +114,10 @@ public class AdvancementManager { this.type = type; } + public static Builder createEmptyCopy(Builder builder) { + return new Builder(builder.id, builder.type); + } + public static Builder create(ResourceLocation id) { return new Builder(id, AdvancementType.REGULAR); } @@ -169,11 +171,12 @@ public class AdvancementManager { public static > Builder createRecipe(T recipe, AdvancementType type) { Item item = recipe.getResultItem().getItem(); return create(item, type, displayBuilder -> displayBuilder.hideToast().hideFromChat()) - .awardRecipe(item) - .addRecipeUnlockCriterion( - "has_the_recipe", - recipe - ); + //.awardRecipe(item) + .addRecipeUnlockCriterion("has_the_recipe", recipe) + .startReward() + .addRecipe(recipe.getId()) + .endReward() + .requirements(RequirementsStrategy.OR); } public Builder parent(Advancement advancement) { @@ -277,11 +280,7 @@ public class AdvancementManager { return addCriterion( name, RecipeUnlockedTrigger.unlocked(recipe.getId()) - ) - .startReward() - .addRecipe(recipe.getId()) - .endReward() - .requirements(RequirementsStrategy.OR); + ); } public Builder addInventoryChangedCriterion(String name, ItemLike... items) { @@ -291,6 +290,24 @@ public class AdvancementManager { ); } + public Builder addInventoryChangedCriterion(String name, TagKey tag) { + return addCriterion( + name, + InventoryChangeTrigger.TriggerInstance.hasItems(new ItemPredicate( + tag, + null, + MinMaxBounds.Ints.ANY, + MinMaxBounds.Ints.ANY, + EnchantmentPredicate.NONE, + EnchantmentPredicate.NONE, + null, + NbtPredicate.ANY + )) + ); + } + + // + public Builder addEquipmentSetSlotCriterion(EquipmentSet set, String slot) { return addInventoryChangedCriterion( set.baseName + "_" + slot, @@ -352,6 +369,11 @@ public class AdvancementManager { AdvancementManager.register(id, this.builder); return this.id; } + + public ResourceLocation buildAndRegister(Map map) { + map.put(id, this.builder); + return this.id; + } } public static class DisplayBuilder { diff --git a/src/main/java/org/betterx/bclib/mixin/common/ServerAdvancementManagerMixin.java b/src/main/java/org/betterx/bclib/mixin/common/ServerAdvancementManagerMixin.java index ce1a6d4a..5dad6785 100644 --- a/src/main/java/org/betterx/bclib/mixin/common/ServerAdvancementManagerMixin.java +++ b/src/main/java/org/betterx/bclib/mixin/common/ServerAdvancementManagerMixin.java @@ -16,7 +16,7 @@ import java.util.Map; public class ServerAdvancementManagerMixin { @ModifyArg(method = "apply(Ljava/util/Map;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/AdvancementList;add(Ljava/util/Map;)V")) - public Map wunder_interceptApply(Map map) { + public Map bcl_interceptApply(Map map) { AdvancementManager.addAdvancements(map); return map; } diff --git a/src/main/java/org/betterx/bclib/recipes/AbstractAdvancementRecipe.java b/src/main/java/org/betterx/bclib/recipes/AbstractAdvancementRecipe.java new file mode 100644 index 00000000..22775133 --- /dev/null +++ b/src/main/java/org/betterx/bclib/recipes/AbstractAdvancementRecipe.java @@ -0,0 +1,107 @@ +package org.betterx.bclib.recipes; + +import org.betterx.bclib.api.v2.advancement.AdvancementManager; + +import net.minecraft.advancements.RequirementsStrategy; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.ArmorItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TieredItem; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Block; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class AbstractAdvancementRecipe { + protected AdvancementManager.Builder advancement; + boolean hasUnlockTrigger = false; + boolean generateAdvancement = false; + + protected void createAdvancement(ResourceLocation id, boolean isTool) { + hasUnlockTrigger = false; + generateAdvancement = true; + advancement = AdvancementManager.Builder.create( + id, + isTool + ? AdvancementManager.AdvancementType.RECIPE_TOOL + : AdvancementManager.AdvancementType.RECIPE_DECORATIONS + ); + } + + protected void createAdvancement(ResourceLocation id, ItemLike output) { + createAdvancement(id, (output.asItem() instanceof TieredItem || output.asItem() instanceof ArmorItem)); + } + + private int nameCounter = 0; + + public void unlockedBy(ItemStack... stacks) { + List items = Arrays.stream(stacks) + .filter(stack -> stack.getCount() > 0) + .map(stack -> (ItemLike) stack.getItem()) + .toList(); + + unlockedBy((ItemLike[]) items.toArray()); + } + + public void unlockedBy(ItemLike... items) { + String name = "has_" + (nameCounter++) + "_" + + Arrays.stream(items) + .map(block -> (block instanceof Block) + ? Registry.BLOCK.getKey((Block) block) + : Registry.ITEM.getKey((Item) block)) + .filter(id -> id != null) + .map(id -> id.getPath()) + .collect(Collectors.joining("_")); + if (name.length() > 45) name = name.substring(0, 42); + unlockedBy(name, items); + } + + public void unlockedBy(TagKey tag) { + ResourceLocation id = tag.location(); + if (id != null) { + unlockedBy("has_tag_" + id.getPath(), tag); + } + } + + public void unlockedBy(String name, ItemLike... items) { + hasUnlockTrigger = true; + advancement.addInventoryChangedCriterion(name, items); + } + + public void unlockedBy(String name, TagKey tag) { + hasUnlockTrigger = true; + advancement.addInventoryChangedCriterion(name, tag); + } + + public void noAdvancement() { + generateAdvancement = false; + } + + public void clearAdvancementCriteria() { + if (advancement != null) + advancement = AdvancementManager.Builder.createEmptyCopy(advancement); + } + + protected void registerAdvancement(Recipe recipe) { + if (hasUnlockTrigger && generateAdvancement) { + advancement + .startDisplay(recipe.getResultItem().getItem()) + .hideFromChat() + .hideToast() + .endDisplay() + .addRecipeUnlockCriterion("has_the_recipe", recipe) + .startReward() + .addRecipe(recipe.getId()) + .endReward() + .requirements(RequirementsStrategy.OR); + + advancement.buildAndRegister(); + } + } +} diff --git a/src/main/java/org/betterx/bclib/recipes/AlloyingRecipe.java b/src/main/java/org/betterx/bclib/recipes/AlloyingRecipe.java index 34e5b5ea..afda4629 100644 --- a/src/main/java/org/betterx/bclib/recipes/AlloyingRecipe.java +++ b/src/main/java/org/betterx/bclib/recipes/AlloyingRecipe.java @@ -249,10 +249,9 @@ public class AlloyingRecipe implements Recipe, UnknownReceipBookCateg BCLib.LOGGER.debug("Can't add Alloying recipe {}! Ingeredient or output not exists.", id); return; } - BCLRecipeManager.addRecipeAndCreateAdvancement( + BCLRecipeManager.addRecipe( TYPE, - new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime), - false + new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime) ); } } diff --git a/src/main/java/org/betterx/bclib/recipes/AnvilRecipe.java b/src/main/java/org/betterx/bclib/recipes/AnvilRecipe.java index d4deebaa..2e63cd68 100644 --- a/src/main/java/org/betterx/bclib/recipes/AnvilRecipe.java +++ b/src/main/java/org/betterx/bclib/recipes/AnvilRecipe.java @@ -350,10 +350,9 @@ public class AnvilRecipe implements Recipe, UnknownReceipBookCategory BCLib.LOGGER.debug("Can't add Anvil recipe {}! Ingeredient or output not exists.", id); return; } - BCLRecipeManager.addRecipeAndCreateAdvancement( + BCLRecipeManager.addRecipe( TYPE, - new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage), - false + new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage) ); } } diff --git a/src/main/java/org/betterx/bclib/recipes/BCLRecipeManager.java b/src/main/java/org/betterx/bclib/recipes/BCLRecipeManager.java index ab4cdd7b..20a5e799 100644 --- a/src/main/java/org/betterx/bclib/recipes/BCLRecipeManager.java +++ b/src/main/java/org/betterx/bclib/recipes/BCLRecipeManager.java @@ -63,6 +63,7 @@ public class BCLRecipeManager { list.put(recipe.getId(), recipe); } + @Deprecated(forRemoval = true) public static > void addRecipeAndCreateAdvancement( RecipeType type, T recipe @@ -71,6 +72,7 @@ public class BCLRecipeManager { registerAndCreateAdvancement(recipe, recipe.getResultItem().getItem() instanceof TieredItem); } + @Deprecated(forRemoval = true) public static > void addRecipeAndCreateAdvancement( RecipeType type, T recipe, @@ -80,6 +82,7 @@ public class BCLRecipeManager { registerAndCreateAdvancement(recipe, isTool); } + @Deprecated(forRemoval = true) public static > ResourceLocation registerAndCreateAdvancement( T recipe, boolean isTool diff --git a/src/main/java/org/betterx/bclib/recipes/CraftingRecipes.java b/src/main/java/org/betterx/bclib/recipes/CraftingRecipes.java index 9976b72a..369407b8 100644 --- a/src/main/java/org/betterx/bclib/recipes/CraftingRecipes.java +++ b/src/main/java/org/betterx/bclib/recipes/CraftingRecipes.java @@ -48,17 +48,17 @@ public class CraftingRecipes { .addMaterial('S', Items.STONE) .checkConfig(Configs.RECIPE_CONFIG) .build(); - GridRecipe.make(BCLib.MOD_ID, "tag_bucket", Items.BUCKET) - .setShape("I I", " I ") - .addMaterial('I', CommonItemTags.IRON_INGOTS) - .checkConfig(Configs.RECIPE_CONFIG) - .build(); GridRecipe.make(BCLib.MOD_ID, "tag_compass", Items.COMPASS) .setShape(" I ", "IDI", " I ") .addMaterial('I', CommonItemTags.IRON_INGOTS) .addMaterial('D', Items.REDSTONE) .checkConfig(Configs.RECIPE_CONFIG) .build(); + GridRecipe.make(BCLib.MOD_ID, "tag_bucket", Items.BUCKET) + .setShape("I I", " I ") + .addMaterial('I', CommonItemTags.IRON_INGOTS) + .checkConfig(Configs.RECIPE_CONFIG) + .build(); GridRecipe.make(BCLib.MOD_ID, "tag_minecart", Items.MINECART) .setShape("I I", "III") .addMaterial('I', CommonItemTags.IRON_INGOTS) diff --git a/src/main/java/org/betterx/bclib/recipes/FurnaceRecipe.java b/src/main/java/org/betterx/bclib/recipes/FurnaceRecipe.java index 617a6506..7980fcd3 100644 --- a/src/main/java/org/betterx/bclib/recipes/FurnaceRecipe.java +++ b/src/main/java/org/betterx/bclib/recipes/FurnaceRecipe.java @@ -7,7 +7,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.*; import net.minecraft.world.level.ItemLike; -public class FurnaceRecipe { +public class FurnaceRecipe extends AbstractAdvancementRecipe { private static final FurnaceRecipe INSTANCE = new FurnaceRecipe(); private ResourceLocation id; @@ -31,6 +31,8 @@ public class FurnaceRecipe { INSTANCE.time = 200; INSTANCE.xp = 0; INSTANCE.exist = BCLRecipeManager.exists(output) && BCLRecipeManager.exists(input); + INSTANCE.createAdvancement(INSTANCE.id, false); + INSTANCE.unlockedBy(input); return INSTANCE; } @@ -84,7 +86,8 @@ public class FurnaceRecipe { xp, time ); - BCLRecipeManager.addRecipeAndCreateAdvancement(RecipeType.SMELTING, recipe, false); + BCLRecipeManager.addRecipe(RecipeType.SMELTING, recipe); + registerAdvancement(recipe); if (blasting) { BlastingRecipe recipe2 = new BlastingRecipe( @@ -95,7 +98,8 @@ public class FurnaceRecipe { xp, time / 2 ); - BCLRecipeManager.addRecipeAndCreateAdvancement(RecipeType.BLASTING, recipe2, false); + BCLRecipeManager.addRecipe(RecipeType.BLASTING, recipe2); + registerAdvancement(recipe2); } if (campfire) { @@ -107,7 +111,9 @@ public class FurnaceRecipe { xp, time * 3 ); - BCLRecipeManager.addRecipeAndCreateAdvancement(RecipeType.CAMPFIRE_COOKING, recipe2, false); + + BCLRecipeManager.addRecipe(RecipeType.CAMPFIRE_COOKING, recipe2); + registerAdvancement(recipe2); } if (smoker) { @@ -119,7 +125,9 @@ public class FurnaceRecipe { xp, time / 2 ); - BCLRecipeManager.addRecipeAndCreateAdvancement(RecipeType.SMOKING, recipe2, false); + + BCLRecipeManager.addRecipe(RecipeType.SMOKING, recipe2); + registerAdvancement(recipe2); } } } diff --git a/src/main/java/org/betterx/bclib/recipes/GridRecipe.java b/src/main/java/org/betterx/bclib/recipes/GridRecipe.java index 855f1587..a7e173f8 100644 --- a/src/main/java/org/betterx/bclib/recipes/GridRecipe.java +++ b/src/main/java/org/betterx/bclib/recipes/GridRecipe.java @@ -17,7 +17,7 @@ import com.google.common.collect.Maps; import java.util.Arrays; import java.util.Map; -public class GridRecipe { +public class GridRecipe extends AbstractAdvancementRecipe { private static final GridRecipe INSTANCE = new GridRecipe(); private ResourceLocation id; @@ -50,7 +50,7 @@ public class GridRecipe { INSTANCE.count = 1; INSTANCE.exist = output != null && BCLRecipeManager.exists(output); - + INSTANCE.createAdvancement(id, output); return INSTANCE; } @@ -76,17 +76,20 @@ public class GridRecipe { } public GridRecipe addMaterial(char key, TagKey value) { + unlockedBy(value); return addMaterial(key, Ingredient.of(value)); } - public GridRecipe addMaterial(char key, ItemStack... value) { - return addMaterial(key, Ingredient.of(Arrays.stream(value))); + public GridRecipe addMaterial(char key, ItemStack... values) { + unlockedBy(values); + return addMaterial(key, Ingredient.of(Arrays.stream(values))); } public GridRecipe addMaterial(char key, ItemLike... values) { for (ItemLike item : values) { exist &= BCLRecipeManager.exists(item); } + unlockedBy(values); return addMaterial(key, Ingredient.of(values)); } @@ -145,6 +148,7 @@ public class GridRecipe { result ) : new ShapelessRecipe(id, group, result, materials); - BCLRecipeManager.addRecipeAndCreateAdvancement(type, recipe); + BCLRecipeManager.addRecipe(type, recipe); + registerAdvancement(recipe); } } diff --git a/src/main/java/org/betterx/bclib/recipes/SmithingTableRecipe.java b/src/main/java/org/betterx/bclib/recipes/SmithingTableRecipe.java index 8f79c63c..425916f8 100644 --- a/src/main/java/org/betterx/bclib/recipes/SmithingTableRecipe.java +++ b/src/main/java/org/betterx/bclib/recipes/SmithingTableRecipe.java @@ -12,7 +12,7 @@ import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.UpgradeRecipe; import net.minecraft.world.level.ItemLike; -public class SmithingTableRecipe { +public class SmithingTableRecipe extends AbstractAdvancementRecipe { private final static SmithingTableRecipe BUILDER = new SmithingTableRecipe(); private final static RecipeType TYPE = RecipeType.SMITHING; @@ -27,7 +27,7 @@ public class SmithingTableRecipe { BUILDER.addition = null; BUILDER.result = null; BUILDER.exist = true; - + BUILDER.createAdvancement(id, false); return BUILDER; } @@ -56,23 +56,27 @@ public class SmithingTableRecipe { } public SmithingTableRecipe setBase(ItemLike... items) { + unlockedBy(items); this.exist &= BCLRecipeManager.exists(items); this.base = Ingredient.of(items); return this; } public SmithingTableRecipe setBase(TagKey tag) { + unlockedBy(tag); this.base = (Ingredient.of(tag)); return this; } public SmithingTableRecipe setAddition(ItemLike... items) { + unlockedBy(items); this.exist &= BCLRecipeManager.exists(items); this.addition = Ingredient.of(items); return this; } public SmithingTableRecipe setAddition(TagKey tag) { + unlockedBy(tag); this.addition = (Ingredient.of(tag)); return this; } @@ -99,6 +103,8 @@ public class SmithingTableRecipe { return; } - BCLRecipeManager.addRecipeAndCreateAdvancement(TYPE, new UpgradeRecipe(id, base, addition, result)); + UpgradeRecipe recipe = new UpgradeRecipe(id, base, addition, result); + BCLRecipeManager.addRecipe(TYPE, recipe); + registerAdvancement(recipe); } }