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 committed 2020-10-09 15:47:32 +02:00
1 parent 5477a36656
commit 59b4affbe7
7 files changed
+201 -12

No files matched your search

@@ -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<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 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<JsonElement> 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);
}
@@ -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<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)
{
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");
this.advId = id;
this.adv = advancement;
@@ -156,6 +180,11 @@ public class ConditionalRecipe
if (recipes.isEmpty())
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));
}
}
@@ -168,7 +197,7 @@ public class ConditionalRecipe
private final ResourceLocation advId;
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.conditions = conditions;