From 59b4affbe750c03d3a94f31050c2523f0caebbdd Mon Sep 17 00:00:00 2001 From: David Quintana Date: Fri, 9 Oct 2020 15:47:32 +0200 Subject: [PATCH] Fixed conditional advancement loading when using the "advancements" array. Added automatic generation of conditional advancements from the criteria in the conditional recipe entries. Added advancement name calculation from the recipe ID. --- .../advancements/Advancement.java.patch | 2 +- src/generated_test/resources/.cache/cache | 2 + .../advancements/recipes/conditional2.json | 62 +++++++++++++++++++ .../data_gen_test/recipes/conditional2.json | 48 ++++++++++++++ .../crafting/ConditionalAdvancement.java | 39 +++++++++--- .../common/crafting/ConditionalRecipe.java | 35 ++++++++++- .../debug/DataGeneratorTest.java | 25 +++++++- 7 files changed, 201 insertions(+), 12 deletions(-) create mode 100644 src/generated_test/resources/data/data_gen_test/advancements/recipes/conditional2.json create mode 100644 src/generated_test/resources/data/data_gen_test/recipes/conditional2.json diff --git a/patches/minecraft/net/minecraft/advancements/Advancement.java.patch b/patches/minecraft/net/minecraft/advancements/Advancement.java.patch index 00ab2f733..fa4606093 100644 --- a/patches/minecraft/net/minecraft/advancements/Advancement.java.patch +++ b/patches/minecraft/net/minecraft/advancements/Advancement.java.patch @@ -4,7 +4,7 @@ } public static Advancement.Builder func_241043_a_(JsonObject p_241043_0_, ConditionArrayParser p_241043_1_) { -+ if (!net.minecraftforge.common.crafting.ConditionalAdvancement.processConditions(p_241043_0_)) return null; ++ if ((p_241043_0_ = net.minecraftforge.common.crafting.ConditionalAdvancement.processConditional(p_241043_0_)) == null) return null; ResourceLocation resourcelocation = p_241043_0_.has("parent") ? new ResourceLocation(JSONUtils.func_151200_h(p_241043_0_, "parent")) : null; DisplayInfo displayinfo = p_241043_0_.has("display") ? DisplayInfo.func_192294_a(JSONUtils.func_152754_s(p_241043_0_, "display")) : null; AdvancementRewards advancementrewards = p_241043_0_.has("rewards") ? AdvancementRewards.func_241096_a_(JSONUtils.func_152754_s(p_241043_0_, "rewards")) : AdvancementRewards.field_192114_a; diff --git a/src/generated_test/resources/.cache/cache b/src/generated_test/resources/.cache/cache index 77d64f79f..607f36b50 100644 --- a/src/generated_test/resources/.cache/cache +++ b/src/generated_test/resources/.cache/cache @@ -69,7 +69,9 @@ f51f026a75e27a0a53a76771d553c0e3385a2966 assets/piston_event_test/models/item/sh cf16f861eaf5815238c2278eb48bde0688cb73b7 assets/scaffolding_test/blockstates/scaffolding_method_test.json 862196702dcd5538c5ceb4ac6202e57eb5c8a97f data/custom_tag_types_test/tags/custom_tag_types_test/custom_types/tests.json 4fbaf6f4a3ea05cc071076e27f44ac81f9cc50e3 data/data_gen_test/advancements/conditional.json +66442c8000af9af4ba36109b3c9d09d9ffd57277 data/data_gen_test/advancements/recipes/conditional2.json ed4cbf1a3a2f5d8969f6346fdc9acdbe81d0c919 data/data_gen_test/recipes/conditional.json +ca9827bff0a49957e01cf3887ef5131ad8710320 data/data_gen_test/recipes/conditional2.json 40208299608468b044f64317995f9182ec219d90 data/data_gen_test/tags/blocks/test.json d65c425e740dc833f29d16606a1171825876be0d data/data_gen_test/tags/blocks/thing/one.json 1f70ed4ddc878bada5e43d3c44a34157806beda8 data/data_gen_test/tags/blocks/thing/three.json diff --git a/src/generated_test/resources/data/data_gen_test/advancements/recipes/conditional2.json b/src/generated_test/resources/data/data_gen_test/advancements/recipes/conditional2.json new file mode 100644 index 000000000..302cf5ff9 --- /dev/null +++ b/src/generated_test/resources/data/data_gen_test/advancements/recipes/conditional2.json @@ -0,0 +1,62 @@ +{ + "advancements": [ + { + "conditions": [ + { + "value": { + "values": [ + { + "value": { + "modid": "minecraft", + "type": "forge:mod_loaded" + }, + "type": "forge:not" + }, + { + "item": "minecraft:dirt", + "type": "forge:item_exists" + }, + { + "type": "forge:false" + } + ], + "type": "forge:and" + }, + "type": "forge:not" + } + ], + "advancement": { + "parent": "minecraft:recipes/root", + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + }, + "criteria": { + "has_dirt": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "minecraft:dirt" + } + ] + } + }, + "has_the_recipe": { + "trigger": "minecraft:recipe_unlocked", + "conditions": { + "recipe": "minecraft:diamond_block" + } + } + }, + "requirements": [ + [ + "has_dirt", + "has_the_recipe" + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/src/generated_test/resources/data/data_gen_test/recipes/conditional2.json b/src/generated_test/resources/data/data_gen_test/recipes/conditional2.json new file mode 100644 index 000000000..7a49e3baf --- /dev/null +++ b/src/generated_test/resources/data/data_gen_test/recipes/conditional2.json @@ -0,0 +1,48 @@ +{ + "type": "forge:conditional", + "recipes": [ + { + "conditions": [ + { + "value": { + "values": [ + { + "value": { + "modid": "minecraft", + "type": "forge:mod_loaded" + }, + "type": "forge:not" + }, + { + "item": "minecraft:dirt", + "type": "forge:item_exists" + }, + { + "type": "forge:false" + } + ], + "type": "forge:and" + }, + "type": "forge:not" + } + ], + "recipe": { + "type": "minecraft:crafting_shaped", + "pattern": [ + "XXX", + "XXX", + "XXX" + ], + "key": { + "X": { + "item": "minecraft:dirt" + } + }, + "result": { + "item": "minecraft:diamond_block", + "count": 64 + } + } + } + ] +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/common/crafting/ConditionalAdvancement.java b/src/main/java/net/minecraftforge/common/crafting/ConditionalAdvancement.java index 79e45efb2..d945cf038 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ConditionalAdvancement.java +++ b/src/main/java/net/minecraftforge/common/crafting/ConditionalAdvancement.java @@ -22,6 +22,7 @@ package net.minecraftforge.common.crafting; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; +import java.util.function.Supplier; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -29,9 +30,12 @@ import com.google.gson.JsonObject; import com.google.gson.JsonSyntaxException; import net.minecraft.advancements.Advancement; +import net.minecraft.data.IFinishedRecipe; import net.minecraft.util.JSONUtils; import net.minecraftforge.common.crafting.conditions.ICondition; +import javax.annotation.Nullable; + public class ConditionalAdvancement { public static Builder builder() @@ -39,11 +43,22 @@ public class ConditionalAdvancement return new Builder(); } + @Deprecated public static boolean processConditions(JsonObject json) { + return processConditional(json) != null; + } + + /** + * Processes the conditional advancement during loading. + * @param json The incoming json from the advancement file. + * @return The advancement that passed the conditions, or null if none did. + */ + @Nullable + public static JsonObject processConditional(JsonObject json) { JsonArray entries = JSONUtils.getJsonArray(json, "advancements", null); if (entries == null) { - return CraftingHelper.processConditions(json, "conditions"); + return CraftingHelper.processConditions(json, "conditions") ? json : null; } int idx = 0; @@ -52,16 +67,16 @@ public class ConditionalAdvancement if (!ele.isJsonObject()) throw new JsonSyntaxException("Invalid advancement entry at index " + idx + " Must be JsonObject"); if (CraftingHelper.processConditions(JSONUtils.getJsonArray(ele.getAsJsonObject(), "conditions"))) - return true; + return JSONUtils.getJsonObject(ele.getAsJsonObject(), "advancement"); idx++; } - return false; + return null; } public static class Builder { private List conditions = new ArrayList<>(); - private List advancements = new ArrayList<>(); + private List> advancements = new ArrayList<>(); private List currentConditions = new ArrayList<>(); private boolean locked = false; @@ -82,14 +97,24 @@ public class ConditionalAdvancement return this; } - public Builder addAdvancement(Advancement.Builder recipe) + public Builder addAdvancement(Advancement.Builder advancement) + { + return addAdvancement(advancement::serialize); + } + + public Builder addAdvancement(IFinishedRecipe fromRecipe) + { + return addAdvancement(fromRecipe::getAdvancementJson); + } + + private Builder addAdvancement(Supplier jsonSupplier) { if (locked) throw new IllegalStateException("Attempted to modify finished builder"); if (currentConditions.isEmpty()) throw new IllegalStateException("Can not add a advancement with no conditions."); conditions.add(currentConditions.toArray(new ICondition[currentConditions.size()])); - advancements.add(recipe); + advancements.add(jsonSupplier); currentConditions.clear(); return this; } @@ -115,7 +140,7 @@ public class ConditionalAdvancement for (ICondition c : conditions.get(x)) conds.add(CraftingHelper.serialize(c)); holder.add("conditions", conds); - holder.add("advancement", advancements.get(x).serialize()); + holder.add("advancement", advancements.get(x).get()); array.add(holder); } diff --git a/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java b/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java index 2853f2a3a..be1681467 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java +++ b/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java @@ -38,6 +38,8 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.crafting.conditions.ICondition; import net.minecraftforge.registries.ObjectHolder; +import javax.annotation.Nullable; + public class ConditionalRecipe { @ObjectHolder("forge:conditional") @@ -130,14 +132,36 @@ public class ConditionalRecipe return this; } + public Builder generateAdvancement() + { + return generateAdvancement(null); + } + + public Builder generateAdvancement(@Nullable ResourceLocation id) + { + ConditionalAdvancement.Builder builder = ConditionalAdvancement.builder(); + for(int i=0;i conditions, List recipes, ResourceLocation advId, ConditionalAdvancement.Builder adv) + private Finished(ResourceLocation id, List conditions, List recipes, @Nullable ResourceLocation advId, @Nullable ConditionalAdvancement.Builder adv) { this.id = id; this.conditions = conditions; diff --git a/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java b/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java index 3931c7b13..54c273dc1 100644 --- a/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java +++ b/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java @@ -150,7 +150,7 @@ public class DataGeneratorTest .patternLine("XXX") .key('X', Blocks.DIRT) .setGroup("") - .addCriterion("has_dirt", hasItem(Blocks.DIRT)) //Doesn't actually print... TODO: nested/conditional advancements? + .addCriterion("has_dirt", hasItem(Blocks.DIRT)) // DUMMY: Necessary, but not used when a custom advancement is provided through setAdvancement ::build ) .setAdvancement(ID, @@ -175,6 +175,29 @@ public class DataGeneratorTest ) ) .build(consumer, ID); + + ConditionalRecipe.builder() + .addCondition( + not( + and( + not(modLoaded("minecraft")), + itemExists("minecraft", "dirt"), + FALSE() + ) + ) + ) + .addRecipe( + ShapedRecipeBuilder.shapedRecipe(Blocks.DIAMOND_BLOCK, 64) + .patternLine("XXX") + .patternLine("XXX") + .patternLine("XXX") + .key('X', Blocks.DIRT) + .setGroup("") + .addCriterion("has_dirt", hasItem(Blocks.DIRT)) + ::build + ) + .generateAdvancement() + .build(consumer, new ResourceLocation("data_gen_test", "conditional2")); } }