Recipe system cleanup. (#6014)
This commit is contained in:
parent
3e9bc3c434
commit
e784a7f606
38 changed files with 1675 additions and 194 deletions
13
build.gradle
13
build.gradle
|
@ -314,6 +314,19 @@ project(':forge') {
|
|||
|
||||
args '--mod', 'forge', '--all', '--output', rootProject.file('src/generated/resources/')
|
||||
}
|
||||
|
||||
forge_test_data {
|
||||
parent runs.forge_data
|
||||
taskName 'forge_test_data'
|
||||
|
||||
environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this!
|
||||
|
||||
mods {
|
||||
tests { sources sourceSets.test }
|
||||
}
|
||||
|
||||
args '--mod', 'data_gen_test', '--all', '--output', rootProject.file('src/generated_test/resources/')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
--- a/net/minecraft/advancements/AdvancementManager.java
|
||||
+++ b/net/minecraft/advancements/AdvancementManager.java
|
||||
@@ -36,7 +36,11 @@
|
||||
Map<ResourceLocation, Advancement.Builder> map = Maps.newHashMap();
|
||||
p_212853_1_.forEach((p_223387_1_, p_223387_2_) -> {
|
||||
try {
|
||||
- Advancement.Builder advancement$builder = field_192783_b.fromJson(p_223387_2_, Advancement.Builder.class);
|
||||
+ Advancement.Builder advancement$builder = net.minecraftforge.common.crafting.ConditionalAdvancement.read(field_192783_b, p_223387_1_, p_223387_2_);
|
||||
+ if (advancement$builder == null) {
|
||||
+ field_192782_a.info("Skipping loading advancement {} as it's conditions were not met", p_223387_1_);
|
||||
+ return;
|
||||
+ }
|
||||
map.put(p_223387_1_, advancement$builder);
|
||||
} catch (IllegalArgumentException | JsonParseException jsonparseexception) {
|
||||
field_192782_a.error("Parsing error loading custom advancement {}: {}", p_223387_1_, jsonparseexception.getMessage());
|
|
@ -0,0 +1,10 @@
|
|||
--- a/net/minecraft/data/RecipeProvider.java
|
||||
+++ b/net/minecraft/data/RecipeProvider.java
|
||||
@@ -58,6 +58,7 @@
|
||||
|
||||
}
|
||||
});
|
||||
+ if (this.getClass() == RecipeProvider.class) //Forge: Subclasses don't need this.
|
||||
this.func_208310_b(p_200398_1_, Advancement.Builder.func_200278_a().func_200275_a("impossible", new ImpossibleTrigger.Instance()).func_200273_b(), path.resolve("data/minecraft/advancements/recipes/root.json"));
|
||||
}
|
||||
|
|
@ -9,3 +9,11 @@
|
|||
IRecipeSerializer<ShapedRecipe> field_222157_a = func_222156_a("crafting_shaped", new ShapedRecipe.Serializer());
|
||||
IRecipeSerializer<ShapelessRecipe> field_222158_b = func_222156_a("crafting_shapeless", new ShapelessRecipe.Serializer());
|
||||
SpecialRecipeSerializer<ArmorDyeRecipe> field_222159_c = func_222156_a("crafting_special_armordye", new SpecialRecipeSerializer<>(ArmorDyeRecipe::new));
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
T func_199425_a_(ResourceLocation p_199425_1_, JsonObject p_199425_2_);
|
||||
|
||||
+ @javax.annotation.Nullable
|
||||
T func_199426_a_(ResourceLocation p_199426_1_, PacketBuffer p_199426_2_);
|
||||
|
||||
void func_199427_a_(PacketBuffer p_199427_1_, T p_199427_2_);
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
+
|
||||
+ public net.minecraftforge.common.crafting.IIngredientSerializer<? extends Ingredient> getSerializer() {
|
||||
+ if (!isVanilla()) throw new IllegalStateException("Modderrs must implement Ingredient.getSerializer in their custom Ingredients: " + this);
|
||||
+ return net.minecraftforge.common.crafting.CraftingHelper.INGREDIENT_VANILLA;
|
||||
+ return net.minecraftforge.common.crafting.VanillaIngredientSerializer.INSTANCE;
|
||||
+ }
|
||||
+
|
||||
public static Ingredient func_209357_a(Stream<? extends Ingredient.IItemList> p_209357_0_) {
|
||||
|
@ -84,19 +84,7 @@
|
|||
if (p_199802_0_.isJsonObject()) {
|
||||
return func_209357_a(Stream.of(func_199803_a(p_199802_0_.getAsJsonObject())));
|
||||
} else if (p_199802_0_.isJsonArray()) {
|
||||
@@ -169,6 +206,11 @@
|
||||
}
|
||||
|
||||
public static Ingredient.IItemList func_199803_a(JsonObject p_199803_0_) {
|
||||
+ if (p_199803_0_.has("constant")) {
|
||||
+ Ingredient.IItemList ret = net.minecraftforge.common.crafting.CraftingHelper.getConstant(new ResourceLocation(JSONUtils.func_151200_h(p_199803_0_, "constant")));
|
||||
+ if (ret == null) throw new JsonSyntaxException("Ingredient referenced invalid constant: " + JSONUtils.func_151200_h(p_199803_0_, "constant"));
|
||||
+ return ret;
|
||||
+ }
|
||||
if (p_199803_0_.has("item") && p_199803_0_.has("tag")) {
|
||||
throw new JsonParseException("An ingredient entry is either a tag or an item, not both");
|
||||
} else if (p_199803_0_.has("item")) {
|
||||
@@ -190,6 +232,12 @@
|
||||
@@ -190,6 +227,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,3 +97,13 @@
|
|||
public interface IItemList {
|
||||
Collection<ItemStack> func_199799_a();
|
||||
|
||||
@@ -228,6 +271,9 @@
|
||||
list.add(new ItemStack(item));
|
||||
}
|
||||
|
||||
+ if (list.size() == 0 && !net.minecraftforge.common.ForgeConfig.SERVER.treatEmptyTagsAsAir.get()) {
|
||||
+ list.add(new ItemStack(net.minecraft.block.Blocks.field_180401_cv).func_200302_a(new net.minecraft.util.text.StringTextComponent("Empty Tag: " + field_199800_a.func_199886_b().toString())));
|
||||
+ }
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/net/minecraft/item/crafting/RecipeManager.java
|
||||
+++ b/net/minecraft/item/crafting/RecipeManager.java
|
||||
@@ -50,8 +50,13 @@
|
||||
@@ -50,9 +50,18 @@
|
||||
|
||||
for(Entry<ResourceLocation, JsonObject> entry : p_212853_1_.entrySet()) {
|
||||
ResourceLocation resourcelocation = entry.getKey();
|
||||
|
@ -12,5 +12,10 @@
|
|||
+ continue;
|
||||
+ }
|
||||
IRecipe<?> irecipe = func_215377_a(resourcelocation, entry.getValue());
|
||||
+ if (irecipe == null) {
|
||||
+ field_199521_c.info("Skipping loading recipe {} as it's serializer returned null", resourcelocation);
|
||||
+ continue;
|
||||
+ }
|
||||
map.computeIfAbsent(irecipe.func_222127_g(), (p_223391_0_) -> {
|
||||
return ImmutableMap.builder();
|
||||
}).put(resourcelocation, irecipe);
|
||||
|
|
2
src/generated_test/resources/.cache/cache
Normal file
2
src/generated_test/resources/.cache/cache
Normal file
|
@ -0,0 +1,2 @@
|
|||
4fbaf6f4a3ea05cc071076e27f44ac81f9cc50e3 data\data_gen_test\advancements\conditional.json
|
||||
ed4cbf1a3a2f5d8969f6346fdc9acdbe81d0c919 data\data_gen_test\recipes\conditional.json
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"advancements": [
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"values": [
|
||||
{
|
||||
"value": {
|
||||
"modid": "minecraft",
|
||||
"type": "forge:mod_loaded"
|
||||
},
|
||||
"type": "forge:not"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:dirt",
|
||||
"type": "forge:item_exists"
|
||||
},
|
||||
{
|
||||
"type": "forge:false"
|
||||
}
|
||||
],
|
||||
"type": "forge:and"
|
||||
}
|
||||
],
|
||||
"advancement": {
|
||||
"parent": "minecraft:root",
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "minecraft:diamond_block"
|
||||
},
|
||||
"title": {
|
||||
"text": "Dirt2Diamonds"
|
||||
},
|
||||
"description": {
|
||||
"text": "The BEST crafting recipe in the game!"
|
||||
},
|
||||
"frame": "task",
|
||||
"show_toast": false,
|
||||
"announce_to_chat": false,
|
||||
"hidden": false
|
||||
},
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"data_gen_test:conditional"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"has_dirt": {
|
||||
"trigger": "minecraft:inventory_changed",
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"item": "minecraft:dirt"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"has_dirt"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"type": "forge:conditional",
|
||||
"recipes": [
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"values": [
|
||||
{
|
||||
"value": {
|
||||
"modid": "minecraft",
|
||||
"type": "forge:mod_loaded"
|
||||
},
|
||||
"type": "forge:not"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:dirt",
|
||||
"type": "forge:item_exists"
|
||||
},
|
||||
{
|
||||
"type": "forge:false"
|
||||
}
|
||||
],
|
||||
"type": "forge:and"
|
||||
}
|
||||
],
|
||||
"recipe": {
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"XXX",
|
||||
"XXX",
|
||||
"XXX"
|
||||
],
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "minecraft:dirt"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "minecraft:diamond_block",
|
||||
"count": 64
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -49,6 +49,8 @@ public class ForgeConfig
|
|||
|
||||
public final IntValue clumpingThreshold;
|
||||
|
||||
public final BooleanValue treatEmptyTagsAsAir;
|
||||
|
||||
Server(ForgeConfigSpec.Builder builder) {
|
||||
builder.comment("Server configuration settings")
|
||||
.push("server");
|
||||
|
@ -104,6 +106,11 @@ public class ForgeConfig
|
|||
.worldRestart()
|
||||
.defineInRange("clumpingThreshold", 64, 64, 1024);
|
||||
|
||||
treatEmptyTagsAsAir = builder
|
||||
.comment("Vanilla will treat crafting recipess using empty tags as air, and allow you to craft with nothing in that slot. This changes empty tags to use BARRIER as the item. To prevent crafting with air.")
|
||||
.translation("forge.configgui.treatEmptyTagsAsAir")
|
||||
.define("treatEmptyTagsAsAir", false);
|
||||
|
||||
builder.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package net.minecraftforge.common;
|
||||
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.*;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
|
@ -41,14 +42,32 @@ import org.apache.logging.log4j.Logger;
|
|||
import net.minecraft.command.arguments.ArgumentSerializer;
|
||||
import net.minecraft.command.arguments.ArgumentTypes;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.IRecipeSerializer;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.storage.SaveHandler;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
import net.minecraftforge.common.crafting.CompoundIngredient;
|
||||
import net.minecraftforge.common.crafting.ConditionalRecipe;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.common.crafting.IngredientNBT;
|
||||
import net.minecraftforge.common.crafting.VanillaIngredientSerializer;
|
||||
import net.minecraftforge.common.crafting.conditions.AndCondition;
|
||||
import net.minecraftforge.common.crafting.conditions.FalseCondition;
|
||||
import net.minecraftforge.common.crafting.conditions.ItemExistsCondition;
|
||||
import net.minecraftforge.common.crafting.conditions.ModLoadedCondition;
|
||||
import net.minecraftforge.common.crafting.conditions.NotCondition;
|
||||
import net.minecraftforge.common.crafting.conditions.OrCondition;
|
||||
import net.minecraftforge.common.crafting.conditions.TagEmptyCondition;
|
||||
import net.minecraftforge.common.crafting.conditions.TrueCondition;
|
||||
import net.minecraftforge.common.data.ForgeBlockTagsProvider;
|
||||
import net.minecraftforge.common.data.ForgeItemTagsProvider;
|
||||
import net.minecraftforge.common.data.ForgeRecipeProvider;
|
||||
import net.minecraftforge.common.model.animation.CapabilityAnimation;
|
||||
import net.minecraftforge.energy.CapabilityEnergy;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
|
@ -91,6 +110,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
|
|||
final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
modEventBus.addListener(this::preInit);
|
||||
modEventBus.addListener(this::gatherData);
|
||||
modEventBus.register(this);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::serverStarting);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::serverStopping);
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ForgeConfig.clientSpec);
|
||||
|
@ -171,4 +191,24 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
|
|||
gen.addProvider(new ForgeRecipeProvider(gen));
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent //ModBus, can't use addListener due to nested genetics.
|
||||
public void registerRecipeSerialziers(RegistryEvent.Register<IRecipeSerializer<?>> event)
|
||||
{
|
||||
CraftingHelper.register(AndCondition.Serializer.INSTANCE);
|
||||
CraftingHelper.register(FalseCondition.Serializer.INSTANCE);
|
||||
CraftingHelper.register(ItemExistsCondition.Serializer.INSTANCE);
|
||||
CraftingHelper.register(ModLoadedCondition.Serializer.INSTANCE);
|
||||
CraftingHelper.register(NotCondition.Serializer.INSTANCE);
|
||||
CraftingHelper.register(OrCondition.Serializer.INSTANCE);
|
||||
CraftingHelper.register(TrueCondition.Serializer.INSTANCE);
|
||||
CraftingHelper.register(TagEmptyCondition.Serializer.INSTANCE);
|
||||
|
||||
CraftingHelper.register(new ResourceLocation("forge", "compound"), CompoundIngredient.Serializer.INSTANCE);
|
||||
CraftingHelper.register(new ResourceLocation("forge", "nbt"), IngredientNBT.Serializer.INSTANCE);
|
||||
CraftingHelper.register(new ResourceLocation("minecraft", "item"), VanillaIngredientSerializer.INSTANCE);
|
||||
|
||||
event.getRegistry().register(new ConditionalRecipe.Serializer<IRecipe<?>>().setRegistryName(new ResourceLocation("forge", "conditional")));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ import javax.annotation.Nonnull;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
|
@ -41,15 +43,15 @@ import net.minecraft.network.PacketBuffer;
|
|||
|
||||
public class CompoundIngredient extends Ingredient
|
||||
{
|
||||
private Collection<Ingredient> children;
|
||||
private List<Ingredient> children;
|
||||
private ItemStack[] stacks;
|
||||
private IntList itemIds;
|
||||
private final boolean isSimple;
|
||||
|
||||
protected CompoundIngredient(Collection<Ingredient> children)
|
||||
protected CompoundIngredient(List<Ingredient> children)
|
||||
{
|
||||
super(Stream.of());
|
||||
this.children = children;
|
||||
this.children = Collections.unmodifiableList(children);
|
||||
this.isSimple = children.stream().allMatch(Ingredient::isSimple);
|
||||
}
|
||||
|
||||
|
@ -110,17 +112,34 @@ public class CompoundIngredient extends Ingredient
|
|||
@Override
|
||||
public IIngredientSerializer<? extends Ingredient> getSerializer()
|
||||
{
|
||||
return CraftingHelper.INGREDIENT_COMPOUND;
|
||||
return Serializer.INSTANCE;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Collection<Ingredient> getChildren()
|
||||
{
|
||||
return Collections.unmodifiableCollection(this.children);
|
||||
return this.children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize()
|
||||
{
|
||||
if (this.children.size() == 1)
|
||||
{
|
||||
return this.children.get(0).serialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonArray json = new JsonArray();
|
||||
this.children.stream().forEach(e -> json.add(e.serialize()));
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Serializer implements IIngredientSerializer<CompoundIngredient>
|
||||
{
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
@Override
|
||||
public CompoundIngredient parse(PacketBuffer buffer)
|
||||
{
|
||||
|
@ -130,7 +149,7 @@ public class CompoundIngredient extends Ingredient
|
|||
@Override
|
||||
public CompoundIngredient parse(JsonObject json)
|
||||
{
|
||||
throw new JsonSyntaxException("CompountIngredient should not be directly referenced in json, just use an array of ingredients.");
|
||||
throw new JsonSyntaxException("CompoundIngredient should not be directly referenced in json, just use an array of ingredients.");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.crafting.conditions.ICondition;
|
||||
|
||||
public class ConditionalAdvancement
|
||||
{
|
||||
public static Builder builder()
|
||||
{
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static Advancement.Builder read(Gson gson, ResourceLocation recipeId, JsonObject json)
|
||||
{
|
||||
JsonArray entries = JSONUtils.getJsonArray(json, "advancements", null);
|
||||
if (entries == null)
|
||||
{
|
||||
if (!CraftingHelper.processConditions(json, "conditions"))
|
||||
return null;
|
||||
return gson.fromJson(json, Advancement.Builder.class);
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
for (JsonElement ele : entries)
|
||||
{
|
||||
if (!ele.isJsonObject())
|
||||
throw new JsonSyntaxException("Invalid advancement entry at index " + idx + " Must be JsonObject");
|
||||
if (CraftingHelper.processConditions(JSONUtils.getJsonArray(ele.getAsJsonObject(), "conditions")))
|
||||
return gson.fromJson(JSONUtils.getJsonObject(ele.getAsJsonObject(), "advancement"), Advancement.Builder.class);
|
||||
idx++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class Builder
|
||||
{
|
||||
private List<ICondition[]> conditions = new ArrayList<>();
|
||||
private List<Advancement.Builder> advancements = new ArrayList<>();
|
||||
|
||||
private List<ICondition> currentConditions = new ArrayList<>();
|
||||
private boolean locked = false;
|
||||
|
||||
public Builder addCondition(ICondition condition)
|
||||
{
|
||||
if (locked)
|
||||
throw new IllegalStateException("Attempted to modify finished builder");
|
||||
currentConditions.add(condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addAdvancement(Consumer<Consumer<Advancement.Builder>> callable)
|
||||
{
|
||||
if (locked)
|
||||
throw new IllegalStateException("Attempted to modify finished builder");
|
||||
callable.accept(this::addAdvancement);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addAdvancement(Advancement.Builder recipe)
|
||||
{
|
||||
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);
|
||||
currentConditions.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonObject write()
|
||||
{
|
||||
if (!locked)
|
||||
{
|
||||
if (!currentConditions.isEmpty())
|
||||
throw new IllegalStateException("Invalid builder state: Orphaned conditions");
|
||||
if (advancements.isEmpty())
|
||||
throw new IllegalStateException("Invalid builder state: No Advancements");
|
||||
locked = true;
|
||||
}
|
||||
JsonObject json = new JsonObject();
|
||||
JsonArray array = new JsonArray();
|
||||
json.add("advancements", array);
|
||||
for (int x = 0; x < conditions.size(); x++)
|
||||
{
|
||||
JsonObject holder = new JsonObject();
|
||||
|
||||
JsonArray conds = new JsonArray();
|
||||
for (ICondition c : conditions.get(x))
|
||||
conds.add(CraftingHelper.serialize(c));
|
||||
holder.add("conditions", conds);
|
||||
holder.add("advancement", advancements.get(x).serialize());
|
||||
|
||||
array.add(holder);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.minecraft.data.IFinishedRecipe;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.IRecipeSerializer;
|
||||
import net.minecraft.item.crafting.RecipeManager;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.crafting.conditions.ICondition;
|
||||
import net.minecraftforge.registries.ObjectHolder;
|
||||
|
||||
public class ConditionalRecipe
|
||||
{
|
||||
@ObjectHolder("forge:conditional")
|
||||
public static final IRecipeSerializer<IRecipe<?>> SERIALZIER = null;
|
||||
|
||||
public static Builder builder()
|
||||
{
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Serializer<T extends IRecipe<?>> implements IRecipeSerializer<T>
|
||||
{
|
||||
private ResourceLocation name;
|
||||
|
||||
@Override
|
||||
public IRecipeSerializer<?> setRegistryName(ResourceLocation name)
|
||||
{
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getRegistryName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<IRecipeSerializer<?>> getRegistryType()
|
||||
{
|
||||
return Serializer.<IRecipeSerializer<?>>castClass(IRecipeSerializer.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // Need this wrapper, because generics
|
||||
private static <G> Class<G> castClass(Class<?> cls)
|
||||
{
|
||||
return (Class<G>)cls;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // We return a nested one, so we can't know what type it is.
|
||||
@Override
|
||||
public T read(ResourceLocation recipeId, JsonObject json)
|
||||
{
|
||||
JsonArray items = JSONUtils.getJsonArray(json, "recipes");
|
||||
int idx = 0;
|
||||
for (JsonElement ele : items)
|
||||
{
|
||||
if (!ele.isJsonObject())
|
||||
throw new JsonSyntaxException("Invalid recipes entry at index " + idx + " Must be JsonObject");
|
||||
if (CraftingHelper.processConditions(JSONUtils.getJsonArray(ele.getAsJsonObject(), "conditions")))
|
||||
return (T)RecipeManager.deserializeRecipe(recipeId, JSONUtils.getJsonObject(ele.getAsJsonObject(), "recipe"));
|
||||
idx++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//Should never get here as we return one of the recipes we wrap.
|
||||
@Override public T read(ResourceLocation recipeId, PacketBuffer buffer) { return null; }
|
||||
@Override public void write(PacketBuffer buffer, T recipe) {}
|
||||
}
|
||||
|
||||
public static class Builder
|
||||
{
|
||||
private List<ICondition[]> conditions = new ArrayList<>();
|
||||
private List<IFinishedRecipe> recipes = new ArrayList<>();
|
||||
private ResourceLocation advId;
|
||||
private ConditionalAdvancement.Builder adv;
|
||||
|
||||
private List<ICondition> currentConditions = new ArrayList<>();
|
||||
|
||||
public Builder addCondition(ICondition condition)
|
||||
{
|
||||
currentConditions.add(condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addRecipe(Consumer<Consumer<IFinishedRecipe>> callable)
|
||||
{
|
||||
callable.accept(this::addRecipe);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addRecipe(IFinishedRecipe recipe)
|
||||
{
|
||||
if (currentConditions.isEmpty())
|
||||
throw new IllegalStateException("Can not add a recipe with no conditions.");
|
||||
conditions.add(currentConditions.toArray(new ICondition[currentConditions.size()]));
|
||||
recipes.add(recipe);
|
||||
currentConditions.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (this.advId != null)
|
||||
throw new IllegalStateException("Invalid ConditionalRecipeBuilder, Advancement already set");
|
||||
this.advId = id;
|
||||
this.adv = advancement;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void build(Consumer<IFinishedRecipe> consumer, String namespace, String path)
|
||||
{
|
||||
build(consumer, new ResourceLocation(namespace, path));
|
||||
}
|
||||
|
||||
public void build(Consumer<IFinishedRecipe> consumer, ResourceLocation id)
|
||||
{
|
||||
if (!currentConditions.isEmpty())
|
||||
throw new IllegalStateException("Invalid ConditionalRecipe builder, Orphaned conditions");
|
||||
if (recipes.isEmpty())
|
||||
throw new IllegalStateException("Invalid ConditionalRecipe builder, No recipes");
|
||||
|
||||
consumer.accept(new Finished(id, conditions, recipes, advId, adv));
|
||||
}
|
||||
}
|
||||
|
||||
private static class Finished implements IFinishedRecipe
|
||||
{
|
||||
private final ResourceLocation id;
|
||||
private final List<ICondition[]> conditions;
|
||||
private final List<IFinishedRecipe> recipes;
|
||||
private final ResourceLocation advId;
|
||||
private final ConditionalAdvancement.Builder adv;
|
||||
|
||||
private Finished(ResourceLocation id, List<ICondition[]> conditions, List<IFinishedRecipe> recipes, ResourceLocation advId, ConditionalAdvancement.Builder adv)
|
||||
{
|
||||
this.id = id;
|
||||
this.conditions = conditions;
|
||||
this.recipes = recipes;
|
||||
this.advId = advId;
|
||||
this.adv = adv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(JsonObject json) {
|
||||
JsonArray array = new JsonArray();
|
||||
json.add("recipes", array);
|
||||
for (int x = 0; x < conditions.size(); x++)
|
||||
{
|
||||
JsonObject holder = new JsonObject();
|
||||
|
||||
JsonArray conds = new JsonArray();
|
||||
for (ICondition c : conditions.get(x))
|
||||
conds.add(CraftingHelper.serialize(c));
|
||||
holder.add("conditions", conds);
|
||||
holder.add("recipe", recipes.get(x).getRecipeJson());
|
||||
|
||||
array.add(holder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRecipeSerializer<?> getSerializer()
|
||||
{
|
||||
return SERIALZIER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getAdvancementJson() {
|
||||
return adv == null ? null : adv.write();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAdvancementID() {
|
||||
return advId;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,19 +19,12 @@
|
|||
|
||||
package net.minecraftforge.common.crafting;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraftforge.fml.ModList;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.Lists;
|
||||
|
@ -40,24 +33,21 @@ import com.google.gson.GsonBuilder;
|
|||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.item.crafting.Ingredient.IItemList;
|
||||
import net.minecraftforge.common.crafting.conditions.ICondition;
|
||||
import net.minecraftforge.common.crafting.conditions.IConditionSerializer;
|
||||
import net.minecraft.nbt.JsonToNBT;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.resources.IResource;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.Marker;
|
||||
|
@ -65,71 +55,17 @@ import org.apache.logging.log4j.MarkerManager;
|
|||
|
||||
public class CraftingHelper
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
@SuppressWarnings("unused")
|
||||
private static final Marker CRAFTHELPER = MarkerManager.getMarker("CRAFTHELPER");
|
||||
private static Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
private static final Map<ResourceLocation, IConditionSerializer> conditions = new HashMap<>();
|
||||
private static final Map<ResourceLocation, IConditionSerializer<?>> conditions = new HashMap<>();
|
||||
private static final BiMap<ResourceLocation, IIngredientSerializer<?>> ingredients = HashBiMap.create();
|
||||
private static Map<ResourceLocation, IItemList> constants = new HashMap<>();
|
||||
|
||||
public static final IConditionSerializer CONDITION_MOD_LOADED = condition("mod_loaded", json -> {
|
||||
String modid = JSONUtils.getString(json, "modid");
|
||||
return () -> ModList.get().isLoaded(modid);
|
||||
});
|
||||
public static final IConditionSerializer CONDITION_ITEM_EXISTS = condition("item_exists", json -> {
|
||||
String itemName = JSONUtils.getString(json, "item");
|
||||
return () -> ForgeRegistries.ITEMS.containsKey(new ResourceLocation(itemName));
|
||||
});
|
||||
public static final IConditionSerializer CONDITION_NOT = condition("not", json -> {
|
||||
BooleanSupplier child = CraftingHelper.getCondition(JSONUtils.getJsonObject(json, "value"));
|
||||
return () -> !child.getAsBoolean();
|
||||
});
|
||||
public static final IConditionSerializer CONDITION_OR = condition("or", json -> {
|
||||
JsonArray values = JSONUtils.getJsonArray(json, "values");
|
||||
List<BooleanSupplier> children = Lists.newArrayList();
|
||||
for (JsonElement j : values)
|
||||
{
|
||||
if (!j.isJsonObject())
|
||||
throw new JsonSyntaxException("Or condition values must be an array of JsonObjects");
|
||||
children.add(CraftingHelper.getCondition(j.getAsJsonObject()));
|
||||
}
|
||||
return () -> children.stream().anyMatch(BooleanSupplier::getAsBoolean);
|
||||
});
|
||||
public static final IConditionSerializer CONDITION_AND = condition("and", json -> {
|
||||
JsonArray values = JSONUtils.getJsonArray(json, "values");
|
||||
List<BooleanSupplier> children = Lists.newArrayList();
|
||||
for (JsonElement j : values)
|
||||
{
|
||||
if (!j.isJsonObject())
|
||||
throw new JsonSyntaxException("And condition values must be an array of JsonObjects");
|
||||
children.add(CraftingHelper.getCondition(j.getAsJsonObject()));
|
||||
}
|
||||
return () -> children.stream().allMatch(c -> c.getAsBoolean());
|
||||
});
|
||||
public static final IConditionSerializer CONDITION_FALSE = condition("false", json -> () -> false);
|
||||
|
||||
public static final IIngredientSerializer<IngredientNBT> INGREDIENT_NBT = register(new ResourceLocation("forge", "nbt"), new IngredientNBT.Serializer());
|
||||
public static final IIngredientSerializer<CompoundIngredient> INGREDIENT_COMPOUND = register(new ResourceLocation("forge", "compound"), new CompoundIngredient.Serializer());
|
||||
public static final IIngredientSerializer<Ingredient> INGREDIENT_VANILLA = register(new ResourceLocation("minecraft", "item"), new IIngredientSerializer<Ingredient>() {
|
||||
public Ingredient parse(PacketBuffer buffer) {
|
||||
return Ingredient.fromItemListStream(Stream.generate(() -> new Ingredient.SingleItemList(buffer.readItemStack())).limit(buffer.readVarInt()));
|
||||
}
|
||||
|
||||
public Ingredient parse(JsonObject json) {
|
||||
return Ingredient.fromItemListStream(Stream.of(Ingredient.deserializeItemList(json)));
|
||||
}
|
||||
|
||||
public void write(PacketBuffer buffer, Ingredient ingredient) {
|
||||
ItemStack[] items = ingredient.getMatchingStacks();
|
||||
buffer.writeVarInt(items.length);
|
||||
|
||||
for (ItemStack stack : items)
|
||||
buffer.writeItemStack(stack);
|
||||
}
|
||||
});
|
||||
|
||||
public static IConditionSerializer register(ResourceLocation key, IConditionSerializer serializer)
|
||||
public static IConditionSerializer<?> register(IConditionSerializer<?> serializer)
|
||||
{
|
||||
ResourceLocation key = serializer.getID();
|
||||
if (conditions.containsKey(key))
|
||||
throw new IllegalStateException("Duplicate recipe condition serializer: " + key);
|
||||
conditions.put(key, serializer);
|
||||
|
@ -144,11 +80,11 @@ public class CraftingHelper
|
|||
ingredients.put(key, serializer);
|
||||
return serializer;
|
||||
}
|
||||
|
||||
private static IConditionSerializer condition(String name, IConditionSerializer serializer) {
|
||||
return register(new ResourceLocation("forge", name), serializer);
|
||||
@Nullable
|
||||
public static ResourceLocation getID(IIngredientSerializer<?> serializer)
|
||||
{
|
||||
return ingredients.inverse().get(serializer);
|
||||
}
|
||||
|
||||
public static <T extends Ingredient> void write(PacketBuffer buffer, T ingredient)
|
||||
{
|
||||
@SuppressWarnings("unchecked") //I wonder if there is a better way generic wise...
|
||||
|
@ -156,7 +92,7 @@ public class CraftingHelper
|
|||
ResourceLocation key = ingredients.inverse().get(serializer);
|
||||
if (key == null)
|
||||
throw new IllegalArgumentException("Tried to serialize unregistered Ingredient: " + ingredient + " " + serializer);
|
||||
if (serializer != INGREDIENT_VANILLA)
|
||||
if (serializer != VanillaIngredientSerializer.INSTANCE)
|
||||
{
|
||||
buffer.writeVarInt(-1); //Marker to know there is a custom ingredient
|
||||
buffer.writeResourceLocation(key);
|
||||
|
@ -275,94 +211,27 @@ public class CraftingHelper
|
|||
throw new JsonSyntaxException("Conditions must be an array of JsonObjects");
|
||||
|
||||
JsonObject json = conditions.get(x).getAsJsonObject();
|
||||
BooleanSupplier cond = CraftingHelper.getCondition(json);
|
||||
if (!cond.getAsBoolean())
|
||||
if (!CraftingHelper.getCondition(json).test())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static BooleanSupplier getCondition(JsonObject json)
|
||||
public static ICondition getCondition(JsonObject json)
|
||||
{
|
||||
ResourceLocation type = new ResourceLocation(JSONUtils.getString(json, "type"));
|
||||
IConditionSerializer serrializer = conditions.get(type);
|
||||
if (serrializer == null)
|
||||
IConditionSerializer<?> serializer = conditions.get(type);
|
||||
if (serializer == null)
|
||||
throw new JsonSyntaxException("Unknown condition type: " + type.toString());
|
||||
return serrializer.parse(json);
|
||||
return serializer.read(json);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static IItemList getConstant(ResourceLocation key) {
|
||||
return constants.get(key);
|
||||
}
|
||||
|
||||
public static void reloadConstants(IResourceManager manager) {
|
||||
Map<ResourceLocation, IItemList> tmp = new HashMap<>();
|
||||
for(ResourceLocation key : manager.getAllResourceLocations("recipes", filename -> filename.equals("_constants.json")))
|
||||
{
|
||||
String path = key.getPath();
|
||||
if (!path.equals("recipes/_constants.json")) //Top level only
|
||||
continue;
|
||||
|
||||
tmp.putAll(loadConstants(manager, key));
|
||||
}
|
||||
constants = tmp;
|
||||
}
|
||||
|
||||
public static Map<ResourceLocation, IItemList> loadConstants(IResourceManager manager, ResourceLocation key) {
|
||||
Map<ResourceLocation, IItemList> tmp = new HashMap<>();
|
||||
try (IResource iresource = manager.getResource(key))
|
||||
{
|
||||
JsonObject[] elements = JSONUtils.fromJson(GSON, IOUtils.toString(iresource.getInputStream(), StandardCharsets.UTF_8), JsonObject[].class);
|
||||
for (int x = 0; x < elements.length; x++)
|
||||
{
|
||||
JsonObject json = elements[x];
|
||||
//Force namespace to the directory that this constants file is in, to prevent modders from overriding other's sneakily
|
||||
//TODO: Move back to a resource pack/mod specific constant list?
|
||||
ResourceLocation name = json.has("name") ? new ResourceLocation(JSONUtils.getString(json, "name")) : null;
|
||||
if (name != null)
|
||||
name = new ResourceLocation(key.getNamespace(), name.getPath());
|
||||
|
||||
if (json == null || json.size() == 0)
|
||||
LOGGER.error(CRAFTHELPER, "Couldn't load constant #{} from {} as it's null or empty", x, key);
|
||||
else if (!processConditions(json, "conditions"))
|
||||
LOGGER.info(CRAFTHELPER, "Skipping loading constant #{} from {} as it's conditions were not met", x, key);
|
||||
else if (name == null)
|
||||
LOGGER.error(CRAFTHELPER, "Couldn't load constant #{} from {} as it's missing `name`", x, key);
|
||||
else if (json.has("items"))
|
||||
{
|
||||
List<ItemStack> items = new ArrayList<>();
|
||||
for (JsonElement item : JSONUtils.getJsonArray(json, "items"))
|
||||
{
|
||||
if (item.isJsonObject())
|
||||
items.add(getItemStack(item.getAsJsonObject(), true));
|
||||
else
|
||||
{
|
||||
LOGGER.error(CRAFTHELPER, "Couldn't load constant #{} from {} as it's `items` entry is not a object", x, key);
|
||||
items.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!items.isEmpty())
|
||||
tmp.put(name, new StackList(items));
|
||||
}
|
||||
else if (json.has("tag"))
|
||||
tmp.put(name, Ingredient.deserializeItemList(json));
|
||||
else if (json.has("item"))
|
||||
tmp.put(name, new StackList(Lists.newArrayList(getItemStack(JSONUtils.getJsonObject(json, "item"), true))));
|
||||
else
|
||||
LOGGER.error(CRAFTHELPER, "Couldn't load constant #{} from {} as it's missing `item` or `items` element", x, key);
|
||||
}
|
||||
|
||||
}
|
||||
catch (IllegalArgumentException | JsonParseException e)
|
||||
{
|
||||
LOGGER.error(CRAFTHELPER, "Parsing error loading constants {}", key, e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.error(CRAFTHELPER, "Couldn't read constants from {}", key, e);
|
||||
}
|
||||
return tmp;
|
||||
public static <T extends ICondition> JsonObject serialize(T condition)
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
IConditionSerializer<T> serializer = (IConditionSerializer<T>)conditions.get(condition.getID());
|
||||
if (serializer == null)
|
||||
throw new JsonSyntaxException("Unknown condition type: " + condition.getID().toString());
|
||||
return serializer.getJson(condition);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,14 @@ import java.util.stream.Stream;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
//TODO: 1.15 Rename to NBTIngredient to match naming.
|
||||
public class IngredientNBT extends Ingredient
|
||||
{
|
||||
private final ItemStack stack;
|
||||
|
@ -56,11 +58,25 @@ public class IngredientNBT extends Ingredient
|
|||
@Override
|
||||
public IIngredientSerializer<? extends Ingredient> getSerializer()
|
||||
{
|
||||
return CraftingHelper.INGREDIENT_NBT;
|
||||
return Serializer.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize()
|
||||
{
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", CraftingHelper.getID(Serializer.INSTANCE).toString());
|
||||
json.addProperty("item", stack.getItem().getRegistryName().toString());
|
||||
json.addProperty("count", stack.getCount());
|
||||
if (stack.hasTag())
|
||||
json.addProperty("nbt", stack.getTag().toString());
|
||||
return json;
|
||||
}
|
||||
|
||||
public static class Serializer implements IIngredientSerializer<IngredientNBT>
|
||||
{
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
@Override
|
||||
public IngredientNBT parse(PacketBuffer buffer) {
|
||||
return new IngredientNBT(buffer.readItemStack());
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
public class VanillaIngredientSerializer implements IIngredientSerializer<Ingredient>
|
||||
{
|
||||
public static final VanillaIngredientSerializer INSTANCE = new VanillaIngredientSerializer();
|
||||
|
||||
public Ingredient parse(PacketBuffer buffer)
|
||||
{
|
||||
return Ingredient.fromItemListStream(Stream.generate(() -> new Ingredient.SingleItemList(buffer.readItemStack())).limit(buffer.readVarInt()));
|
||||
}
|
||||
|
||||
public Ingredient parse(JsonObject json)
|
||||
{
|
||||
return Ingredient.fromItemListStream(Stream.of(Ingredient.deserializeItemList(json)));
|
||||
}
|
||||
|
||||
public void write(PacketBuffer buffer, Ingredient ingredient)
|
||||
{
|
||||
ItemStack[] items = ingredient.getMatchingStacks();
|
||||
buffer.writeVarInt(items.length);
|
||||
|
||||
for (ItemStack stack : items)
|
||||
buffer.writeItemStack(stack);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
|
||||
public class AndCondition implements ICondition
|
||||
{
|
||||
private static final ResourceLocation NAME = new ResourceLocation("forge", "and");
|
||||
private final ICondition[] children;
|
||||
|
||||
public AndCondition(ICondition... values)
|
||||
{
|
||||
if (values == null || values.length == 0)
|
||||
throw new IllegalArgumentException("Values must not be empty");
|
||||
|
||||
for (ICondition child : values)
|
||||
{
|
||||
if (child == null)
|
||||
throw new IllegalArgumentException("Value must not be null");
|
||||
}
|
||||
|
||||
this.children = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
for (ICondition child : children)
|
||||
{
|
||||
if (!child.test())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return Joiner.on(" && ").join(children);
|
||||
}
|
||||
|
||||
public static class Serializer implements IConditionSerializer<AndCondition>
|
||||
{
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
@Override
|
||||
public void write(JsonObject json, AndCondition value)
|
||||
{
|
||||
JsonArray values = new JsonArray();
|
||||
for (ICondition child : value.children)
|
||||
values.add(CraftingHelper.serialize(child));
|
||||
json.add("values", values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AndCondition read(JsonObject json)
|
||||
{
|
||||
List<ICondition> children = new ArrayList<>();
|
||||
for (JsonElement j : JSONUtils.getJsonArray(json, "values"))
|
||||
{
|
||||
if (!j.isJsonObject())
|
||||
throw new JsonSyntaxException("And condition values must be an array of JsonObjects");
|
||||
children.add(CraftingHelper.getCondition(j.getAsJsonObject()));
|
||||
}
|
||||
return new AndCondition(children.toArray(new ICondition[children.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return AndCondition.NAME;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public final class FalseCondition implements ICondition
|
||||
{
|
||||
public static final FalseCondition INSTANCE = new FalseCondition();
|
||||
private static final ResourceLocation NAME = new ResourceLocation("forge", "false");
|
||||
|
||||
private FalseCondition() {}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "false";
|
||||
}
|
||||
|
||||
public static class Serializer implements IConditionSerializer<FalseCondition>
|
||||
{
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
@Override
|
||||
public void write(JsonObject json, FalseCondition value) { }
|
||||
|
||||
@Override
|
||||
public FalseCondition read(JsonObject json)
|
||||
{
|
||||
return FalseCondition.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return FalseCondition.NAME;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,14 +17,13 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting;
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface IConditionSerializer
|
||||
public interface ICondition
|
||||
{
|
||||
BooleanSupplier parse(JsonObject json);
|
||||
ResourceLocation getID();
|
||||
|
||||
boolean test();
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
public interface IConditionBuilder
|
||||
{
|
||||
default ICondition and(ICondition... values)
|
||||
{
|
||||
return new AndCondition(values);
|
||||
}
|
||||
|
||||
default ICondition FALSE()
|
||||
{
|
||||
return FalseCondition.INSTANCE;
|
||||
}
|
||||
|
||||
default ICondition TRUE()
|
||||
{
|
||||
return TrueCondition.INSTANCE;
|
||||
}
|
||||
|
||||
default ICondition not(ICondition value)
|
||||
{
|
||||
return new NotCondition(value);
|
||||
}
|
||||
|
||||
default ICondition or(ICondition... values)
|
||||
{
|
||||
return new OrCondition(values);
|
||||
}
|
||||
|
||||
default ICondition itemExists(String namespace, String path)
|
||||
{
|
||||
return new ItemExistsCondition(namespace, path);
|
||||
}
|
||||
|
||||
default ICondition modLoaded(String modid)
|
||||
{
|
||||
return new ModLoadedCondition(modid);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public interface IConditionSerializer<T extends ICondition>
|
||||
{
|
||||
void write(JsonObject json, T value);
|
||||
|
||||
T read(JsonObject json);
|
||||
|
||||
ResourceLocation getID();
|
||||
|
||||
default JsonObject getJson(T value)
|
||||
{
|
||||
JsonObject json = new JsonObject();
|
||||
this.write(json, value);
|
||||
json.addProperty("type", value.getID().toString());
|
||||
return json;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class ItemExistsCondition implements ICondition
|
||||
{
|
||||
private static final ResourceLocation NAME = new ResourceLocation("forge", "item_exists");
|
||||
private final ResourceLocation item;
|
||||
|
||||
public ItemExistsCondition(String location)
|
||||
{
|
||||
this(new ResourceLocation(location));
|
||||
}
|
||||
|
||||
public ItemExistsCondition(String namespace, String path)
|
||||
{
|
||||
this(new ResourceLocation(namespace, path));
|
||||
}
|
||||
|
||||
public ItemExistsCondition(ResourceLocation item)
|
||||
{
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
return ForgeRegistries.ITEMS.containsKey(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "item_exists(\"" + item + "\")";
|
||||
}
|
||||
|
||||
public static class Serializer implements IConditionSerializer<ItemExistsCondition>
|
||||
{
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
@Override
|
||||
public void write(JsonObject json, ItemExistsCondition value)
|
||||
{
|
||||
json.addProperty("item", value.item.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemExistsCondition read(JsonObject json)
|
||||
{
|
||||
return new ItemExistsCondition(new ResourceLocation(JSONUtils.getString(json, "item")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return ItemExistsCondition.NAME;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
|
||||
public class ModLoadedCondition implements ICondition
|
||||
{
|
||||
private static final ResourceLocation NAME = new ResourceLocation("forge", "mod_loaded");
|
||||
private final String modid;
|
||||
|
||||
public ModLoadedCondition(String modid)
|
||||
{
|
||||
this.modid = modid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
return ModList.get().isLoaded(modid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "mod_loaded(\"" + modid + "\")";
|
||||
}
|
||||
|
||||
public static class Serializer implements IConditionSerializer<ModLoadedCondition>
|
||||
{
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
@Override
|
||||
public void write(JsonObject json, ModLoadedCondition value)
|
||||
{
|
||||
json.addProperty("modid", value.modid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModLoadedCondition read(JsonObject json)
|
||||
{
|
||||
return new ModLoadedCondition(JSONUtils.getString(json, "modid"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return ModLoadedCondition.NAME;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
|
||||
public class NotCondition implements ICondition
|
||||
{
|
||||
private static final ResourceLocation NAME = new ResourceLocation("forge", "not");
|
||||
private final ICondition child;
|
||||
|
||||
public NotCondition(ICondition child)
|
||||
{
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
return !child.test();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "!" + child;
|
||||
}
|
||||
|
||||
public static class Serializer implements IConditionSerializer<NotCondition>
|
||||
{
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
@Override
|
||||
public void write(JsonObject json, NotCondition value)
|
||||
{
|
||||
json.add("value", CraftingHelper.serialize(value.child));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NotCondition read(JsonObject json)
|
||||
{
|
||||
return new NotCondition(CraftingHelper.getCondition(JSONUtils.getJsonObject(json, "value")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return NotCondition.NAME;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
|
||||
public class OrCondition implements ICondition
|
||||
{
|
||||
private static final ResourceLocation NAME = new ResourceLocation("forge", "or");
|
||||
private final ICondition[] children;
|
||||
|
||||
public OrCondition(ICondition... values)
|
||||
{
|
||||
if (values == null || values.length == 0)
|
||||
throw new IllegalArgumentException("Values must not be empty");
|
||||
|
||||
for (ICondition child : values)
|
||||
{
|
||||
if (child == null)
|
||||
throw new IllegalArgumentException("Value must not be null");
|
||||
}
|
||||
|
||||
this.children = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
for (ICondition child : children)
|
||||
{
|
||||
if (child.test())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return Joiner.on(" || ").join(children);
|
||||
}
|
||||
|
||||
public static class Serializer implements IConditionSerializer<OrCondition>
|
||||
{
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
@Override
|
||||
public void write(JsonObject json, OrCondition value)
|
||||
{
|
||||
JsonArray values = new JsonArray();
|
||||
for (ICondition child : value.children)
|
||||
values.add(CraftingHelper.serialize(child));
|
||||
json.add("values", values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrCondition read(JsonObject json)
|
||||
{
|
||||
List<ICondition> children = new ArrayList<>();
|
||||
for (JsonElement j : JSONUtils.getJsonArray(json, "values"))
|
||||
{
|
||||
if (!j.isJsonObject())
|
||||
throw new JsonSyntaxException("Or condition values must be an array of JsonObjects");
|
||||
children.add(CraftingHelper.getCondition(j.getAsJsonObject()));
|
||||
}
|
||||
return new OrCondition(children.toArray(new ICondition[children.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return OrCondition.NAME;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class TagEmptyCondition implements ICondition
|
||||
{
|
||||
private static final ResourceLocation NAME = new ResourceLocation("forge", "tag_empty");
|
||||
private final ResourceLocation tag_name;
|
||||
|
||||
public TagEmptyCondition(String location)
|
||||
{
|
||||
this(new ResourceLocation(location));
|
||||
}
|
||||
|
||||
public TagEmptyCondition(String namespace, String path)
|
||||
{
|
||||
this(new ResourceLocation(namespace, path));
|
||||
}
|
||||
|
||||
public TagEmptyCondition(ResourceLocation tag)
|
||||
{
|
||||
this.tag_name = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
Tag<Item> tag = ItemTags.getCollection().get(tag_name);
|
||||
return tag == null || tag.getAllElements().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "tag_empty(\"" + tag_name + "\")";
|
||||
}
|
||||
|
||||
public static class Serializer implements IConditionSerializer<TagEmptyCondition>
|
||||
{
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
@Override
|
||||
public void write(JsonObject json, TagEmptyCondition value)
|
||||
{
|
||||
json.addProperty("tag", value.tag_name.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TagEmptyCondition read(JsonObject json)
|
||||
{
|
||||
return new TagEmptyCondition(new ResourceLocation(JSONUtils.getString(json, "tag")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return TagEmptyCondition.NAME;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.crafting.conditions;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public final class TrueCondition implements ICondition
|
||||
{
|
||||
public static final TrueCondition INSTANCE = new TrueCondition();
|
||||
private static final ResourceLocation NAME = new ResourceLocation("forge", "true");
|
||||
|
||||
private TrueCondition() {}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "true";
|
||||
}
|
||||
|
||||
public static class Serializer implements IConditionSerializer<TrueCondition>
|
||||
{
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
@Override
|
||||
public void write(JsonObject json, TrueCondition value) { }
|
||||
|
||||
@Override
|
||||
public TrueCondition read(JsonObject json)
|
||||
{
|
||||
return TrueCondition.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
{
|
||||
return TrueCondition.NAME;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,16 +52,12 @@ import net.minecraftforge.common.Tags;
|
|||
|
||||
public class ForgeRecipeProvider extends RecipeProvider
|
||||
{
|
||||
private final DataGenerator generator;
|
||||
private final Path ADV_ROOT;
|
||||
private Map<Item, Tag<Item>> replacements = new HashMap<>();
|
||||
private Set<ResourceLocation> excludes = new HashSet<>();
|
||||
|
||||
public ForgeRecipeProvider(DataGenerator generatorIn)
|
||||
{
|
||||
super(generatorIn);
|
||||
this.generator = generatorIn;
|
||||
ADV_ROOT = this.generator.getOutputFolder().resolve("data/minecraft/advancements/recipes/root.json");
|
||||
}
|
||||
|
||||
private void exclude(IItemProvider item)
|
||||
|
@ -101,7 +97,6 @@ public class ForgeRecipeProvider extends RecipeProvider
|
|||
|
||||
@Override
|
||||
protected void saveRecipeAdvancement(DirectoryCache cache, JsonObject advancementJson, Path pathIn) {
|
||||
if (pathIn.equals(ADV_ROOT)) return; //We NEVER care about this.
|
||||
//NOOP - We dont replace any of the advancement things yet...
|
||||
}
|
||||
|
||||
|
|
|
@ -208,7 +208,9 @@ public class ModLoader
|
|||
|
||||
LOGGER.debug(LOADING, "ModContainer is {}", ModContainer.class.getClassLoader());
|
||||
final List<ModContainer> containers = modFile.getScanResult().getTargets().entrySet().stream().
|
||||
map(e -> buildModContainerFromTOML(modFile, modClassLoader, modInfoMap, e)).collect(Collectors.toList());
|
||||
map(e -> buildModContainerFromTOML(modFile, modClassLoader, modInfoMap, e))
|
||||
.filter(e -> e != null)
|
||||
.collect(Collectors.toList());
|
||||
if (containers.size() != modInfoMap.size()) {
|
||||
LOGGER.fatal(LOADING,"File {} constructed {} mods: {}, but had {} mods specified: {}",
|
||||
modFile.getFilePath(),
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.server.command;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.server.command;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.server.command;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
|
|
@ -50,7 +50,13 @@ public net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher fie
|
|||
public net.minecraft.command.arguments.EntityOptions func_202024_a(Ljava/lang/String;Lnet/minecraft/command/arguments/EntityOptions$IFilter;Ljava/util/function/Predicate;Lnet/minecraft/util/text/ITextComponent;)V # register
|
||||
public net.minecraft.command.arguments.EntitySelectorParser func_197396_n()V # updateFilter
|
||||
public net.minecraft.command.arguments.EntitySelectorParser func_197404_d()V # parseArguments
|
||||
protected net.minecraft.data.RecipeProvider field_200413_c # generator
|
||||
protected net.minecraft.data.RecipeProvider func_200403_a(Lnet/minecraft/util/IItemProvider;)Lnet/minecraft/advancements/criterion/InventoryChangeTrigger$Instance; # hasItem
|
||||
protected net.minecraft.data.RecipeProvider func_200404_a(Ljava/util/function/Consumer;)V # registerRecipes
|
||||
protected net.minecraft.data.RecipeProvider func_200405_a([Lnet/minecraft/advancements/criterion/ItemPredicate;)Lnet/minecraft/advancements/criterion/InventoryChangeTrigger$Instance; # hasItem
|
||||
protected net.minecraft.data.RecipeProvider func_200407_a(Lnet/minecraft/block/Block;)Lnet/minecraft/advancements/criterion/EnterBlockTrigger$Instance; # enteredBlock
|
||||
protected net.minecraft.data.RecipeProvider func_200408_a(Lnet/minecraft/advancements/criterion/MinMaxBounds$IntBound;Lnet/minecraft/util/IItemProvider;)Lnet/minecraft/advancements/criterion/InventoryChangeTrigger$Instance; # hasItem
|
||||
protected net.minecraft.data.RecipeProvider func_200409_a(Lnet/minecraft/tags/Tag;)Lnet/minecraft/advancements/criterion/InventoryChangeTrigger$Instance; # hasItem
|
||||
protected net.minecraft.data.RecipeProvider func_208310_b(Lnet/minecraft/data/DirectoryCache;Lcom/google/gson/JsonObject;Ljava/nio/file/Path;)V # saveRecipeAdvancement
|
||||
public net.minecraft.data.ShapedRecipeBuilder$Result
|
||||
public net.minecraft.entity.Entity func_70022_Q()Ljava/lang/String; # getEntityString
|
||||
|
|
|
@ -137,6 +137,8 @@
|
|||
"forge.configgui.forgeLightPipelineEnabled": "Forge Light Pipeline Enabled",
|
||||
"forge.configgui.selectiveResourceReloadEnabled.tooltip": "When enabled, makes specific reload tasks such as language changing quicker to run.",
|
||||
"forge.configgui.selectiveResourceReloadEnabled": "Enable Selective Resource Loading",
|
||||
"forge.configgui.treatEmptyTagsAsAir.tooltip": "Vanilla will treat crafting recipess using empty tags as air, and allow you to craft with nothing in that slot. If false, this changes empty tags to use BARRIER as the item. To prevent crafting with air.",
|
||||
"forge.configgui.treatEmptyTagsAsAir": "Treat empty tags as air",
|
||||
|
||||
"forge.controlsgui.shift": "SHIFT + %s",
|
||||
"forge.controlsgui.control": "CTRL + %s",
|
||||
|
|
110
src/test/java/net/minecraftforge/debug/DataGeneratorTest.java
Normal file
110
src/test/java/net/minecraftforge/debug/DataGeneratorTest.java
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.debug;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.advancements.AdvancementRewards;
|
||||
import net.minecraft.advancements.FrameType;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.IFinishedRecipe;
|
||||
import net.minecraft.data.RecipeProvider;
|
||||
import net.minecraft.data.ShapedRecipeBuilder;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraftforge.common.crafting.ConditionalAdvancement;
|
||||
import net.minecraftforge.common.crafting.ConditionalRecipe;
|
||||
import net.minecraftforge.common.crafting.conditions.IConditionBuilder;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
|
||||
|
||||
@Mod("data_gen_test")
|
||||
@Mod.EventBusSubscriber(bus = Bus.MOD)
|
||||
public class DataGeneratorTest
|
||||
{
|
||||
@SubscribeEvent
|
||||
public static void gatherData(GatherDataEvent event)
|
||||
{
|
||||
DataGenerator gen = event.getGenerator();
|
||||
|
||||
if (event.includeServer())
|
||||
{
|
||||
gen.addProvider(new Recipes(gen));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Recipes extends RecipeProvider implements IConditionBuilder
|
||||
{
|
||||
public Recipes(DataGenerator gen)
|
||||
{
|
||||
super(gen);
|
||||
}
|
||||
|
||||
protected void registerRecipes(Consumer<IFinishedRecipe> consumer)
|
||||
{
|
||||
ResourceLocation ID = new ResourceLocation("data_gen_test", "conditional");
|
||||
|
||||
ConditionalRecipe.builder()
|
||||
.addCondition(
|
||||
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)) //Doesn't actually print... TODO: nested/conditional advancements?
|
||||
::build
|
||||
)
|
||||
.setAdvancement(ID,
|
||||
ConditionalAdvancement.builder()
|
||||
.addCondition(
|
||||
and(
|
||||
not(modLoaded("minecraft")),
|
||||
itemExists("minecraft", "dirt"),
|
||||
FALSE()
|
||||
)
|
||||
)
|
||||
.addAdvancement(
|
||||
Advancement.Builder.builder()
|
||||
.withParentId(new ResourceLocation("minecraft", "root"))
|
||||
.withDisplay(Blocks.DIAMOND_BLOCK,
|
||||
new StringTextComponent("Dirt2Diamonds"),
|
||||
new StringTextComponent("The BEST crafting recipe in the game!"),
|
||||
null, FrameType.TASK, false, false, false
|
||||
)
|
||||
.withRewards(AdvancementRewards.Builder.recipe(ID))
|
||||
.withCriterion("has_dirt", hasItem(Blocks.DIRT))
|
||||
)
|
||||
)
|
||||
.build(consumer, ID);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,7 +54,7 @@ import net.minecraftforge.fml.common.Mod;
|
|||
public class PistonEventTest
|
||||
{
|
||||
|
||||
public static final String MODID = "pistoneventtest";
|
||||
public static final String MODID = "piston_event_test";
|
||||
|
||||
private static Block shiftOnMove = new BlockShiftOnMove();
|
||||
|
||||
|
|
|
@ -43,3 +43,7 @@ loaderVersion="[28,)"
|
|||
modId="command_event_test"
|
||||
[[mods]]
|
||||
modId="entity_selector_test"
|
||||
[[mods]]
|
||||
modId="data_gen_test"
|
||||
[[mods]]
|
||||
modId="piston_event_test"
|
Loading…
Reference in a new issue