[Change] Refactored Recipe-Advancement API to prevent #29

This commit is contained in:
Frank 2022-08-01 18:35:32 +02:00
parent 8061049949
commit 35c023692c
10 changed files with 187 additions and 39 deletions

View file

@ -6,15 +6,13 @@ import org.betterx.bclib.complexmaterials.WoodenComplexMaterial;
import org.betterx.bclib.items.complex.EquipmentSet; import org.betterx.bclib.items.complex.EquipmentSet;
import net.minecraft.advancements.*; import net.minecraft.advancements.*;
import net.minecraft.advancements.critereon.InventoryChangeTrigger; import net.minecraft.advancements.critereon.*;
import net.minecraft.advancements.critereon.LocationPredicate;
import net.minecraft.advancements.critereon.PlayerTrigger;
import net.minecraft.advancements.critereon.RecipeUnlockedTrigger;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.data.recipes.RecipeBuilder; import net.minecraft.data.recipes.RecipeBuilder;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.Container; import net.minecraft.world.Container;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -116,6 +114,10 @@ public class AdvancementManager {
this.type = type; this.type = type;
} }
public static Builder createEmptyCopy(Builder builder) {
return new Builder(builder.id, builder.type);
}
public static Builder create(ResourceLocation id) { public static Builder create(ResourceLocation id) {
return new Builder(id, AdvancementType.REGULAR); return new Builder(id, AdvancementType.REGULAR);
} }
@ -169,11 +171,12 @@ public class AdvancementManager {
public static <C extends Container, T extends Recipe<C>> Builder createRecipe(T recipe, AdvancementType type) { public static <C extends Container, T extends Recipe<C>> Builder createRecipe(T recipe, AdvancementType type) {
Item item = recipe.getResultItem().getItem(); Item item = recipe.getResultItem().getItem();
return create(item, type, displayBuilder -> displayBuilder.hideToast().hideFromChat()) return create(item, type, displayBuilder -> displayBuilder.hideToast().hideFromChat())
.awardRecipe(item) //.awardRecipe(item)
.addRecipeUnlockCriterion( .addRecipeUnlockCriterion("has_the_recipe", recipe)
"has_the_recipe", .startReward()
recipe .addRecipe(recipe.getId())
); .endReward()
.requirements(RequirementsStrategy.OR);
} }
public Builder parent(Advancement advancement) { public Builder parent(Advancement advancement) {
@ -277,11 +280,7 @@ public class AdvancementManager {
return addCriterion( return addCriterion(
name, name,
RecipeUnlockedTrigger.unlocked(recipe.getId()) RecipeUnlockedTrigger.unlocked(recipe.getId())
) );
.startReward()
.addRecipe(recipe.getId())
.endReward()
.requirements(RequirementsStrategy.OR);
} }
public Builder addInventoryChangedCriterion(String name, ItemLike... items) { public Builder addInventoryChangedCriterion(String name, ItemLike... items) {
@ -291,6 +290,24 @@ public class AdvancementManager {
); );
} }
public Builder addInventoryChangedCriterion(String name, TagKey<Item> 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) { public Builder addEquipmentSetSlotCriterion(EquipmentSet set, String slot) {
return addInventoryChangedCriterion( return addInventoryChangedCriterion(
set.baseName + "_" + slot, set.baseName + "_" + slot,
@ -352,6 +369,11 @@ public class AdvancementManager {
AdvancementManager.register(id, this.builder); AdvancementManager.register(id, this.builder);
return this.id; return this.id;
} }
public ResourceLocation buildAndRegister(Map<ResourceLocation, Advancement.Builder> map) {
map.put(id, this.builder);
return this.id;
}
} }
public static class DisplayBuilder { public static class DisplayBuilder {

View file

@ -16,7 +16,7 @@ import java.util.Map;
public class ServerAdvancementManagerMixin { public class ServerAdvancementManagerMixin {
@ModifyArg(method = "apply(Ljava/util/Map;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/util/profiling/ProfilerFiller;)V", @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")) at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/AdvancementList;add(Ljava/util/Map;)V"))
public Map<ResourceLocation, Advancement.Builder> wunder_interceptApply(Map<ResourceLocation, Advancement.Builder> map) { public Map<ResourceLocation, Advancement.Builder> bcl_interceptApply(Map<ResourceLocation, Advancement.Builder> map) {
AdvancementManager.addAdvancements(map); AdvancementManager.addAdvancements(map);
return map; return map;
} }

View file

@ -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<ItemLike> 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<Item> 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<Item> 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();
}
}
}

View file

@ -249,10 +249,9 @@ public class AlloyingRecipe implements Recipe<Container>, UnknownReceipBookCateg
BCLib.LOGGER.debug("Can't add Alloying recipe {}! Ingeredient or output not exists.", id); BCLib.LOGGER.debug("Can't add Alloying recipe {}! Ingeredient or output not exists.", id);
return; return;
} }
BCLRecipeManager.addRecipeAndCreateAdvancement( BCLRecipeManager.addRecipe(
TYPE, TYPE,
new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime), new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime)
false
); );
} }
} }

