mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 00:37:52 +00:00
Fix TagEmptyCondition by passing tag context into conditional and recipe deserializers. (#8546)
This commit is contained in:
1 parent
1f031ad2c3
commit
87c4f90fb2
21 files changed
+473
-22
No files matched your search
@@ -29,17 +29,26 @@ public class ConditionalAdvancement
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@linkplain #processConditional(JsonObject, ICondition.IContext) the more general overload}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
@Nullable
|
||||
public static JsonObject processConditional(JsonObject json) {
|
||||
return processConditional(json, ICondition.IContext.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
public static JsonObject processConditional(JsonObject json, ICondition.IContext context) {
|
||||
JsonArray entries = GsonHelper.getAsJsonArray(json, "advancements", null);
|
||||
if (entries == null)
|
||||
{
|
||||
return CraftingHelper.processConditions(json, "conditions") ? json : null;
|
||||
return CraftingHelper.processConditions(json, "conditions", context) ? json : null;
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
@@ -47,7 +56,7 @@ public class ConditionalAdvancement
|
||||
{
|
||||
if (!ele.isJsonObject())
|
||||
throw new JsonSyntaxException("Invalid advancement entry at index " + idx + " Must be JsonObject");
|
||||
if (CraftingHelper.processConditions(GsonHelper.getAsJsonArray(ele.getAsJsonObject(), "conditions")))
|
||||
if (CraftingHelper.processConditions(GsonHelper.getAsJsonArray(ele.getAsJsonObject(), "conditions"), context))
|
||||
return GsonHelper.getAsJsonObject(ele.getAsJsonObject(), "advancement");
|
||||
idx++;
|
||||
}
|
||||
|
||||
@@ -65,9 +65,15 @@ public class ConditionalRecipe
|
||||
return (Class<G>)cls;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // We return a nested one, so we can't know what type it is.
|
||||
@Override
|
||||
public T fromJson(ResourceLocation recipeId, JsonObject json)
|
||||
{
|
||||
return fromJson(recipeId, json, ICondition.IContext.EMPTY);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // We return a nested one, so we can't know what type it is.
|
||||
@Override
|
||||
public T fromJson(ResourceLocation recipeId, JsonObject json, ICondition.IContext context)
|
||||
{
|
||||
JsonArray items = GsonHelper.getAsJsonArray(json, "recipes");
|
||||
int idx = 0;
|
||||
@@ -75,7 +81,7 @@ public class ConditionalRecipe
|
||||
{
|
||||
if (!ele.isJsonObject())
|
||||
throw new JsonSyntaxException("Invalid recipes entry at index " + idx + " Must be JsonObject");
|
||||
if (CraftingHelper.processConditions(GsonHelper.getAsJsonArray(ele.getAsJsonObject(), "conditions")))
|
||||
if (CraftingHelper.processConditions(GsonHelper.getAsJsonArray(ele.getAsJsonObject(), "conditions"), context))
|
||||
return (T)RecipeManager.fromJson(recipeId, GsonHelper.getAsJsonObject(ele.getAsJsonObject(), "recipe"));
|
||||
idx++;
|
||||
}
|
||||
|
||||
@@ -199,12 +199,30 @@ public class CraftingHelper
|
||||
return new ItemStack(item, GsonHelper.getAsInt(json, "count", 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use the {@linkplain #processConditions(JsonObject, String, ICondition.IContext) other more general overload}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
public static boolean processConditions(JsonObject json, String memberName)
|
||||
{
|
||||
return !json.has(memberName) || processConditions(GsonHelper.getAsJsonArray(json, memberName));
|
||||
return processConditions(json, memberName, ICondition.IContext.EMPTY);
|
||||
}
|
||||
|
||||
public static boolean processConditions(JsonObject json, String memberName, ICondition.IContext context)
|
||||
{
|
||||
return !json.has(memberName) || processConditions(GsonHelper.getAsJsonArray(json, memberName), context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use the {@linkplain #processConditions(JsonArray, ICondition.IContext) other more general overload}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
public static boolean processConditions(JsonArray conditions)
|
||||
{
|
||||
return processConditions(conditions, ICondition.IContext.EMPTY);
|
||||
}
|
||||
|
||||
public static boolean processConditions(JsonArray conditions, ICondition.IContext context)
|
||||
{
|
||||
for (int x = 0; x < conditions.size(); x++)
|
||||
{
|
||||
@@ -212,7 +230,7 @@ public class CraftingHelper
|
||||
throw new JsonSyntaxException("Conditions must be an array of JsonObjects");
|
||||
|
||||
JsonObject json = conditions.get(x).getAsJsonObject();
|
||||
if (!CraftingHelper.getCondition(json).test())
|
||||
if (!CraftingHelper.getCondition(json).test(context))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -45,10 +45,16 @@ public class AndCondition implements ICondition
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
return test(IContext.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(IContext context)
|
||||
{
|
||||
for (ICondition child : children)
|
||||
{
|
||||
if (!child.test())
|
||||
if (!child.test(context))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Minecraft Forge - Forge Development LLC
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConditionContext implements ICondition.IContext
|
||||
{
|
||||
private final TagManager tagManager;
|
||||
private Map<ResourceKey<?>, Map<ResourceLocation, Tag<Holder<?>>>> loadedTags = null;
|
||||
|
||||
public ConditionContext(TagManager tagManager)
|
||||
{
|
||||
this.tagManager = tagManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Map<ResourceLocation, Tag<Holder<T>>> getAllTags(ResourceKey<? extends Registry<T>> registry)
|
||||
{
|
||||
if (loadedTags == null)
|
||||
{
|
||||
var tags = tagManager.getResult();
|
||||
if (tags.isEmpty()) throw new IllegalStateException("Tags have not been loaded yet.");
|
||||
|
||||
loadedTags = new IdentityHashMap<>();
|
||||
for (var loadResult : tags)
|
||||
{
|
||||
loadedTags.put(loadResult.key(), (Map) Collections.unmodifiableMap(loadResult.tags()));
|
||||
}
|
||||
}
|
||||
return (Map) loadedTags.getOrDefault(registry, Collections.emptyMap());
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,54 @@
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagKey;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public interface ICondition
|
||||
{
|
||||
ResourceLocation getID();
|
||||
|
||||
default boolean test(IContext context)
|
||||
{
|
||||
return test();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@linkplain #test(IContext) the other more general overload}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
boolean test();
|
||||
|
||||
interface IContext
|
||||
{
|
||||
IContext EMPTY = new IContext()
|
||||
{
|
||||
@Override
|
||||
public <T> Map<ResourceLocation, Tag<Holder<T>>> getAllTags(ResourceKey<? extends Registry<T>> registry)
|
||||
{
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the requested tag if available, or an empty tag otherwise.
|
||||
*/
|
||||
default <T> Tag<Holder<T>> getTag(TagKey<T> key)
|
||||
{
|
||||
return getAllTags(key.registry()).getOrDefault(key.location(), Tag.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the loaded tags for the passed registry, or an empty map if none is available.
|
||||
* Note that the map and the tags are unmodifiable.
|
||||
*/
|
||||
<T> Map<ResourceLocation, Tag<Holder<T>>> getAllTags(ResourceKey<? extends Registry<T>> registry);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
public interface IConditionBuilder
|
||||
{
|
||||
default ICondition and(ICondition... values)
|
||||
@@ -41,4 +44,9 @@ public interface IConditionBuilder
|
||||
{
|
||||
return new ModLoadedCondition(modid);
|
||||
}
|
||||
|
||||
default ICondition tagEmpty(TagKey<Item> tag)
|
||||
{
|
||||
return new TagEmptyCondition(tag.location());
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,13 @@ public class NotCondition implements ICondition
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
return !child.test();
|
||||
return test(IContext.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(IContext context)
|
||||
{
|
||||
return !child.test(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,10 +45,16 @@ public class OrCondition implements ICondition
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
return test(IContext.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(IContext context)
|
||||
{
|
||||
for (ICondition child : children)
|
||||
{
|
||||
if (child.test())
|
||||
if (child.test(context))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,15 +7,12 @@ package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class TagEmptyCondition implements ICondition
|
||||
{
|
||||
private static final ResourceLocation NAME = new ResourceLocation("forge", "tag_empty");
|
||||
@@ -42,10 +39,16 @@ public class TagEmptyCondition implements ICondition
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(ICondition.IContext context)
|
||||
{
|
||||
return context.getTag(tag).getValues().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
return !Registry.ITEM.getTag(tag).map(HolderSet.Named::iterator).map(Iterator::hasNext).orElse(false);
|
||||
return test(IContext.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Minecraft Forge - Forge Development LLC
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.extensions;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import net.minecraftforge.common.crafting.conditions.ICondition;
|
||||
|
||||
public interface IForgeRecipeSerializer<T extends Recipe<?>>
|
||||
{
|
||||
private RecipeSerializer<T> self()
|
||||
{
|
||||
return (RecipeSerializer<T>) this;
|
||||
}
|
||||
|
||||
default T fromJson(ResourceLocation recipeLoc, JsonObject recipeJson, ICondition.IContext context)
|
||||
{
|
||||
return self().fromJson(recipeLoc, recipeJson);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user