[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 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 <C extends Container, T extends Recipe<C>> 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<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) {
return addInventoryChangedCriterion(
set.baseName + "_" + slot,
@ -352,6 +369,11 @@ public class AdvancementManager {
AdvancementManager.register(id, this.builder);
return this.id;
}
public ResourceLocation buildAndRegister(Map<ResourceLocation, Advancement.Builder> map) {
map.put(id, this.builder);
return this.id;
}
}
public static class DisplayBuilder {

View file

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

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);
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)
);
}
}

View file

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

View file

@ -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)

View file

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

View file

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

View file

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