View file

@ -350,10 +350,9 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
BCLib.LOGGER.debug("Can't add Anvil recipe {}! Ingeredient or output not exists.", id); BCLib.LOGGER.debug("Can't add Anvil recipe {}! Ingeredient or output not exists.", id);
return; return;
} }
BCLRecipeManager.addRecipeAndCreateAdvancement( BCLRecipeManager.addRecipe(
TYPE, TYPE,
new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage), new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage)
false
); );
} }
} }

View file

@ -63,6 +63,7 @@ public class BCLRecipeManager {
list.put(recipe.getId(), recipe); list.put(recipe.getId(), recipe);
} }
@Deprecated(forRemoval = true)
public static <C extends Container, T extends Recipe<C>> void addRecipeAndCreateAdvancement( public static <C extends Container, T extends Recipe<C>> void addRecipeAndCreateAdvancement(
RecipeType<T> type, RecipeType<T> type,
T recipe T recipe
@ -71,6 +72,7 @@ public class BCLRecipeManager {
registerAndCreateAdvancement(recipe, recipe.getResultItem().getItem() instanceof TieredItem); registerAndCreateAdvancement(recipe, recipe.getResultItem().getItem() instanceof TieredItem);
} }
@Deprecated(forRemoval = true)
public static <C extends Container, T extends Recipe<C>> void addRecipeAndCreateAdvancement( public static <C extends Container, T extends Recipe<C>> void addRecipeAndCreateAdvancement(
RecipeType<T> type, RecipeType<T> type,
T recipe, T recipe,
@ -80,6 +82,7 @@ public class BCLRecipeManager {
registerAndCreateAdvancement(recipe, isTool); registerAndCreateAdvancement(recipe, isTool);
} }
@Deprecated(forRemoval = true)
public static <C extends Container, T extends Recipe<C>> ResourceLocation registerAndCreateAdvancement( public static <C extends Container, T extends Recipe<C>> ResourceLocation registerAndCreateAdvancement(
T recipe, T recipe,
boolean isTool boolean isTool

View file

@ -48,17 +48,17 @@ public class CraftingRecipes {
.addMaterial('S', Items.STONE) .addMaterial('S', Items.STONE)
.checkConfig(Configs.RECIPE_CONFIG) .checkConfig(Configs.RECIPE_CONFIG)
.build(); .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) GridRecipe.make(BCLib.MOD_ID, "tag_compass", Items.COMPASS)
.setShape(" I ", "IDI", " I ") .setShape(" I ", "IDI", " I ")
.addMaterial('I', CommonItemTags.IRON_INGOTS) .addMaterial('I', CommonItemTags.IRON_INGOTS)
.addMaterial('D', Items.REDSTONE) .addMaterial('D', Items.REDSTONE)
.checkConfig(Configs.RECIPE_CONFIG) .checkConfig(Configs.RECIPE_CONFIG)
.build(); .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) GridRecipe.make(BCLib.MOD_ID, "tag_minecart", Items.MINECART)
.setShape("I I", "III") .setShape("I I", "III")
.addMaterial('I', CommonItemTags.IRON_INGOTS) .addMaterial('I', CommonItemTags.IRON_INGOTS)

View file

@ -7,7 +7,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.*; import net.minecraft.world.item.crafting.*;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
public class FurnaceRecipe { public class FurnaceRecipe extends AbstractAdvancementRecipe {
private static final FurnaceRecipe INSTANCE = new FurnaceRecipe(); private static final FurnaceRecipe INSTANCE = new FurnaceRecipe();
private ResourceLocation id; private ResourceLocation id;
@ -31,6 +31,8 @@ public class FurnaceRecipe {
INSTANCE.time = 200; INSTANCE.time = 200;
INSTANCE.xp = 0; INSTANCE.xp = 0;
INSTANCE.exist = BCLRecipeManager.exists(output) && BCLRecipeManager.exists(input); INSTANCE.exist = BCLRecipeManager.exists(output) && BCLRecipeManager.exists(input);
INSTANCE.createAdvancement(INSTANCE.id, false);
INSTANCE.unlockedBy(input);
return INSTANCE; return INSTANCE;
} }
@ -84,7 +86,8 @@ public class FurnaceRecipe {
xp, xp,
time time
); );
BCLRecipeManager.addRecipeAndCreateAdvancement(RecipeType.SMELTING, recipe, false); BCLRecipeManager.addRecipe(RecipeType.SMELTING, recipe);
registerAdvancement(recipe);
if (blasting) { if (blasting) {
BlastingRecipe recipe2 = new BlastingRecipe( BlastingRecipe recipe2 = new BlastingRecipe(
@ -95,7 +98,8 @@ public class FurnaceRecipe {
xp, xp,
time / 2 time / 2
); );
BCLRecipeManager.addRecipeAndCreateAdvancement(RecipeType.BLASTING, recipe2, false); BCLRecipeManager.addRecipe(RecipeType.BLASTING, recipe2);
registerAdvancement(recipe2);
} }
if (campfire) { if (campfire) {
@ -107,7 +111,9 @@ public class FurnaceRecipe {
xp, xp,
time * 3 time * 3
); );
BCLRecipeManager.addRecipeAndCreateAdvancement(RecipeType.CAMPFIRE_COOKING, recipe2, false);
BCLRecipeManager.addRecipe(RecipeType.CAMPFIRE_COOKING, recipe2);
registerAdvancement(recipe2);
} }
if (smoker) { if (smoker) {
@ -119,7 +125,9 @@ public class FurnaceRecipe {
xp, xp,
time / 2 time / 2
); );
BCLRecipeManager.addRecipeAndCreateAdvancement(RecipeType.SMOKING, recipe2, false);
BCLRecipeManager.addRecipe(RecipeType.SMOKING, recipe2);
registerAdvancement(recipe2);
} }
} }
} }

