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.
This commit is contained in:
David Quintana 2020-10-09 15:47:32 +02:00
parent 5477a36656
commit 59b4affbe7
7 changed files with 201 additions and 12 deletions

View file

@ -4,7 +4,7 @@
} }
public static Advancement.Builder func_241043_a_(JsonObject p_241043_0_, ConditionArrayParser p_241043_1_) { 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; 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; 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; AdvancementRewards advancementrewards = p_241043_0_.has("rewards") ? AdvancementRewards.func_241096_a_(JSONUtils.func_152754_s(p_241043_0_, "rewards")) : AdvancementRewards.field_192114_a;

View file

@ -69,7 +69,9 @@ f51f026a75e27a0a53a76771d553c0e3385a2966 assets/piston_event_test/models/item/sh
cf16f861eaf5815238c2278eb48bde0688cb73b7 assets/scaffolding_test/blockstates/scaffolding_method_test.json cf16f861eaf5815238c2278eb48bde0688cb73b7 assets/scaffolding_test/blockstates/scaffolding_method_test.json
862196702dcd5538c5ceb4ac6202e57eb5c8a97f data/custom_tag_types_test/tags/custom_tag_types_test/custom_types/tests.json 862196702dcd5538c5ceb4ac6202e57eb5c8a97f data/custom_tag_types_test/tags/custom_tag_types_test/custom_types/tests.json
4fbaf6f4a3ea05cc071076e27f44ac81f9cc50e3 data/data_gen_test/advancements/conditional.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 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 40208299608468b044f64317995f9182ec219d90 data/data_gen_test/tags/blocks/test.json
d65c425e740dc833f29d16606a1171825876be0d data/data_gen_test/tags/blocks/thing/one.json d65c425e740dc833f29d16606a1171825876be0d data/data_gen_test/tags/blocks/thing/one.json
1f70ed4ddc878bada5e43d3c44a34157806beda8 data/data_gen_test/tags/blocks/thing/three.json 1f70ed4ddc878bada5e43d3c44a34157806beda8 data/data_gen_test/tags/blocks/thing/three.json

View file

@ -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"
]
]
}
}
]
}

View file

@ -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
}
}
}
]
}

View file

@ -22,6 +22,7 @@ package net.minecraftforge.common.crafting;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@ -29,9 +30,12 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import net.minecraft.advancements.Advancement; import net.minecraft.advancements.Advancement;
import net.minecraft.data.IFinishedRecipe;
import net.minecraft.util.JSONUtils; import net.minecraft.util.JSONUtils;
import net.minecraftforge.common.crafting.conditions.ICondition; import net.minecraftforge.common.crafting.conditions.ICondition;
import javax.annotation.Nullable;
public class ConditionalAdvancement public class ConditionalAdvancement
{ {
public static Builder builder() public static Builder builder()
@ -39,11 +43,22 @@ public class ConditionalAdvancement
return new Builder(); return new Builder();
} }
@Deprecated
public static boolean processConditions(JsonObject json) { 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); JsonArray entries = JSONUtils.getJsonArray(json, "advancements", null);
if (entries == null) if (entries == null)
{ {
return CraftingHelper.processConditions(json, "conditions"); return CraftingHelper.processConditions(json, "conditions") ? json : null;
} }
int idx = 0; int idx = 0;
@ -52,16 +67,16 @@ public class ConditionalAdvancement
if (!ele.isJsonObject()) if (!ele.isJsonObject())
throw new JsonSyntaxException("Invalid advancement entry at index " + idx + " Must be JsonObject"); throw new JsonSyntaxException("Invalid advancement entry at index " + idx + " Must be JsonObject");
if (CraftingHelper.processConditions(JSONUtils.getJsonArray(ele.getAsJsonObject(), "conditions"))) if (CraftingHelper.processConditions(JSONUtils.getJsonArray(ele.getAsJsonObject(), "conditions")))
return true; return JSONUtils.getJsonObject(ele.getAsJsonObject(), "advancement");
idx++; idx++;
} }
return false; return null;
} }
public static class Builder public static class Builder
{ {
private List<ICondition[]> conditions = new ArrayList<>(); private List<ICondition[]> conditions = new ArrayList<>();
private List<Advancement.Builder> advancements = new ArrayList<>(); private List<Supplier<JsonElement>> advancements = new ArrayList<>();
private List<ICondition> currentConditions = new ArrayList<>(); private List<ICondition> currentConditions = new ArrayList<>();
private boolean locked = false; private boolean locked = false;
@ -82,14 +97,24 @@ public class ConditionalAdvancement
return this; 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<JsonElement> jsonSupplier)
{ {
if (locked) if (locked)
throw new IllegalStateException("Attempted to modify finished builder"); throw new IllegalStateException("Attempted to modify finished builder");
if (currentConditions.isEmpty()) if (currentConditions.isEmpty())
throw new IllegalStateException("Can not add a advancement with no conditions."); throw new IllegalStateException("Can not add a advancement with no conditions.");
conditions.add(currentConditions.toArray(new ICondition[currentConditions.size()])); conditions.add(currentConditions.toArray(new ICondition[currentConditions.size()]));
advancements.add(recipe); advancements.add(jsonSupplier);
currentConditions.clear(); currentConditions.clear();
return this; return this;
} }
@ -115,7 +140,7 @@ public class ConditionalAdvancement
for (ICondition c : conditions.get(x)) for (ICondition c : conditions.get(x))
conds.add(CraftingHelper.serialize(c)); conds.add(CraftingHelper.serialize(c));
holder.add("conditions", conds); holder.add("conditions", conds);
holder.add("advancement", advancements.get(x).serialize()); holder.add("advancement", advancements.get(x).get());
array.add(holder); array.add(holder);
} }