View file

@ -17,7 +17,7 @@ import com.google.common.collect.Maps;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
public class GridRecipe { public class GridRecipe extends AbstractAdvancementRecipe {
private static final GridRecipe INSTANCE = new GridRecipe(); private static final GridRecipe INSTANCE = new GridRecipe();
private ResourceLocation id; private ResourceLocation id;
@ -50,7 +50,7 @@ public class GridRecipe {
INSTANCE.count = 1; INSTANCE.count = 1;
INSTANCE.exist = output != null && BCLRecipeManager.exists(output); INSTANCE.exist = output != null && BCLRecipeManager.exists(output);
INSTANCE.createAdvancement(id, output);
return INSTANCE; return INSTANCE;
} }
@ -76,17 +76,20 @@ public class GridRecipe {
} }
public GridRecipe addMaterial(char key, TagKey<Item> value) { public GridRecipe addMaterial(char key, TagKey<Item> value) {
unlockedBy(value);
return addMaterial(key, Ingredient.of(value)); return addMaterial(key, Ingredient.of(value));
} }
public GridRecipe addMaterial(char key, ItemStack... value) { public GridRecipe addMaterial(char key, ItemStack... values) {
return addMaterial(key, Ingredient.of(Arrays.stream(value))); unlockedBy(values);
return addMaterial(key, Ingredient.of(Arrays.stream(values)));
} }
public GridRecipe addMaterial(char key, ItemLike... values) { public GridRecipe addMaterial(char key, ItemLike... values) {
for (ItemLike item : values) { for (ItemLike item : values) {
exist &= BCLRecipeManager.exists(item); exist &= BCLRecipeManager.exists(item);
} }
unlockedBy(values);
return addMaterial(key, Ingredient.of(values)); return addMaterial(key, Ingredient.of(values));
} }
@ -145,6 +148,7 @@ public class GridRecipe {
result result
) : new ShapelessRecipe(id, group, result, materials); ) : new ShapelessRecipe(id, group, result, materials);
BCLRecipeManager.addRecipeAndCreateAdvancement(type, recipe); BCLRecipeManager.addRecipe(type, recipe);
registerAdvancement(recipe);
} }
} }

View file

@ -12,7 +12,7 @@ import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.UpgradeRecipe; import net.minecraft.world.item.crafting.UpgradeRecipe;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
public class SmithingTableRecipe { public class SmithingTableRecipe extends AbstractAdvancementRecipe {
private final static SmithingTableRecipe BUILDER = new SmithingTableRecipe(); private final static SmithingTableRecipe BUILDER = new SmithingTableRecipe();
private final static RecipeType<UpgradeRecipe> TYPE = RecipeType.SMITHING; private final static RecipeType<UpgradeRecipe> TYPE = RecipeType.SMITHING;
@ -27,7 +27,7 @@ public class SmithingTableRecipe {
BUILDER.addition = null; BUILDER.addition = null;
BUILDER.result = null; BUILDER.result = null;
BUILDER.exist = true; BUILDER.exist = true;
BUILDER.createAdvancement(id, false);
return BUILDER; return BUILDER;
} }
@ -56,23 +56,27 @@ public class SmithingTableRecipe {
} }
public SmithingTableRecipe setBase(ItemLike... items) { public SmithingTableRecipe setBase(ItemLike... items) {
unlockedBy(items);
this.exist &= BCLRecipeManager.exists(items); this.exist &= BCLRecipeManager.exists(items);
this.base = Ingredient.of(items); this.base = Ingredient.of(items);
return this; return this;
} }
public SmithingTableRecipe setBase(TagKey<Item> tag) { public SmithingTableRecipe setBase(TagKey<Item> tag) {
unlockedBy(tag);
this.base = (Ingredient.of(tag)); this.base = (Ingredient.of(tag));
return this; return this;
} }
public SmithingTableRecipe setAddition(ItemLike... items) { public SmithingTableRecipe setAddition(ItemLike... items) {
unlockedBy(items);
this.exist &= BCLRecipeManager.exists(items); this.exist &= BCLRecipeManager.exists(items);
this.addition = Ingredient.of(items); this.addition = Ingredient.of(items);
return this; return this;
} }
public SmithingTableRecipe setAddition(TagKey<Item> tag) { public SmithingTableRecipe setAddition(TagKey<Item> tag) {
unlockedBy(tag);
this.addition = (Ingredient.of(tag)); this.addition = (Ingredient.of(tag));
return this; return this;
} }
@ -99,6 +103,8 @@ public class SmithingTableRecipe {
return; return;
} }
BCLRecipeManager.addRecipeAndCreateAdvancement(TYPE, new UpgradeRecipe(id, base, addition, result)); UpgradeRecipe recipe = new UpgradeRecipe(id, base, addition, result);
BCLRecipeManager.addRecipe(TYPE, recipe);
registerAdvancement(recipe);
} }
} }