View file

@ -38,6 +38,8 @@ import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.crafting.conditions.ICondition; import net.minecraftforge.common.crafting.conditions.ICondition;
import net.minecraftforge.registries.ObjectHolder; import net.minecraftforge.registries.ObjectHolder;
import javax.annotation.Nullable;
public class ConditionalRecipe public class ConditionalRecipe
{ {
@ObjectHolder("forge:conditional") @ObjectHolder("forge:conditional")
@ -130,14 +132,36 @@ public class ConditionalRecipe
return this; return this;
} }
public Builder generateAdvancement()
{
return generateAdvancement(null);
}
public Builder generateAdvancement(@Nullable ResourceLocation id)
{
ConditionalAdvancement.Builder builder = ConditionalAdvancement.builder();
for(int i=0;i<recipes.size();i++)
{
for(ICondition cond : conditions.get(i))
builder = builder.addCondition(cond);
builder = builder.addAdvancement(recipes.get(i));
}
return setAdvancement(id, builder);
}
public Builder setAdvancement(ConditionalAdvancement.Builder advancement)
{
return setAdvancement(null, advancement);
}
public Builder setAdvancement(String namespace, String path, ConditionalAdvancement.Builder advancement) public Builder setAdvancement(String namespace, String path, ConditionalAdvancement.Builder advancement)
{ {
return setAdvancement(new ResourceLocation(namespace, path), advancement); return setAdvancement(new ResourceLocation(namespace, path), advancement);
} }
public Builder setAdvancement(ResourceLocation id, ConditionalAdvancement.Builder advancement) public Builder setAdvancement(@Nullable ResourceLocation id, ConditionalAdvancement.Builder advancement)
{ {
if (this.advId != null) if (this.adv != null)
throw new IllegalStateException("Invalid ConditionalRecipeBuilder, Advancement already set"); throw new IllegalStateException("Invalid ConditionalRecipeBuilder, Advancement already set");
this.advId = id; this.advId = id;
this.adv = advancement; this.adv = advancement;
@ -156,6 +180,11 @@ public class ConditionalRecipe
if (recipes.isEmpty()) if (recipes.isEmpty())
throw new IllegalStateException("Invalid ConditionalRecipe builder, No recipes"); throw new IllegalStateException("Invalid ConditionalRecipe builder, No recipes");
if (advId == null && adv != null)
{
advId = new ResourceLocation(id.getNamespace(), "recipes/" + id.getPath());
}
consumer.accept(new Finished(id, conditions, recipes, advId, adv)); consumer.accept(new Finished(id, conditions, recipes, advId, adv));
} }
} }
@ -168,7 +197,7 @@ public class ConditionalRecipe
private final ResourceLocation advId; private final ResourceLocation advId;
private final ConditionalAdvancement.Builder adv; private final ConditionalAdvancement.Builder adv;
private Finished(ResourceLocation id, List<ICondition[]> conditions, List<IFinishedRecipe> recipes, ResourceLocation advId, ConditionalAdvancement.Builder adv) private Finished(ResourceLocation id, List<ICondition[]> conditions, List<IFinishedRecipe> recipes, @Nullable ResourceLocation advId, @Nullable ConditionalAdvancement.Builder adv)
{ {
this.id = id; this.id = id;
this.conditions = conditions; this.conditions = conditions;

View file

@ -150,7 +150,7 @@ public class DataGeneratorTest
.patternLine("XXX") .patternLine("XXX")
.key('X', Blocks.DIRT) .key('X', Blocks.DIRT)
.setGroup("") .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 ::build
) )
.setAdvancement(ID, .setAdvancement(ID,
@ -175,6 +175,29 @@ public class DataGeneratorTest
) )
) )
.build(consumer, ID); .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"));
} }
} }