mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-24 05:47:59 +01:00
Finally got all the recipes fixed
This commit is contained in:
parent
070aeaefe3
commit
8e30e8539a
65 changed files with 861 additions and 607 deletions
|
@ -8,7 +8,7 @@ import com.google.common.collect.Sets;
|
|||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.minelittlepony.unicopia.recipe.ingredient.Ingredient;
|
||||
import com.minelittlepony.unicopia.recipe.ingredient.PredicatedIngredient;
|
||||
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
|
@ -20,42 +20,42 @@ public class Pattern {
|
|||
|
||||
public static Pattern read(PacketByteBuf buf) {
|
||||
return new Pattern(
|
||||
Utils.read(buf, Ingredient.EMPTY, Ingredient::read),
|
||||
Utils.read(buf, PredicatedIngredient.EMPTY, PredicatedIngredient::read),
|
||||
buf.readVarInt(),
|
||||
buf.readVarInt()
|
||||
);
|
||||
}
|
||||
|
||||
public static Pattern read(JsonObject json) {
|
||||
String[] patterns = combinePatternMatrix(getPattern(JsonHelper.getArray(json, "pattern")));
|
||||
Map<String, Ingredient> ingredients = readIngredients(JsonHelper.getObject(json, "key"));
|
||||
String[] patterns = removePadding(readPattern(JsonHelper.getArray(json, "pattern")));
|
||||
Map<String, PredicatedIngredient> symbols = readSymbols(JsonHelper.getObject(json, "key"));
|
||||
|
||||
return new Pattern(patterns, ingredients);
|
||||
return new Pattern(patterns, symbols);
|
||||
}
|
||||
|
||||
public final DefaultedList<Ingredient> matrix;
|
||||
public final DefaultedList<PredicatedIngredient> matrix;
|
||||
|
||||
public final int width;
|
||||
public final int height;
|
||||
|
||||
public Pattern(DefaultedList<Ingredient> matrix, int width, int height) {
|
||||
public Pattern(DefaultedList<PredicatedIngredient> matrix, int width, int height) {
|
||||
this.matrix = matrix;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public Pattern(String[] pattern, Map<String, Ingredient> ingredients) {
|
||||
public Pattern(String[] pattern, Map<String, PredicatedIngredient> ingredients) {
|
||||
this(pattern, ingredients, pattern[0].length(), pattern.length);
|
||||
}
|
||||
|
||||
private Pattern(String[] pattern, Map<String, Ingredient> ingredients, int width, int height) {
|
||||
private Pattern(String[] pattern, Map<String, PredicatedIngredient> ingredients, int width, int height) {
|
||||
this(buildIngredientMatrix(pattern, ingredients, width, height), width, height);
|
||||
}
|
||||
|
||||
public boolean matches(CraftingInventory inv) {
|
||||
for(int x = 0; x <= inv.getWidth() - width; x++) {
|
||||
for(int y = 0; y <= inv.getHeight() - height; y++) {
|
||||
if (matchesSmall(inv, x, y, true) || matchesSmall(inv, x, y, false)) {
|
||||
if (matchesPattern(inv, x, y, true) || matchesPattern(inv, x, y, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ public class Pattern {
|
|||
}
|
||||
|
||||
public void write(PacketByteBuf buf) {
|
||||
Utils.write(buf, matrix, Ingredient::write);
|
||||
Utils.write(buf, matrix, PredicatedIngredient::write);
|
||||
buf.writeVarInt(width);
|
||||
buf.writeVarInt(height);
|
||||
}
|
||||
|
@ -74,17 +74,19 @@ public class Pattern {
|
|||
return matrix.size();
|
||||
}
|
||||
|
||||
private boolean matchesSmall(CraftingInventory inv, int offsetX, int offsetY, boolean reflected) {
|
||||
private boolean matchesPattern(CraftingInventory inv, int offsetX, int offsetY, boolean reflected) {
|
||||
for(int x = 0; x < inv.getWidth(); ++x) {
|
||||
for(int y = 0; y < inv.getHeight(); ++y) {
|
||||
int k = x - offsetX;
|
||||
int l = y - offsetY;
|
||||
Ingredient ingredient = Ingredient.EMPTY;
|
||||
if (k >= 0 && l >= 0 && k < width && l < this.height) {
|
||||
int left = x - offsetX;
|
||||
int top = y - offsetY;
|
||||
|
||||
PredicatedIngredient ingredient = PredicatedIngredient.EMPTY;
|
||||
|
||||
if (left >= 0 && top >= 0 && left < width && top < height) {
|
||||
if (reflected) {
|
||||
ingredient = matrix.get(width - k - 1 + l * this.width);
|
||||
ingredient = matrix.get(width - left - 1 + top * width);
|
||||
} else {
|
||||
ingredient = matrix.get(k + l * this.width);
|
||||
ingredient = matrix.get(left + top * width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,111 +99,130 @@ public class Pattern {
|
|||
return true;
|
||||
}
|
||||
|
||||
static DefaultedList<Ingredient> buildIngredientMatrix(String[] pattern, Map<String, Ingredient> ingredients, int width, int height) {
|
||||
DefaultedList<Ingredient> result = DefaultedList.ofSize(width * height, Ingredient.EMPTY);
|
||||
static DefaultedList<PredicatedIngredient> buildIngredientMatrix(String[] pattern, Map<String, PredicatedIngredient> symbols, int width, int height) {
|
||||
DefaultedList<PredicatedIngredient> result = DefaultedList.ofSize(width * height, PredicatedIngredient.EMPTY);
|
||||
|
||||
Set<String> unsolved = Sets.newHashSet(ingredients.keySet());
|
||||
unsolved.remove(" ");
|
||||
Set<String> unresolved = Sets.newHashSet(symbols.keySet());
|
||||
unresolved.remove(" ");
|
||||
|
||||
for(int i = 0; i < pattern.length; ++i) {
|
||||
for(int j = 0; j < pattern[i].length(); ++j) {
|
||||
String key = pattern[i].substring(j, j + 1);
|
||||
|
||||
Ingredient ingredient = ingredients.get(key);
|
||||
PredicatedIngredient ingredient = symbols.get(key);
|
||||
|
||||
if (ingredient == null) {
|
||||
throw new JsonSyntaxException("Pattern references symbol '" + key + "' but it's not defined in the key");
|
||||
}
|
||||
|
||||
unsolved.remove(key);
|
||||
unresolved.remove(key);
|
||||
result.set(j + width * i, ingredient);
|
||||
}
|
||||
}
|
||||
|
||||
if (!unsolved.isEmpty()) {
|
||||
throw new JsonSyntaxException("Key defines symbols that aren't used in pattern: " + unsolved);
|
||||
if (!unresolved.isEmpty()) {
|
||||
throw new JsonSyntaxException("Key defines symbols that aren't used in pattern: " + unresolved);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static String[] combinePatternMatrix(String... lines) {
|
||||
int i = Integer.MAX_VALUE;
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
int l = 0;
|
||||
/**
|
||||
* Removes empty space from around the recipe pattern.
|
||||
*
|
||||
* Turns patterns such as:
|
||||
* " o"
|
||||
* " a"
|
||||
* " "
|
||||
* Into:
|
||||
* "o"
|
||||
* "a"
|
||||
*
|
||||
* @param pattern
|
||||
* @return A new recipe pattern with all leading and trailing empty rows/columns removed.
|
||||
*/
|
||||
static String[] removePadding(String... pattern) {
|
||||
int left = Integer.MAX_VALUE;
|
||||
int right = 0;
|
||||
|
||||
for(int row = 0; row < lines.length; ++row) {
|
||||
String line = lines[row];
|
||||
int top = 0;
|
||||
int bottom = 0;
|
||||
|
||||
i = Math.min(i, lookAhead(line));
|
||||
for(int yPosition = 0; yPosition < pattern.length; ++yPosition) {
|
||||
String row = pattern[yPosition];
|
||||
|
||||
int n = lookBack(line);
|
||||
left = Math.min(left, findFirstSymbol(row));
|
||||
|
||||
j = Math.max(j, n);
|
||||
if (n < 0) {
|
||||
if (k == row) {
|
||||
++k;
|
||||
int rowEnd = findLastSymbol(row);
|
||||
|
||||
right = Math.max(right, rowEnd);
|
||||
|
||||
if (rowEnd < 0) {
|
||||
if (top == yPosition) {
|
||||
top++;
|
||||
}
|
||||
|
||||
++l;
|
||||
bottom++;
|
||||
} else {
|
||||
l = 0;
|
||||
bottom = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.length == l) {
|
||||
if (pattern.length == bottom) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
String[] strings = new String[lines.length - l - k];
|
||||
String[] strings = new String[pattern.length - bottom - top];
|
||||
|
||||
for(int o = 0; o < strings.length; ++o) {
|
||||
strings[o] = lines[o + k].substring(i, j + 1);
|
||||
for(int i = 0; i < strings.length; i++) {
|
||||
strings[i] = pattern[i + top].substring(left, right + 1);
|
||||
}
|
||||
|
||||
return strings;
|
||||
}
|
||||
|
||||
private static int lookAhead(String pattern) {
|
||||
private static int findFirstSymbol(String pattern) {
|
||||
int i;
|
||||
for(i = 0; i < pattern.length() && pattern.charAt(i) == ' '; ++i) {}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private static int lookBack(String pattern) {
|
||||
private static int findLastSymbol(String pattern) {
|
||||
int i;
|
||||
for(i = pattern.length() - 1; i >= 0 && pattern.charAt(i) == ' '; --i) {}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static String[] getPattern(JsonArray json) {
|
||||
String[] strings = new String[json.size()];
|
||||
if (strings.length > 3) {
|
||||
throw new JsonSyntaxException("Invalid pattern: too many rows, 3 is maximum");
|
||||
} else if (strings.length == 0) {
|
||||
throw new JsonSyntaxException("Invalid pattern: empty pattern not allowed");
|
||||
} else {
|
||||
for(int i = 0; i < strings.length; ++i) {
|
||||
String string = JsonHelper.asString(json.get(i), "pattern[" + i + "]");
|
||||
if (string.length() > 3) {
|
||||
static String[] readPattern(JsonArray json) {
|
||||
String[] rows = new String[json.size()];
|
||||
|
||||
if (rows.length > 3) {
|
||||
throw new JsonSyntaxException("Invalid pattern: too many rows, 3 is maximum");
|
||||
}
|
||||
if (rows.length == 0) {
|
||||
throw new JsonSyntaxException("Invalid pattern: empty pattern not allowed");
|
||||
}
|
||||
|
||||
for(int i = 0; i < rows.length; ++i) {
|
||||
String column = JsonHelper.asString(json.get(i), "pattern[" + i + "]");
|
||||
|
||||
if (column.length() > 3) {
|
||||
throw new JsonSyntaxException("Invalid pattern: too many columns, 3 is maximum");
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 0 && strings[0].length() != string.length()) {
|
||||
if (i > 0 && rows[0].length() != column.length()) {
|
||||
throw new JsonSyntaxException("Invalid pattern: each row must be the same width");
|
||||
}
|
||||
}
|
||||
|
||||
strings[i] = string;
|
||||
}
|
||||
rows[i] = column;
|
||||
}
|
||||
|
||||
return strings;
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
static Map<String, Ingredient> readIngredients(JsonObject json) {
|
||||
static Map<String, PredicatedIngredient> readSymbols(JsonObject json) {
|
||||
return Util.make(json.entrySet().stream().collect(Collectors.toMap(e -> {
|
||||
if (e.getKey().length() != 1) {
|
||||
throw new JsonSyntaxException("Invalid key entry: '" + e.getKey() + "' is an invalid symbol (must be 1 character only).");
|
||||
|
@ -213,8 +234,7 @@ public class Pattern {
|
|||
|
||||
return e.getKey();
|
||||
},
|
||||
e -> Ingredient.one(e.getValue())
|
||||
)), m -> m.put(" ", Ingredient.EMPTY));
|
||||
e -> PredicatedIngredient.one(e.getValue())
|
||||
)), m -> m.put(" ", PredicatedIngredient.EMPTY));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,10 +3,11 @@ package com.minelittlepony.unicopia.recipe;
|
|||
import java.util.Random;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.recipe.ingredient.Ingredient;
|
||||
import com.minelittlepony.unicopia.recipe.ingredient.PredicatedIngredient;
|
||||
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.recipe.SpecialCraftingRecipe;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
|
@ -20,10 +21,10 @@ public class ShapedSpecialRecipe extends SpecialCraftingRecipe {
|
|||
private static final Random RANDOM = new Random();
|
||||
|
||||
private final Pattern pattern;
|
||||
private final Ingredient output;
|
||||
private final PredicatedIngredient output;
|
||||
private final String group;
|
||||
|
||||
public ShapedSpecialRecipe(Identifier id, String group, Pattern pattern, Ingredient output) {
|
||||
public ShapedSpecialRecipe(Identifier id, String group, Pattern pattern, PredicatedIngredient output) {
|
||||
super(id);
|
||||
this.group = group;
|
||||
this.pattern = pattern;
|
||||
|
@ -57,7 +58,7 @@ public class ShapedSpecialRecipe extends SpecialCraftingRecipe {
|
|||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return null;
|
||||
return URecipes.CRAFTING_SHAPED;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,8 +67,8 @@ public class ShapedSpecialRecipe extends SpecialCraftingRecipe {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DefaultedList<net.minecraft.recipe.Ingredient> getPreviewInputs() {
|
||||
return Ingredient.preview(pattern.matrix);
|
||||
public DefaultedList<Ingredient> getPreviewInputs() {
|
||||
return PredicatedIngredient.preview(pattern.matrix);
|
||||
}
|
||||
|
||||
public static class Serializer implements RecipeSerializer<ShapedSpecialRecipe> {
|
||||
|
@ -76,7 +77,7 @@ public class ShapedSpecialRecipe extends SpecialCraftingRecipe {
|
|||
return new ShapedSpecialRecipe(id,
|
||||
JsonHelper.getString(json, "group", ""),
|
||||
Pattern.read(json),
|
||||
Ingredient.one(json.get("result"))
|
||||
PredicatedIngredient.one(json.get("result"))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -85,7 +86,7 @@ public class ShapedSpecialRecipe extends SpecialCraftingRecipe {
|
|||
return new ShapedSpecialRecipe(id,
|
||||
buf.readString(32767),
|
||||
Pattern.read(buf),
|
||||
Ingredient.read(buf)
|
||||
PredicatedIngredient.read(buf)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,11 @@ package com.minelittlepony.unicopia.recipe;
|
|||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.minelittlepony.unicopia.recipe.ingredient.Ingredient;
|
||||
import com.minelittlepony.unicopia.recipe.ingredient.PredicatedIngredient;
|
||||
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.recipe.SpecialCraftingRecipe;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
|
@ -17,11 +18,11 @@ import net.minecraft.world.World;
|
|||
public class ShapelessSpecialRecipe extends SpecialCraftingRecipe {
|
||||
|
||||
private final String group;
|
||||
private final Ingredient output;
|
||||
private final PredicatedIngredient output;
|
||||
|
||||
private final DefaultedList<Ingredient> input;
|
||||
private final DefaultedList<PredicatedIngredient> input;
|
||||
|
||||
public ShapelessSpecialRecipe(Identifier id, String group, Ingredient output, DefaultedList<Ingredient> input) {
|
||||
public ShapelessSpecialRecipe(Identifier id, String group, PredicatedIngredient output, DefaultedList<PredicatedIngredient> input) {
|
||||
super(id);
|
||||
this.group = group;
|
||||
this.output = output;
|
||||
|
@ -66,8 +67,8 @@ public class ShapelessSpecialRecipe extends SpecialCraftingRecipe {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DefaultedList<net.minecraft.recipe.Ingredient> getPreviewInputs() {
|
||||
return Ingredient.preview(input);
|
||||
public DefaultedList<Ingredient> getPreviewInputs() {
|
||||
return PredicatedIngredient.preview(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,11 +78,11 @@ public class ShapelessSpecialRecipe extends SpecialCraftingRecipe {
|
|||
|
||||
public static class Serializer implements RecipeSerializer<ShapelessSpecialRecipe> {
|
||||
@Override
|
||||
public ShapelessSpecialRecipe read(Identifier identifier, JsonObject jsonObject) {
|
||||
public ShapelessSpecialRecipe read(Identifier identifier, JsonObject json) {
|
||||
return new ShapelessSpecialRecipe(identifier,
|
||||
JsonHelper.getString(jsonObject, "group", ""),
|
||||
Ingredient.one(jsonObject.get("output")),
|
||||
Ingredient.many(JsonHelper.getArray(jsonObject, "ingredients"))
|
||||
JsonHelper.getString(json, "group", ""),
|
||||
PredicatedIngredient.one(json.get("result")),
|
||||
PredicatedIngredient.many(JsonHelper.getArray(json, "ingredients"))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -89,8 +90,8 @@ public class ShapelessSpecialRecipe extends SpecialCraftingRecipe {
|
|||
public ShapelessSpecialRecipe read(Identifier identifier, PacketByteBuf buf) {
|
||||
return new ShapelessSpecialRecipe(identifier,
|
||||
buf.readString(32767),
|
||||
Ingredient.read(buf),
|
||||
Utils.read(buf, Ingredient.EMPTY, Ingredient::read));
|
||||
PredicatedIngredient.read(buf),
|
||||
Utils.read(buf, PredicatedIngredient.EMPTY, PredicatedIngredient::read));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -98,7 +99,7 @@ public class ShapelessSpecialRecipe extends SpecialCraftingRecipe {
|
|||
buf.writeString(recipe.group);
|
||||
recipe.output.write(buf);
|
||||
buf.writeVarInt(recipe.input.size());
|
||||
Utils.write(buf, recipe.input, Ingredient::write);
|
||||
Utils.write(buf, recipe.input, PredicatedIngredient::write);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,11 @@ package com.minelittlepony.unicopia.recipe;
|
|||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.container.SpellBookInventory;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.recipe.ingredient.Ingredient;
|
||||
import com.minelittlepony.unicopia.recipe.ingredient.PredicatedIngredient;
|
||||
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.recipe.Recipe;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.recipe.RecipeType;
|
||||
|
@ -21,19 +22,17 @@ import net.minecraft.world.World;
|
|||
*/
|
||||
public class SpellBookRecipe implements Recipe<CraftingInventory> {
|
||||
|
||||
private final Ingredient input;
|
||||
|
||||
private final Ingredient output;
|
||||
|
||||
private final DefaultedList<Ingredient> ingredients;
|
||||
|
||||
private final Identifier id;
|
||||
private final PredicatedIngredient input;
|
||||
private final PredicatedIngredient output;
|
||||
private final DefaultedList<PredicatedIngredient> ingredients;
|
||||
|
||||
public SpellBookRecipe(Identifier id, Ingredient input, Ingredient output, DefaultedList<Ingredient> ingredients) {
|
||||
|
||||
public SpellBookRecipe(Identifier id, String group, PredicatedIngredient input, PredicatedIngredient output, DefaultedList<PredicatedIngredient> ingredients) {
|
||||
this.id = id;
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.ingredients = ingredients;
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -68,8 +67,8 @@ public class SpellBookRecipe implements Recipe<CraftingInventory> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DefaultedList<net.minecraft.recipe.Ingredient> getPreviewInputs() {
|
||||
return Ingredient.preview(ingredients, DefaultedList.copyOf(null, input.getPreview()));
|
||||
public DefaultedList<Ingredient> getPreviewInputs() {
|
||||
return PredicatedIngredient.preview(ingredients, DefaultedList.copyOf(null, input.getPreview()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -96,18 +95,20 @@ public class SpellBookRecipe implements Recipe<CraftingInventory> {
|
|||
@Override
|
||||
public SpellBookRecipe read(Identifier id, JsonObject json) {
|
||||
return new SpellBookRecipe(id,
|
||||
Ingredient.one(json.get("input")),
|
||||
Ingredient.one(json.get("result")),
|
||||
Ingredient.many(JsonHelper.getArray(json, "ingredients"))
|
||||
JsonHelper.getString(json, "group", ""),
|
||||
PredicatedIngredient.one(JsonHelper.getObject(json, "input")),
|
||||
PredicatedIngredient.one(JsonHelper.getObject(json, "result")),
|
||||
PredicatedIngredient.many(JsonHelper.getArray(json, "ingredients"))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellBookRecipe read(Identifier id, PacketByteBuf buf) {
|
||||
return new SpellBookRecipe(id,
|
||||
Ingredient.read(buf),
|
||||
Ingredient.read(buf),
|
||||
Utils.read(buf, Ingredient.EMPTY, Ingredient::read)
|
||||
buf.readString(32767),
|
||||
PredicatedIngredient.read(buf),
|
||||
PredicatedIngredient.read(buf),
|
||||
Utils.read(buf, PredicatedIngredient.EMPTY, PredicatedIngredient::read)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -115,7 +116,7 @@ public class SpellBookRecipe implements Recipe<CraftingInventory> {
|
|||
public void write(PacketByteBuf buf, SpellBookRecipe recipe) {
|
||||
recipe.input.write(buf);
|
||||
recipe.output.write(buf);
|
||||
Utils.write(buf, recipe.ingredients, Ingredient::write);
|
||||
Utils.write(buf, recipe.ingredients, PredicatedIngredient::write);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,18 +6,24 @@ import java.util.function.BiConsumer;
|
|||
import java.util.function.Function;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.minelittlepony.unicopia.recipe.ingredient.Ingredient;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.minelittlepony.unicopia.recipe.ingredient.PredicatedIngredient;
|
||||
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
public class Utils {
|
||||
public final class Utils {
|
||||
private Utils() {}
|
||||
|
||||
static final Random RANDOM = new Random();
|
||||
public static final Random RANDOM = new Random();
|
||||
|
||||
static <T> DefaultedList<T> read(PacketByteBuf buf, T def, Function<PacketByteBuf, T> reader) {
|
||||
public static <T> DefaultedList<T> read(PacketByteBuf buf, T def, Function<PacketByteBuf, T> reader) {
|
||||
DefaultedList<T> list = DefaultedList.ofSize(buf.readInt(), def);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
list.set(i, reader.apply(buf));
|
||||
|
@ -25,18 +31,32 @@ public class Utils {
|
|||
return list;
|
||||
}
|
||||
|
||||
static <T> void write(PacketByteBuf buf, DefaultedList<T> list, BiConsumer<T, PacketByteBuf> writer) {
|
||||
public static <T> void write(PacketByteBuf buf, DefaultedList<T> list, BiConsumer<T, PacketByteBuf> writer) {
|
||||
buf.writeInt(list.size());
|
||||
list.forEach(i -> writer.accept(i, buf));
|
||||
}
|
||||
|
||||
public static Identifier asIdentifier(JsonElement json) {
|
||||
return new Identifier(json.getAsString());
|
||||
}
|
||||
|
||||
public static <C extends Inventory> boolean matchShapeless(DefaultedList<Ingredient> ingredients, C inv, int mult) {
|
||||
public static Identifier getIdentifier(JsonObject json, String property) {
|
||||
return new Identifier(JsonHelper.getString(json, property));
|
||||
}
|
||||
|
||||
public static <T> T require(T reference, String errorMessage) {
|
||||
if (reference == null) {
|
||||
throw new JsonParseException(errorMessage);
|
||||
}
|
||||
return reference;
|
||||
}
|
||||
|
||||
public static <C extends Inventory> boolean matchShapeless(DefaultedList<PredicatedIngredient> ingredients, C inv, int mult) {
|
||||
if (mult == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Ingredient> toMatch = Lists.newArrayList(ingredients);
|
||||
List<PredicatedIngredient> toMatch = Lists.newArrayList(ingredients);
|
||||
|
||||
for (int i = 0; i < inv.getInvSize(); i++) {
|
||||
ItemStack stack = inv.getInvStack(i);
|
||||
|
@ -51,7 +71,7 @@ public class Utils {
|
|||
return toMatch.isEmpty();
|
||||
}
|
||||
|
||||
private static boolean removeMatch(List<Ingredient> toMatch, ItemStack stack, int materialMult) {
|
||||
private static boolean removeMatch(List<PredicatedIngredient> toMatch, ItemStack stack, int materialMult) {
|
||||
return toMatch.stream()
|
||||
.filter(s -> s.matches(stack, materialMult))
|
||||
.findFirst()
|
||||
|
|
|
@ -1,25 +1,27 @@
|
|||
package com.minelittlepony.unicopia.recipe.ingredient;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.minelittlepony.unicopia.recipe.Utils;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
/**
|
||||
* Requires only one of the sub-ingredients to match when matching.
|
||||
* Makes a random choice from a pool of alternatives when crafting.
|
||||
*/
|
||||
class ChoicePredicate implements Ingredient.Predicate {
|
||||
static Ingredient.Predicate read(JsonArray arr) {
|
||||
return new ChoicePredicate(Ingredient.many(arr));
|
||||
class ChoicePredicate implements Predicate {
|
||||
static Predicate read(JsonArray arr) {
|
||||
return new ChoicePredicate(PredicatedIngredient.many(arr));
|
||||
}
|
||||
|
||||
private final List<Ingredient> options;
|
||||
private final DefaultedList<PredicatedIngredient> options;
|
||||
|
||||
ChoicePredicate(List<Ingredient> options) {
|
||||
ChoicePredicate(DefaultedList<PredicatedIngredient> options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
|
@ -34,13 +36,24 @@ class ChoicePredicate implements Ingredient.Predicate {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
buf.writeInt(options.size());
|
||||
options.forEach(i -> i.write(buf));
|
||||
public Stream<ItemStack> getMatchingStacks() {
|
||||
return options.stream().flatMap(PredicatedIngredient::getMatchingStacks).distinct();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ItemStack> getMatchingStacks() {
|
||||
return options.stream().flatMap(Ingredient::getMatchingStacks).distinct();
|
||||
public PredicateSerializer<?> getSerializer() {
|
||||
return PredicateSerializer.CHOICE;
|
||||
}
|
||||
|
||||
static final class Serializer implements PredicateSerializer<ChoicePredicate> {
|
||||
@Override
|
||||
public Predicate read(PacketByteBuf buf) {
|
||||
return new ChoicePredicate(Utils.read(buf, PredicatedIngredient.EMPTY, PredicatedIngredient::read));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf, ChoicePredicate predicate) {
|
||||
Utils.write(buf, predicate.options, PredicatedIngredient::write);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ import java.util.function.BiPredicate;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.recipe.Utils;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.Lazy;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
|
@ -18,7 +18,7 @@ import net.minecraft.util.Util;
|
|||
* Tests for whether a tag contains the input when matching.
|
||||
* Supplies a random item from the tag as the output when crafting.
|
||||
*/
|
||||
class DamagePredicate implements Ingredient.Predicate {
|
||||
class DamagePredicate implements Predicate {
|
||||
private static final Map<String, BiPredicate<Integer, Integer>> OPERATIONS = Util.make(new HashMap<>(), map -> {
|
||||
map.put("==", (a, b) -> a == b);
|
||||
map.put("!=", (a, b) -> a != b);
|
||||
|
@ -28,35 +28,15 @@ class DamagePredicate implements Ingredient.Predicate {
|
|||
map.put("<=", (a, b) -> a <= b);
|
||||
});
|
||||
|
||||
static Ingredient.Predicate read(PacketByteBuf buf) {
|
||||
int count = buf.readInt();
|
||||
if (count == 0) {
|
||||
return EMPTY;
|
||||
}
|
||||
return new DamagePredicate(buf.readInt(), buf.readString(32767));
|
||||
}
|
||||
|
||||
static Ingredient.Predicate read(JsonObject json) {
|
||||
if (!json.has("damage")) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
JsonObject o = JsonHelper.getObject(json, "damage");
|
||||
return new DamagePredicate(
|
||||
JsonHelper.getInt(o, "damage"),
|
||||
JsonHelper.getString(o, "op")
|
||||
);
|
||||
}
|
||||
|
||||
private final String op;
|
||||
private final int damage;
|
||||
|
||||
private final Lazy<BiPredicate<Integer, Integer>> operation;
|
||||
private final BiPredicate<Integer, Integer> operation;
|
||||
|
||||
DamagePredicate(int damage, String op) {
|
||||
this.op = op.trim();
|
||||
this.damage = damage;
|
||||
this.operation = new Lazy<>(() -> OPERATIONS.get(op));
|
||||
this.operation = Utils.require(OPERATIONS.get(op), "Invalid damage tag '" + op + "' " + damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -72,13 +52,41 @@ class DamagePredicate implements Ingredient.Predicate {
|
|||
|
||||
@Override
|
||||
public boolean matches(ItemStack other, int materialMult) {
|
||||
return !other.isEmpty() && operation.get().test(other.getDamage(), damage);
|
||||
return !other.isEmpty() && operation.test(other.getDamage(), damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
buf.writeInt(1);
|
||||
buf.writeInt(damage);
|
||||
buf.writeString(op);
|
||||
public PredicateSerializer<?> getSerializer() {
|
||||
return PredicateSerializer.DAMAGE;
|
||||
}
|
||||
|
||||
static final class Serializer implements PredicateSerializer<DamagePredicate>, PredicateSerializer.JsonReader {
|
||||
@Override
|
||||
public Predicate read(PacketByteBuf buf) {
|
||||
int count = buf.readInt();
|
||||
if (count == 0) {
|
||||
return Predicate.EMPTY;
|
||||
}
|
||||
return new DamagePredicate(buf.readInt(), buf.readString(32767));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf, DamagePredicate predicate) {
|
||||
buf.writeInt(predicate.damage);
|
||||
buf.writeString(predicate.op);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate read(JsonObject json) {
|
||||
if (!json.has("damage")) {
|
||||
return Predicate.EMPTY;
|
||||
}
|
||||
|
||||
JsonObject o = JsonHelper.getObject(json, "damage");
|
||||
return new DamagePredicate(
|
||||
JsonHelper.getInt(o, "damage"),
|
||||
JsonHelper.getString(o, "op")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ import java.util.stream.Stream;
|
|||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.minelittlepony.unicopia.recipe.Utils;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
|
@ -18,48 +20,20 @@ import net.minecraft.util.registry.Registry;
|
|||
* A predicate that tests for a specific enchantment on an input when matching.
|
||||
* Appends that enchantment to the output when crafting.
|
||||
*/
|
||||
class EnchantmentPredicate implements Ingredient.Predicate {
|
||||
public static Ingredient.Predicate read(PacketByteBuf buf) {
|
||||
int level = buf.readInt();
|
||||
if (level == 0) {
|
||||
return EMPTY;
|
||||
}
|
||||
return new EnchantmentPredicate(Registry.ENCHANTMENT.get(buf.readIdentifier()), level);
|
||||
}
|
||||
|
||||
static Ingredient.Predicate read(JsonObject json) {
|
||||
|
||||
if (!json.has("enchantment")) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
JsonElement e = json.get("enchantment");
|
||||
|
||||
if (e.isJsonObject()) {
|
||||
JsonObject o = e.getAsJsonObject();
|
||||
Enchantment enchantment = Registry.ENCHANTMENT.get(new Identifier(o.get("id").getAsString()));
|
||||
int level = o.has("level") ? o.get("level").getAsInt() : 1;
|
||||
|
||||
return new EnchantmentPredicate(enchantment, level);
|
||||
}
|
||||
|
||||
Enchantment enchantment = Registry.ENCHANTMENT.get(new Identifier(e.getAsString()));
|
||||
return new EnchantmentPredicate(enchantment, 1);
|
||||
}
|
||||
|
||||
class EnchantmentPredicate implements Predicate {
|
||||
private final int level;
|
||||
private final Enchantment enchantment;
|
||||
|
||||
EnchantmentPredicate(Enchantment enchantment, int level) {
|
||||
this.enchantment = enchantment;
|
||||
EnchantmentPredicate(Identifier id, int level) {
|
||||
this.enchantment = Utils.require(Registry.ENCHANTMENT.get(id), "Invalid enchantment tag '" + id + "'");
|
||||
this.level = level;
|
||||
if (enchantment == null) {
|
||||
throw new JsonParseException("Invalid enchantment (null)");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack applyModifiers(ItemStack output, Random random) {
|
||||
if (output.isEmpty()) {
|
||||
output = new ItemStack(Items.ENCHANTED_BOOK);
|
||||
}
|
||||
output.addEnchantment(enchantment, level);
|
||||
return output;
|
||||
}
|
||||
|
@ -69,14 +43,47 @@ class EnchantmentPredicate implements Ingredient.Predicate {
|
|||
return EnchantmentHelper.getLevel(enchantment, stack) >= level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
buf.writeInt(level);
|
||||
buf.writeIdentifier(Registry.ENCHANTMENT.getId(enchantment));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ItemStack> getMatchingStacks() {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PredicateSerializer<?> getSerializer() {
|
||||
return PredicateSerializer.ENCHANTMENT;
|
||||
}
|
||||
|
||||
static final class Serializer implements PredicateSerializer<EnchantmentPredicate>, PredicateSerializer.JsonReader {
|
||||
@Override
|
||||
public Predicate read(PacketByteBuf buf) {
|
||||
int level = buf.readInt();
|
||||
if (level == 0) {
|
||||
return Predicate.EMPTY;
|
||||
}
|
||||
return new EnchantmentPredicate(buf.readIdentifier(), level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf, EnchantmentPredicate predicate) {
|
||||
buf.writeInt(predicate.level);
|
||||
buf.writeIdentifier(Registry.ENCHANTMENT.getId(predicate.enchantment));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate read(JsonObject json) {
|
||||
if (!json.has("enchantment")) {
|
||||
return Predicate.EMPTY;
|
||||
}
|
||||
|
||||
JsonElement e = json.get("enchantment");
|
||||
|
||||
if (e.isJsonObject()) {
|
||||
JsonObject o = e.getAsJsonObject();
|
||||
return new EnchantmentPredicate(Utils.getIdentifier(o, "id"), Math.max(1, JsonHelper.getInt(o, "level", 1)));
|
||||
}
|
||||
|
||||
return new EnchantmentPredicate(Utils.asIdentifier(e), 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
package com.minelittlepony.unicopia.recipe.ingredient;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
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.JsonParseException;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
import net.minecraft.util.Lazy;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
@Immutable
|
||||
public class Ingredient {
|
||||
public static final Ingredient EMPTY = new Ingredient(Predicate.EMPTY, Predicate.EMPTY, Predicate.EMPTY, Predicate.EMPTY, Predicate.EMPTY);
|
||||
|
||||
private final List<Predicate> predicates;
|
||||
|
||||
private final Lazy<List<ItemStack>> matchingStacks;
|
||||
private final Lazy<net.minecraft.recipe.Ingredient> preview;
|
||||
|
||||
Ingredient(Predicate... predicates) {
|
||||
this.predicates = Lists.newArrayList(predicates);
|
||||
this.matchingStacks = new Lazy<>(() -> {
|
||||
return this.predicates.stream()
|
||||
.flatMap(Predicate::getMatchingStacks)
|
||||
.filter(s -> matches(s, 1))
|
||||
.collect(Collectors.toList());
|
||||
});
|
||||
this.preview = new Lazy<>(() -> {
|
||||
return net.minecraft.recipe.Ingredient.ofStacks(getMatchingStacks().toArray(ItemStack[]::new));
|
||||
});
|
||||
}
|
||||
|
||||
public Stream<ItemStack> getMatchingStacks() {
|
||||
return matchingStacks.get().stream();
|
||||
}
|
||||
|
||||
public net.minecraft.recipe.Ingredient getPreview() {
|
||||
return preview.get();
|
||||
}
|
||||
|
||||
public ItemStack getStack(Random random) {
|
||||
ItemStack[] output = new ItemStack[] { ItemStack.EMPTY.copy() };
|
||||
|
||||
predicates.forEach(p -> output[0] = p.applyModifiers(output[0], random));
|
||||
|
||||
return output[0];
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack other, int materialMult) {
|
||||
return predicates.stream().allMatch(p -> p.matches(other, materialMult));
|
||||
}
|
||||
|
||||
public void write(PacketByteBuf buf) {
|
||||
predicates.forEach(p -> p.write(buf));
|
||||
}
|
||||
|
||||
public static Ingredient read(PacketByteBuf buf) {
|
||||
return new Ingredient(
|
||||
StackPredicate.read(buf),
|
||||
TagPredicate.read(buf),
|
||||
SpellPredicate.read(buf),
|
||||
EnchantmentPredicate.read(buf),
|
||||
ToxicityPredicate.read(buf));
|
||||
}
|
||||
|
||||
public static Ingredient one(JsonElement json) {
|
||||
|
||||
if (json.isJsonArray()) {
|
||||
return new Ingredient(
|
||||
ChoicePredicate.read(json.getAsJsonArray()),
|
||||
Predicate.EMPTY,
|
||||
Predicate.EMPTY,
|
||||
Predicate.EMPTY,
|
||||
Predicate.EMPTY);
|
||||
}
|
||||
|
||||
JsonObject obj = json.getAsJsonObject();
|
||||
return new Ingredient(
|
||||
StackPredicate.read(obj),
|
||||
TagPredicate.read(obj),
|
||||
SpellPredicate.read(obj),
|
||||
EnchantmentPredicate.read(obj),
|
||||
ToxicityPredicate.read(obj));
|
||||
}
|
||||
|
||||
public static DefaultedList<Ingredient> many(JsonArray arr) {
|
||||
DefaultedList<Ingredient> ingredients = DefaultedList.copyOf(EMPTY);
|
||||
|
||||
arr.forEach(i -> ingredients.add(one(i)));
|
||||
|
||||
if (ingredients.isEmpty()) {
|
||||
throw new JsonParseException("Recipe cannot have 0 ingredients");
|
||||
}
|
||||
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
public static DefaultedList<net.minecraft.recipe.Ingredient> preview(DefaultedList<Ingredient> input) {
|
||||
return preview(input, DefaultedList.of());
|
||||
}
|
||||
|
||||
public static DefaultedList<net.minecraft.recipe.Ingredient> preview(DefaultedList<Ingredient> input, DefaultedList<net.minecraft.recipe.Ingredient> output) {
|
||||
input.stream().map(Ingredient::getPreview).forEach(output::add);
|
||||
return output;
|
||||
}
|
||||
|
||||
public interface Predicate {
|
||||
Predicate EMPTY = new Predicate() {
|
||||
@Override
|
||||
public Stream<ItemStack> getMatchingStacks() {
|
||||
return Stream.empty();
|
||||
}
|
||||
@Override
|
||||
public boolean matches(ItemStack stack, int materialMult) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Stream<ItemStack> getMatchingStacks();
|
||||
|
||||
boolean matches(ItemStack stack, int materialMult);
|
||||
|
||||
default ItemStack applyModifiers(ItemStack output, Random random) {
|
||||
return output;
|
||||
}
|
||||
|
||||
default void write(PacketByteBuf buf) {
|
||||
buf.writeInt(0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.minelittlepony.unicopia.recipe.ingredient;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.minelittlepony.unicopia.recipe.Utils;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionUtil;
|
||||
import net.minecraft.potion.Potions;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
/**
|
||||
* A predicate that tests for a specific enchantment on an input when matching.
|
||||
* Appends that enchantment to the output when crafting.
|
||||
*/
|
||||
class PotionPredicate implements Predicate {
|
||||
private final Potion potion;
|
||||
|
||||
PotionPredicate(Identifier id, int level) {
|
||||
this.potion = Registry.POTION.get(id);
|
||||
if (potion == Potions.EMPTY) {
|
||||
throw new JsonParseException("Invalid potion tag '" + id + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack applyModifiers(ItemStack output, Random random) {
|
||||
if (output.isEmpty()) {
|
||||
output = new ItemStack(Items.POTION);
|
||||
}
|
||||
PotionUtil.setPotion(output, potion);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(ItemStack stack, int materialMult) {
|
||||
return PotionUtil.getPotion(stack) == potion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ItemStack> getMatchingStacks() {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PredicateSerializer<?> getSerializer() {
|
||||
return PredicateSerializer.ENCHANTMENT;
|
||||
}
|
||||
|
||||
static final class Serializer implements PredicateSerializer<PotionPredicate>, PredicateSerializer.JsonReader {
|
||||
@Override
|
||||
public Predicate read(PacketByteBuf buf) {
|
||||
return new PotionPredicate(buf.readIdentifier(), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf, PotionPredicate predicate) {
|
||||
buf.writeIdentifier(Registry.POTION.getId(predicate.potion));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate read(JsonObject json) {
|
||||
if (!json.has("potion")) {
|
||||
return Predicate.EMPTY;
|
||||
}
|
||||
|
||||
JsonElement e = json.get("potion");
|
||||
|
||||
if (e.isJsonObject()) {
|
||||
JsonObject o = e.getAsJsonObject();
|
||||
return new PotionPredicate(Utils.getIdentifier(o, "id"), Math.max(1, JsonHelper.getInt(o, "level", 1)));
|
||||
}
|
||||
|
||||
return new PotionPredicate(Utils.asIdentifier(e), 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.minelittlepony.unicopia.recipe.ingredient;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
public interface Predicate {
|
||||
Predicate EMPTY = new Predicate() {
|
||||
@Override
|
||||
public Stream<ItemStack> getMatchingStacks() {
|
||||
return Stream.empty();
|
||||
}
|
||||
@Override
|
||||
public boolean matches(ItemStack stack, int materialMult) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PredicateSerializer<? super Predicate> getSerializer() {
|
||||
return PredicateSerializer.EMPTY;
|
||||
}
|
||||
};
|
||||
|
||||
Stream<ItemStack> getMatchingStacks();
|
||||
|
||||
boolean matches(ItemStack stack, int materialMult);
|
||||
|
||||
PredicateSerializer<?> getSerializer();
|
||||
|
||||
default ItemStack applyModifiers(ItemStack output, Random random) {
|
||||
return output;
|
||||
}
|
||||
|
||||
default void write(PacketByteBuf buf) {
|
||||
@SuppressWarnings("unchecked")
|
||||
PredicateSerializer<Predicate> serializer = (PredicateSerializer<Predicate>)getSerializer();
|
||||
buf.writeIdentifier(PredicateSerializer.REGISTRY.getId(serializer));
|
||||
serializer.write(buf, this);
|
||||
}
|
||||
|
||||
static Predicate read(PacketByteBuf buf) {
|
||||
return PredicateSerializer.REGISTRY.get(buf.readIdentifier()).read(buf);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.minelittlepony.unicopia.recipe.ingredient;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
|
||||
public interface PredicateSerializer<T extends Predicate> {
|
||||
Registry<PredicateSerializer<?>> REGISTRY = new SimpleRegistry<>();
|
||||
Registry<JsonReader> JSON_READERS = new SimpleRegistry<>();
|
||||
|
||||
PredicateSerializer<Predicate> EMPTY = register("empty", new PredicateSerializer<Predicate>() {
|
||||
@Override
|
||||
public Predicate read(PacketByteBuf buf) {
|
||||
return Predicate.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf, Predicate predicate) {
|
||||
}
|
||||
});
|
||||
PredicateSerializer<StackPredicate> STACK = register("stack", new StackPredicate.Serializer());
|
||||
PredicateSerializer<TagPredicate> TAG = register("tag", new TagPredicate.Serializer());
|
||||
PredicateSerializer<ChoicePredicate> CHOICE = register("choice", new ChoicePredicate.Serializer());
|
||||
PredicateSerializer<SpellPredicate> SPELL = register("spell", new SpellPredicate.Serializer());
|
||||
PredicateSerializer<EnchantmentPredicate> ENCHANTMENT = register("enchantment", new EnchantmentPredicate.Serializer());
|
||||
PredicateSerializer<PotionPredicate> POTION = register("potion", new PotionPredicate.Serializer());
|
||||
PredicateSerializer<DamagePredicate> DAMAGE = register("damage", new DamagePredicate.Serializer());
|
||||
PredicateSerializer<ToxicityPredicate> TOXICITY = register("toxicity", new ToxicityPredicate.Serializer());
|
||||
|
||||
static <T extends Predicate> PredicateSerializer<T> register(String name, PredicateSerializer<T> entry) {
|
||||
Identifier id = new Identifier("unicopia", name);
|
||||
if (entry instanceof JsonReader) {
|
||||
Registry.register(JSON_READERS, id, (JsonReader)entry);
|
||||
}
|
||||
return Registry.register(REGISTRY, id, entry);
|
||||
}
|
||||
|
||||
Predicate read(PacketByteBuf buf);
|
||||
|
||||
void write(PacketByteBuf buf, T predicate);
|
||||
|
||||
@FunctionalInterface
|
||||
interface JsonReader {
|
||||
Predicate read(JsonObject json);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package com.minelittlepony.unicopia.recipe.ingredient;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.minelittlepony.unicopia.recipe.Utils;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
import net.minecraft.util.Lazy;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
@Immutable
|
||||
public class PredicatedIngredient {
|
||||
public static final PredicatedIngredient EMPTY = new PredicatedIngredient(DefaultedList.of());
|
||||
|
||||
private final DefaultedList<Predicate> predicates;
|
||||
|
||||
private final Lazy<List<ItemStack>> matchingStacks;
|
||||
private final Lazy<net.minecraft.recipe.Ingredient> preview;
|
||||
|
||||
PredicatedIngredient(DefaultedList<Predicate> predicates) {
|
||||
this.predicates = predicates;
|
||||
this.matchingStacks = new Lazy<>(() -> {
|
||||
return this.predicates.stream()
|
||||
.flatMap(Predicate::getMatchingStacks)
|
||||
.filter(s -> matches(s, 1))
|
||||
.collect(Collectors.toList());
|
||||
});
|
||||
this.preview = new Lazy<>(() -> {
|
||||
return net.minecraft.recipe.Ingredient.ofStacks(getMatchingStacks().toArray(ItemStack[]::new));
|
||||
});
|
||||
}
|
||||
|
||||
public Stream<ItemStack> getMatchingStacks() {
|
||||
return matchingStacks.get().stream();
|
||||
}
|
||||
|
||||
public net.minecraft.recipe.Ingredient getPreview() {
|
||||
return preview.get();
|
||||
}
|
||||
|
||||
public ItemStack getStack(Random random) {
|
||||
ItemStack[] output = new ItemStack[] { ItemStack.EMPTY.copy() };
|
||||
|
||||
predicates.forEach(p -> output[0] = p.applyModifiers(output[0], random));
|
||||
|
||||
return output[0];
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack other, int materialMult) {
|
||||
return predicates.stream().allMatch(p -> p.matches(other, materialMult));
|
||||
}
|
||||
|
||||
public void write(PacketByteBuf buf) {
|
||||
Utils.write(buf, predicates, Predicate::write);
|
||||
}
|
||||
|
||||
public static PredicatedIngredient read(PacketByteBuf buf) {
|
||||
return new PredicatedIngredient(Utils.read(buf, Predicate.EMPTY, Predicate::read));
|
||||
}
|
||||
|
||||
public static PredicatedIngredient one(JsonElement json) {
|
||||
|
||||
if (json.isJsonArray()) {
|
||||
return new PredicatedIngredient(DefaultedList.copyOf(Predicate.EMPTY, ChoicePredicate.read(json.getAsJsonArray())));
|
||||
}
|
||||
|
||||
JsonObject obj = json.getAsJsonObject();
|
||||
|
||||
Predicate primary = StackPredicate.read(obj);
|
||||
Predicate secondary = TagPredicate.read(obj);
|
||||
if (primary != Predicate.EMPTY && secondary != Predicate.EMPTY) {
|
||||
throw new JsonParseException("Invalid ingredient. Cannot have both an item and a tag requirement.");
|
||||
}
|
||||
if (primary == secondary) {
|
||||
throw new JsonParseException("Invalid ingredient. Must have either an item or tag requirement.");
|
||||
}
|
||||
|
||||
DefaultedList<Predicate> predicates = DefaultedList.of();
|
||||
predicates.add(primary);
|
||||
predicates.add(secondary);
|
||||
PredicateSerializer.JSON_READERS.stream()
|
||||
.map(reader -> reader.read(obj))
|
||||
.filter(i -> i != Predicate.EMPTY)
|
||||
.forEach(predicates::add);
|
||||
|
||||
return new PredicatedIngredient(predicates);
|
||||
}
|
||||
|
||||
public static DefaultedList<PredicatedIngredient> many(JsonArray arr) {
|
||||
|
||||
if (arr.size() == 0) {
|
||||
throw new JsonParseException("Recipe cannot have 0 ingredients");
|
||||
}
|
||||
|
||||
DefaultedList<PredicatedIngredient> ingredients = DefaultedList.ofSize(arr.size(), EMPTY);
|
||||
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
ingredients.set(i, one(arr.get(i)));
|
||||
}
|
||||
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
public static DefaultedList<Ingredient> preview(DefaultedList<PredicatedIngredient> input) {
|
||||
return preview(input, DefaultedList.of());
|
||||
}
|
||||
|
||||
public static DefaultedList<Ingredient> preview(DefaultedList<PredicatedIngredient> input, DefaultedList<Ingredient> output) {
|
||||
input.stream().map(PredicatedIngredient::getPreview).forEach(output::add);
|
||||
return output;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,10 @@ import java.util.Random;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.magic.MagicEffect;
|
||||
import com.minelittlepony.unicopia.magic.spell.SpellRegistry;
|
||||
import com.minelittlepony.unicopia.recipe.Utils;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
@ -13,47 +16,57 @@ import net.minecraft.util.PacketByteBuf;
|
|||
* A predicate that tests for a specific spell on an input when matching.
|
||||
* Appends that spell to the output when crafting.
|
||||
*/
|
||||
class SpellPredicate implements Ingredient.Predicate {
|
||||
static Ingredient.Predicate read(PacketByteBuf buf) {
|
||||
int level = buf.readInt();
|
||||
if (level == 0) {
|
||||
return EMPTY;
|
||||
}
|
||||
return new SpellPredicate(buf.readString());
|
||||
}
|
||||
|
||||
static Ingredient.Predicate read(JsonObject json) {
|
||||
if (!json.has("spell")) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
return new SpellPredicate(json.get("spell").getAsString());
|
||||
}
|
||||
|
||||
private final String spell;
|
||||
class SpellPredicate implements Predicate {
|
||||
private final MagicEffect spell;
|
||||
|
||||
SpellPredicate(String spell) {
|
||||
this.spell = spell;
|
||||
this.spell = Utils.require(SpellRegistry.instance().getSpellFromName(spell), "Unknown spell tag '" + spell + "'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack applyModifiers(ItemStack output, Random random) {
|
||||
return SpellRegistry.instance().enchantStack(output, spell);
|
||||
if (output.isEmpty()) {
|
||||
output = new ItemStack(UItems.GEM);
|
||||
}
|
||||
return SpellRegistry.instance().enchantStack(output, spell.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(ItemStack stack, int materialMult) {
|
||||
return SpellRegistry.getKeyFromStack(stack).equals(spell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
buf.writeInt(1);
|
||||
buf.writeString(spell);
|
||||
return SpellRegistry.getKeyFromStack(stack).equals(spell.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ItemStack> getMatchingStacks() {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PredicateSerializer<?> getSerializer() {
|
||||
return PredicateSerializer.SPELL;
|
||||
}
|
||||
|
||||
static final class Serializer implements PredicateSerializer<SpellPredicate>, PredicateSerializer.JsonReader {
|
||||
@Override
|
||||
public Predicate read(PacketByteBuf buf) {
|
||||
int level = buf.readInt();
|
||||
if (level == 0) {
|
||||
return SpellPredicate.EMPTY;
|
||||
}
|
||||
return new SpellPredicate(buf.readString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf, SpellPredicate predicate) {
|
||||
buf.writeString(predicate.spell.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate read(JsonObject json) {
|
||||
if (!json.has("spell")) {
|
||||
return SpellPredicate.EMPTY;
|
||||
}
|
||||
return new SpellPredicate(json.get("spell").getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,14 @@ import java.util.stream.Stream;
|
|||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.minelittlepony.unicopia.recipe.Utils;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
|
@ -19,26 +21,8 @@ import net.minecraft.util.registry.Registry;
|
|||
* Tests for a specific item, stack size, and damage value when matching.
|
||||
* Presents that item as the output when crafting.
|
||||
*/
|
||||
class StackPredicate implements Ingredient.Predicate {
|
||||
static Ingredient.Predicate read(PacketByteBuf buf) {
|
||||
int count = buf.readInt();
|
||||
if (count == 0) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
return new StackPredicate(buf.readItemStack());
|
||||
}
|
||||
|
||||
DefaultedList<Ingredient> items = DefaultedList.copyOf(Ingredient.EMPTY);
|
||||
while (items.size() < count) {
|
||||
items.add(Ingredient.read(buf));
|
||||
}
|
||||
|
||||
return new ChoicePredicate(items);
|
||||
}
|
||||
|
||||
static Ingredient.Predicate read(JsonObject json) {
|
||||
class StackPredicate implements Predicate {
|
||||
static Predicate read(JsonObject json) {
|
||||
if (!json.has("item")) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
@ -49,15 +33,16 @@ class StackPredicate implements Ingredient.Predicate {
|
|||
return ChoicePredicate.read(e.getAsJsonArray());
|
||||
}
|
||||
|
||||
int count = Math.max(1, JsonHelper.getInt(json, "count", 1));
|
||||
|
||||
if (e.isJsonObject()) {
|
||||
JsonObject o = e.getAsJsonObject();
|
||||
|
||||
Item item = o.has("item") ? Registry.ITEM.get(new Identifier(o.get("item").getAsString())) : Items.AIR;
|
||||
int size = o.has("count") ? Math.max(1, o.get("count").getAsInt()) : 1;
|
||||
return new StackPredicate(new ItemStack(item, size));
|
||||
Item item = o.has("item") ? Registry.ITEM.get(Utils.getIdentifier(o, "item")) : Items.AIR;
|
||||
return new StackPredicate(new ItemStack(item, count));
|
||||
}
|
||||
|
||||
return new StackPredicate(new ItemStack(Registry.ITEM.get(new Identifier(e.getAsString()))));
|
||||
return new StackPredicate(new ItemStack(Registry.ITEM.get(Utils.asIdentifier(e)), count));
|
||||
}
|
||||
|
||||
private final ItemStack stack;
|
||||
|
@ -101,8 +86,20 @@ class StackPredicate implements Ingredient.Predicate {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
buf.writeInt(-1);
|
||||
buf.writeItemStack(stack);
|
||||
public PredicateSerializer<?> getSerializer() {
|
||||
return PredicateSerializer.STACK;
|
||||
}
|
||||
|
||||
static final class Serializer implements PredicateSerializer<StackPredicate> {
|
||||
@Override
|
||||
public Predicate read(PacketByteBuf buf) {
|
||||
return new StackPredicate(buf.readItemStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf, StackPredicate predicate) {
|
||||
buf.writeItemStack(predicate.stack);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,57 +5,41 @@ import java.util.stream.Stream;
|
|||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.minelittlepony.unicopia.recipe.Utils;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tag.ItemTags;
|
||||
import net.minecraft.tag.Tag;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
/**
|
||||
* Tests for whether a tag contains the input when matching.
|
||||
* Supplies a random item from the tag as the output when crafting.
|
||||
*/
|
||||
class TagPredicate implements Ingredient.Predicate {
|
||||
static Ingredient.Predicate read(PacketByteBuf buf) {
|
||||
int count = buf.readInt();
|
||||
if (count == 0) {
|
||||
return EMPTY;
|
||||
}
|
||||
return new TagPredicate(buf.readIdentifier(), count);
|
||||
}
|
||||
|
||||
static Ingredient.Predicate read(JsonObject json) {
|
||||
class TagPredicate implements Predicate {
|
||||
static Predicate read(JsonObject json) {
|
||||
if (!json.has("tag")) {
|
||||
return EMPTY;
|
||||
return Predicate.EMPTY;
|
||||
}
|
||||
|
||||
JsonElement e = json.get("tag");
|
||||
if (e.isJsonObject()) {
|
||||
JsonObject o = e.getAsJsonObject();
|
||||
|
||||
Identifier id = new Identifier(o.get("id").getAsString());
|
||||
int count = o.has("count") ? Math.max(1, o.get("count").getAsInt()) : 1;
|
||||
if (count == 0) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
return new TagPredicate(id, count);
|
||||
return new TagPredicate(Utils.getIdentifier(o, "id"), Math.max(1, JsonHelper.getInt(o, "count", 1)));
|
||||
}
|
||||
|
||||
return new TagPredicate(new Identifier(json.getAsString()), 1);
|
||||
return new TagPredicate(Utils.asIdentifier(e), 1);
|
||||
}
|
||||
|
||||
private final Tag<Item> tag;
|
||||
private final int count;
|
||||
|
||||
TagPredicate(Identifier res, int count) {
|
||||
tag = ItemTags.getContainer().get(res);
|
||||
tag = Utils.require(ItemTags.getContainer().get(res), "Unknown item tag '" + res + "'");
|
||||
this.count = count;
|
||||
if (tag == null) {
|
||||
throw new JsonSyntaxException("Unknown item tag '" + res + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -80,4 +64,26 @@ class TagPredicate implements Ingredient.Predicate {
|
|||
buf.writeInt(count);
|
||||
buf.writeIdentifier(tag.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PredicateSerializer<?> getSerializer() {
|
||||
return PredicateSerializer.TAG;
|
||||
}
|
||||
|
||||
static final class Serializer implements PredicateSerializer<TagPredicate> {
|
||||
@Override
|
||||
public Predicate read(PacketByteBuf buf) {
|
||||
int count = buf.readInt();
|
||||
if (count == 0) {
|
||||
return Predicate.EMPTY;
|
||||
}
|
||||
return new TagPredicate(buf.readIdentifier(), count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf, TagPredicate predicate) {
|
||||
buf.writeInt(predicate.count);
|
||||
buf.writeIdentifier(predicate.tag.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,35 +5,21 @@ import java.util.stream.Stream;
|
|||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.toxin.Toxicity;
|
||||
import com.minelittlepony.unicopia.recipe.Utils;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
/**
|
||||
* A predicate that tests for a specific spell on an input when matching.
|
||||
* Appends that spell to the output when crafting.
|
||||
*/
|
||||
class ToxicityPredicate implements Ingredient.Predicate {
|
||||
static Ingredient.Predicate read(PacketByteBuf buf) {
|
||||
int ordinal = buf.readInt();
|
||||
if (ordinal == 0) {
|
||||
return EMPTY;
|
||||
}
|
||||
return new ToxicityPredicate(Toxicity.values()[ordinal - 1]);
|
||||
}
|
||||
|
||||
static Ingredient.Predicate read(JsonObject json) {
|
||||
if (!json.has("toxicity")) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
return new ToxicityPredicate(Toxicity.byName(json.get("toxicity").getAsString()));
|
||||
}
|
||||
|
||||
class ToxicityPredicate implements Predicate {
|
||||
private final Toxicity toxicity;
|
||||
|
||||
ToxicityPredicate(Toxicity toxicity) {
|
||||
this.toxicity = toxicity;
|
||||
ToxicityPredicate(String name) {
|
||||
this.toxicity = Utils.require(Toxicity.byName(name), "Unknown toxicity tag '" + name + "'");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,13 +32,37 @@ class ToxicityPredicate implements Ingredient.Predicate {
|
|||
return Toxicity.fromStack(stack) == toxicity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
buf.writeInt(toxicity.ordinal() + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ItemStack> getMatchingStacks() {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PredicateSerializer<?> getSerializer() {
|
||||
return PredicateSerializer.TOXICITY;
|
||||
}
|
||||
|
||||
public static final class Serializer implements PredicateSerializer<ToxicityPredicate>, PredicateSerializer.JsonReader {
|
||||
|
||||
@Override
|
||||
public Predicate read(PacketByteBuf buf) {
|
||||
return new ToxicityPredicate(Toxicity.values()[buf.readInt()].name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf, ToxicityPredicate predicate) {
|
||||
buf.writeInt(predicate.toxicity.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate read(JsonObject json) {
|
||||
if (!json.has("toxicity")) {
|
||||
return Predicate.EMPTY;
|
||||
}
|
||||
|
||||
return new ToxicityPredicate(JsonHelper.getString(json, "toxicity"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -81,13 +81,13 @@ public enum Toxicity implements Toxin {
|
|||
if (stack.hasTag()) {
|
||||
Tag tag = stack.getTag().get("toxicity");
|
||||
if (tag != null) {
|
||||
return byName(tag.asString());
|
||||
return REGISTRY.getOrDefault(tag.asString(), SAFE);
|
||||
}
|
||||
}
|
||||
return SAFE;
|
||||
}
|
||||
|
||||
public static Toxicity byName(String name) {
|
||||
return REGISTRY.getOrDefault(name.toUpperCase(), SAFE);
|
||||
return REGISTRY.get(name.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{ "item": "unicopia:sugar_block" }
|
||||
],
|
||||
"*": [
|
||||
{ "item": "unicopia:crereal" }
|
||||
{ "item": "unicopia:cereal" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:boop_o_roops" }
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
],
|
||||
"key": {
|
||||
"#": [
|
||||
{ "item": "unicopia:chitin_block" }
|
||||
{ "item": "unicopia:chitin_shell_block" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:chiseled_chitin_shell_block", "count": 4 }
|
||||
|
|
|
@ -10,5 +10,5 @@
|
|||
{ "item": "unicopia:cloud_block" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:anvil", "data": 0, "count": 1 }
|
||||
"result": { "item": "unicopia:cloud_anvil", "count": 1 }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"type": "unicopia:crafting_shaped",
|
||||
"pattern": [
|
||||
" B ",
|
||||
"FFF",
|
||||
|
@ -10,15 +10,8 @@
|
|||
{ "item": "minecraft:bread" }
|
||||
],
|
||||
"F": [
|
||||
{ "item": "minecraft:red_flower", "data": 1 },
|
||||
{ "item": "minecraft:red_flower", "data": 2 },
|
||||
{ "item": "minecraft:red_flower", "data": 3 },
|
||||
{ "item": "minecraft:red_flower", "data": 4 },
|
||||
{ "item": "minecraft:red_flower", "data": 5 },
|
||||
{ "item": "minecraft:red_flower", "data": 6 },
|
||||
{ "item": "minecraft:red_flower", "data": 7 },
|
||||
{ "item": "minecraft:yellow_flower", "data": 0 }
|
||||
{ "tag": "unicopia:non_toxic" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:daffodil_daisy_sandwich", "data": 0, "count": 2 }
|
||||
"result": { "item": "unicopia:daffodil_daisy_sandwich", "tocicity": "safe", "count": 2 }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"type": "unicopia:crafting_shaped",
|
||||
"pattern": [
|
||||
" B ",
|
||||
"FFF",
|
||||
|
@ -10,17 +10,9 @@
|
|||
{ "item": "minecraft:bread" }
|
||||
],
|
||||
"F": [
|
||||
{ "item": "minecraft:red_flower", "data": 0 },
|
||||
{ "item": "minecraft:red_flower", "data": 1 },
|
||||
{ "item": "minecraft:red_flower", "data": 2 },
|
||||
{ "item": "minecraft:red_flower", "data": 3 },
|
||||
{ "item": "minecraft:red_flower", "data": 4 },
|
||||
{ "item": "minecraft:red_flower", "data": 5 },
|
||||
{ "item": "minecraft:red_flower", "data": 6 },
|
||||
{ "item": "minecraft:red_flower", "data": 7 },
|
||||
{ "item": "minecraft:red_flower", "data": 8 },
|
||||
{ "item": "minecraft:yellow_flower", "data": 0 }
|
||||
{ "tag": "unicopia:non_toxic" },
|
||||
{ "tag": "unicopia:fairly_toxic" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:daffodil_daisy_sandwich", "data": 2, "count": 2 }
|
||||
"result": { "item": "unicopia:daffodil_daisy_sandwich", "toxicity": "fair", "count": 2 }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"type": "unicopia:shapeless_crafting_spell",
|
||||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:corrupted_gem" },
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:gem", "spell": "inferno" },
|
||||
{ "item": "unicopia:gem", "spell": "darkness" },
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "tag": "#unicopia:unaligned" },
|
||||
{ "tag": "#unicopia:unaligned" },
|
||||
{ "tag": "#unicopia:unaligned" }
|
||||
{ "tag": "unicopia:harmonic_elementals" },
|
||||
{ "tag": "unicopia:harmonic_elementals" },
|
||||
{ "tag": "unicopia:harmonic_elementals" }
|
||||
],
|
||||
"result": {
|
||||
"item": [
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "tag": "unicopia:magic_energetic" },
|
||||
{ "tag": "unicopia:knowledge_elementals" },
|
||||
{ "item": "unicopia:gem", "spell": "fire" },
|
||||
{ "tag": "unicopia:magic_firey" }
|
||||
{ "tag": "unicopia:fire_elementals" }
|
||||
],
|
||||
"result": { "item": "unicopia:gem", "spell": "charge" }
|
||||
}
|
|
@ -4,8 +4,8 @@
|
|||
"ingredients": [
|
||||
{ "item": "unicopia:gem", "spell": "charge" },
|
||||
{ "item": "unicopia:corrupted_gem" },
|
||||
{ "tag": "unicopia:life" },
|
||||
{ "item": "minecraft:red_flower", "data": 0 }
|
||||
{ "tag": "unicopia:life_elementals" },
|
||||
{ "item": "minecraft:poppy" }
|
||||
],
|
||||
"result": { "item": "unicopia:gem", "spell": "drake" }
|
||||
}
|
|
@ -3,8 +3,8 @@
|
|||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:gem", "spell": "flame" },
|
||||
{ "tag": "unicopia:fire" },
|
||||
{ "tag": "unicopia:fire" }
|
||||
{ "tag": "unicopia:fire_elementals" },
|
||||
{ "tag": "unicopia:fire_elementals" }
|
||||
],
|
||||
"result": { "item": "unicopia:gem", "spell": "fire" }
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "tag": "unicopia:fire" },
|
||||
{ "tag": "unicopia:fire" },
|
||||
{ "tag": "unicopia:fire" }
|
||||
{ "tag": "unicopia:fire_elementals" },
|
||||
{ "tag": "unicopia:fire_elementals" },
|
||||
{ "tag": "unicopia:fire_elementals" }
|
||||
],
|
||||
"result": { "item": "unicopia:gem", "spell": "fire" }
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "tag": "unicopia:ice" },
|
||||
{ "tag": "unicopia:ice" },
|
||||
{ "tag": "unicopia:ice" }
|
||||
{ "tag": "unicopia:ice_elementals" },
|
||||
{ "tag": "unicopia:ice_elementals" },
|
||||
{ "tag": "unicopia:ice_elementals" }
|
||||
],
|
||||
"result": { "item": "unicopia:gem", "spell": "ice" }
|
||||
}
|
|
@ -3,8 +3,8 @@
|
|||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:gem", "spell": "fire" },
|
||||
{ "tag": "unicopia:fire" },
|
||||
{ "tag": "unicopia:fire" }
|
||||
{ "tag": "unicopia:fire_elementals" },
|
||||
{ "tag": "unicopia:fire_elementals" }
|
||||
],
|
||||
"result": { "item": "unicopia:corrupted_gem", "spell": "inferno" }
|
||||
}
|
|
@ -2,14 +2,9 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "tag": "unicopia:light" },
|
||||
{ "tag": "unicopia:light_elementals" },
|
||||
{ "item": "unicopia:gem", "spell": "fire" },
|
||||
[
|
||||
{ "item": "minecraft:apple" },
|
||||
{ "item": "unicopia:apple_green" },
|
||||
{ "item": "unicopia:apple_sweet" },
|
||||
{ "item": "unicopia:apple_sour" }
|
||||
]
|
||||
{ "tag": "unicopia:fresh_apples" }
|
||||
],
|
||||
"result": { "item": "unicopia:gem", "spell": "light" }
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "tag": "unicopia:sound"},
|
||||
"input": { "tag": "unicopia:sound_elementals"},
|
||||
"ingredients": [
|
||||
{ "tag": "unicopia:apple_bloom" },
|
||||
{ "tag": "unicopia:scootaloo" },
|
||||
{ "tag": "unicopia:sweetie_belle" }
|
||||
{ "tag": "unicopia:apple_bloom_spirit" },
|
||||
{ "tag": "unicopia:scootaloo_spirit" },
|
||||
{ "tag": "unicopia:sweetie_belle_spirit" }
|
||||
],
|
||||
"output": {
|
||||
"result": {
|
||||
"item": "unicopia:music_disc_crusade"
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "tag": "unicopia:sound"},
|
||||
"input": { "tag": "unicopia:sound_elementals"},
|
||||
"ingredients": [
|
||||
{ "item": "minecraft:diamond" },
|
||||
{ "item": "minecraft:diamond" },
|
||||
{ "item": "unicopia:boop_o_roops" }
|
||||
],
|
||||
"output": {
|
||||
"result": {
|
||||
"item": "unicopia:music_disc_funk"
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "tag": "unicopia:sound"},
|
||||
"input": { "tag": "unicopia:sound_elementals"},
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:gem", "spell": "awkward" },
|
||||
{ "item": "minecraft:feather" },
|
||||
{ "item": "minecraft:carrot" }
|
||||
],
|
||||
"output": {
|
||||
"result": {
|
||||
"item": "unicopia:music_disc_pet"
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "tag": "unicopia:sound"},
|
||||
"input": { "tag": "unicopia:sound_elementals"},
|
||||
"ingredients": [
|
||||
{ "item": "minecraft:diamond" },
|
||||
{ "item": "minecraft:diamond" },
|
||||
{ "item": "minecraft:diamond" }
|
||||
],
|
||||
"output": {
|
||||
"result": {
|
||||
"item": "unicopia:music_disc_popular"
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "tag": "unicopia:sound"},
|
||||
"input": { "tag": "unicopia:sound_elementals"},
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:gem", "spell": "awkward" },
|
||||
{ "item": "unicopia:gem", "spell": "awkward" },
|
||||
{ "item": "unicopia:gem", "spell": "awkward" }
|
||||
],
|
||||
"output": {
|
||||
"tag": "unicopia:sound"
|
||||
"result": {
|
||||
"tag": "unicopia:sound_elementals"
|
||||
}
|
||||
}
|
|
@ -2,12 +2,9 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "tag": "unicopia:blood" },
|
||||
{ "tag": "unicopia:energy" },
|
||||
{ "tag": "unicopia:rot" }
|
||||
{ "tag": "unicopia:death_elementals" },
|
||||
{ "tag": "unicopia:knowledge_elementals" },
|
||||
{ "tag": "unicopia:rotting_elementals" }
|
||||
],
|
||||
"result": {
|
||||
"item": "unicopia:corrupted_gem",
|
||||
"spell": "necromancy"
|
||||
}
|
||||
"result": { "item": "unicopia:corrupted_gem", "spell": "necromancy" }
|
||||
}
|
|
@ -2,8 +2,8 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "tag": "unicopia:energy" },
|
||||
{ "tag": "unicopia:life" },
|
||||
{ "tag": "unicopia:knowledge_elementals" },
|
||||
{ "tag": "unicopia:life_elementals" },
|
||||
{ "item": "unicopia:gem", "spell": "charge" }
|
||||
],
|
||||
"result": { "item": "unicopia:gem", "spell": "siphon" }
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "tag": "unicopia:sight" },
|
||||
{ "tag": "unicopia:sight_elementals" },
|
||||
{ "item": "minecraft:ghast_tear" },
|
||||
{ "tag": "unicopia:energy" },
|
||||
{ "tag": "unicopia:knowledge_elementals" },
|
||||
{ "item": "unicopia:gem", "spell": "fire" }
|
||||
],
|
||||
"result": { "item": "unicopia:gem", "spell": "portal" }
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "tag": "unicopia:fire" },
|
||||
{ "tag": "unicopia:shell" },
|
||||
{ "tag": "unicopia:fire_elementals" },
|
||||
{ "tag": "unicopia:shells" },
|
||||
{ "item": "unicopia:gem", "spell": "shield" },
|
||||
{ "tag": "unicopia:shell" }
|
||||
{ "tag": "unicopia:shells" }
|
||||
],
|
||||
"result": {
|
||||
"item": "unicopia:corrupted_gem",
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "id": "unicopia:shell" },
|
||||
{ "id": "unicopia:shell" },
|
||||
{ "id": "unicopia:shard" }
|
||||
{ "tag": "unicopia:shells" },
|
||||
{ "tag": "unicopia:shells" },
|
||||
{ "tag": "unicopia:shards" }
|
||||
],
|
||||
"result": { "item": "unicopia:gem", "spell": "shield" }
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "id": "unicopia:energy" },
|
||||
{ "id": "unicopia:life" },
|
||||
{ "id": "unicopia:dark" },
|
||||
{ "tag": "unicopia:knowledge_elementals" },
|
||||
{ "tag": "unicopia:life_elementals" },
|
||||
{ "tag": "unicopia:dark_elementals" },
|
||||
{ "item": "unicopia:gem", "spell": "siphon" }
|
||||
],
|
||||
"result": { "item": "unicopia:corrupted_gem", "spell": "siphon" }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "item": "minecraft:fire_charge" },
|
||||
{ "tag": "unicopia:blood" },
|
||||
{ "tag": "unicopia:death_elementals" },
|
||||
{ "item": "unicopia:gem", "spell": "fire" }
|
||||
],
|
||||
"result": { "item": "unicopia:corrupted_gem", "spell": "vortex" }
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"type": "unicopia:enchanting_spell",
|
||||
"input": { "item": "unicopia:gem" },
|
||||
"ingredients": [
|
||||
{ "tag": "unicopia:shell" },
|
||||
{ "tag": "unicopia:shells" },
|
||||
{ "item": "unicopia:gem", "spell": "shield" },
|
||||
{ "item": "unicopia:gem", "spell": "portal" }
|
||||
],
|
||||
|
|
|
@ -10,7 +10,22 @@
|
|||
{ "item": "minecraft:andesite" }
|
||||
],
|
||||
"C": [
|
||||
{ "item": "#minecraft:stained_hardened_clay" }
|
||||
{ "item": "minecraft:white_concrete" },
|
||||
{ "item": "minecraft:orange_concrete" },
|
||||
{ "item": "minecraft:magenta_concrete" },
|
||||
{ "item": "minecraft:light_blue_concrete" },
|
||||
{ "item": "minecraft:yellow_concrete" },
|
||||
{ "item": "minecraft:lime_concrete" },
|
||||
{ "item": "minecraft:pink_concrete" },
|
||||
{ "item": "minecraft:gray_concrete" },
|
||||
{ "item": "minecraft:light_gray_concrete" },
|
||||
{ "item": "minecraft:cyan_concrete" },
|
||||
{ "item": "minecraft:purple_concrete" },
|
||||
{ "item": "minecraft:blue_concrete" },
|
||||
{ "item": "minecraft:brown_concrete" },
|
||||
{ "item": "minecraft:green_concrete" },
|
||||
{ "item": "minecraft:red_concrete" },
|
||||
{ "item": "minecraft:black_concrete" }
|
||||
],
|
||||
"B": [
|
||||
{ "item": "minecraft:black_dye" }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"type": "unicopia:crafting_shaped",
|
||||
"pattern": [
|
||||
"AAA",
|
||||
"FTF",
|
||||
|
@ -14,15 +14,8 @@
|
|||
{ "item": "unicopia:cloudsdale_tomato" }
|
||||
],
|
||||
"F": [
|
||||
{ "item": "minecraft:red_flower", "data": 1 },
|
||||
{ "item": "minecraft:red_flower", "data": 2 },
|
||||
{ "item": "minecraft:red_flower", "data": 3 },
|
||||
{ "item": "minecraft:red_flower", "data": 4 },
|
||||
{ "item": "minecraft:red_flower", "data": 5 },
|
||||
{ "item": "minecraft:red_flower", "data": 6 },
|
||||
{ "item": "minecraft:red_flower", "data": 7 },
|
||||
{ "item": "minecraft:yellow_flower", "data": 0 }
|
||||
{ "tag": "unicopia:non_toxic" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:hay_burger" }
|
||||
"result": { "item": "unicopia:hay_burger", "toxicity": "safe" }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"type": "unicopia:crafting_shaped",
|
||||
"pattern": [
|
||||
"AAA",
|
||||
"FTF",
|
||||
|
@ -10,23 +10,15 @@
|
|||
{ "item": "unicopia:alfalfa_leaves" }
|
||||
],
|
||||
"T": [
|
||||
{ "item": "unicopia:tomato", "data": 0 },
|
||||
{ "item": "unicopia:tomato", "data": 1 },
|
||||
{ "item": "unicopia:cloudsdale_tomato", "data": 0 },
|
||||
{ "item": "unicopia:cloudsdale_tomato", "data": 1 }
|
||||
{ "item": "unicopia:tomato" },
|
||||
{ "item": "unicopia:rotten_tomato" },
|
||||
{ "item": "unicopia:cloudsdale_tomato" },
|
||||
{ "item": "unicopia:rotten_cloudsdale_tomato" }
|
||||
],
|
||||
"F": [
|
||||
{ "item": "minecraft:red_flower", "data": 0 },
|
||||
{ "item": "minecraft:red_flower", "data": 1 },
|
||||
{ "item": "minecraft:red_flower", "data": 2 },
|
||||
{ "item": "minecraft:red_flower", "data": 3 },
|
||||
{ "item": "minecraft:red_flower", "data": 4 },
|
||||
{ "item": "minecraft:red_flower", "data": 5 },
|
||||
{ "item": "minecraft:red_flower", "data": 6 },
|
||||
{ "item": "minecraft:red_flower", "data": 7 },
|
||||
{ "item": "minecraft:red_flower", "data": 8 },
|
||||
{ "item": "minecraft:yellow_flower", "data": 0 }
|
||||
{ "tag": "unicopia:non_toxic" },
|
||||
{ "tag": "unicopia:fairly_toxic" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:hay_burger", "data": 2, "count": 1 }
|
||||
"result": { "item": "unicopia:hay_burger", "toxicity": "fair", "count": 1 }
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
],
|
||||
"key": {
|
||||
"#": [
|
||||
{ "item": "minecraft:stained_white_glass_block" }
|
||||
{ "item": "minecraft:white_stained_glass" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:misted_glass_door", "data": 0, "count": 1 }
|
||||
"result": { "item": "unicopia:misted_glass_door", "count": 1 }
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
{ "item": "minecraft:bowl" }
|
||||
],
|
||||
"F": [
|
||||
{ "tag": "#unicopia:non_toxic" },
|
||||
{ "tag": "#unicopia:fairly_toxic" },
|
||||
{ "tag": "unicopia:non_toxic" },
|
||||
{ "tag": "unicopia:fairly_toxic" },
|
||||
{ "item": "unicopia:alfalfa_leaves" }
|
||||
]
|
||||
},
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
{ "item": "minecraft:golden_apple", "data": 0 },
|
||||
{ "item": "unicopia:zap_apple", "data": 0 },
|
||||
{ "item": "unicopia:corrupted_gem" },
|
||||
{ "tag": "#unicopia:non_toxic" },
|
||||
{ "tag": "#unicopia:fairly_toxic" },
|
||||
{ "tag": "#unicopia:severely_toxic" },
|
||||
{ "tag": "unicopia:non_toxic" },
|
||||
{ "tag": "unicopia:fairly_toxic" },
|
||||
{ "tag": "unicopia:severely_toxic" },
|
||||
{ "item": "unicopia:alfalfa_leaves" },
|
||||
{ "item": "unicopia:wheat_worms" }
|
||||
]
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{ "item": "minecraft:bowl" }
|
||||
],
|
||||
"F": [
|
||||
{ "tag": "#unicopia:non_toxic" },
|
||||
{ "tag": "unicopia:non_toxic" },
|
||||
{ "item": "unicopia:alfalfa_leaves" }
|
||||
]
|
||||
},
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
{ "item": "minecraft:bowl" }
|
||||
],
|
||||
"F": [
|
||||
{ "tag": "#unicopia:non_toxic" },
|
||||
{ "tag": "#unicopia:fairly_toxic" },
|
||||
{ "tag": "#unicopia:severely_toxic" },
|
||||
{ "tag": "unicopia:non_toxic" },
|
||||
{ "tag": "unicopia:fairly_toxic" },
|
||||
{ "tag": "unicopia:severely_toxic" },
|
||||
{ "item": "unicopia:alfalfa_leaves" },
|
||||
{ "item": "unicopia:wheat_worms" }
|
||||
]
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
],
|
||||
"key": {
|
||||
"#": [
|
||||
{ "item": "minecraft:slime" }
|
||||
{ "item": "minecraft:slime_block" }
|
||||
],
|
||||
"*": [
|
||||
{ "item": "unicopia:gem" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:cuccoon", "count": 1 }
|
||||
"result": { "item": "unicopia:slime_drop", "count": 1 }
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
],
|
||||
"key": {
|
||||
"#": [
|
||||
{ "item": "minecraft:slime" }
|
||||
{ "item": "minecraft:slime_block" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:slime_layer", "count": 6 }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "#unicopia:fresh_tomatoes" }
|
||||
{ "tag": "unicopia:fresh_tomatoes" }
|
||||
],
|
||||
"result": { "item": "unicopia:tomato_seeds", "count": 3 }
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:zap_apple", "data": 0 },
|
||||
{ "item": "minecraft:dye", "data": 2 }
|
||||
],
|
||||
"result": { "item": "unicopia:zap_apple", "count": 1, "data": 2 }
|
||||
"type": "unicopia:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:zap_apple" },
|
||||
{ "item": "minecraft:green_dye" }
|
||||
],
|
||||
"result": {
|
||||
"item": "unicopia:zap_apple",
|
||||
"appearance": "unicopia:green_apple"
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:zap_apple", "data": 0 },
|
||||
{ "item": "minecraft:dye", "data": 1 }
|
||||
],
|
||||
"result": { "item": "unicopia:zap_apple", "count": 1, "data": 1 }
|
||||
"type": "unicopia:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:zap_apple" },
|
||||
{ "item": "minecraft:red_dye" }
|
||||
],
|
||||
"result": {
|
||||
"item": "unicopia:zap_apple",
|
||||
"appearance": "minecraft:apple"
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:zap_apple", "data": 0 },
|
||||
{ "item": "minecraft:dye", "data": 15 }
|
||||
],
|
||||
"result": { "item": "unicopia:zap_apple", "count": 1, "data": 4 }
|
||||
"type": "unicopia:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:zap_apple" },
|
||||
{ "item": "minecraft:yellow_dye" }
|
||||
],
|
||||
"result": {
|
||||
"item": "unicopia:zap_apple",
|
||||
"appearance": "unicopia:sour_apple"
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:zap_apple", "data": 0 },
|
||||
{ "item": "minecraft:dye", "data": 14 }
|
||||
],
|
||||
"result": { "item": "unicopia:zap_apple", "count": 1, "data": 3 }
|
||||
"type": "unicopia:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:zap_apple" },
|
||||
{ "item": "minecraft:orange_dye" }
|
||||
],
|
||||
"result": {
|
||||
"item": "unicopia:zap_apple",
|
||||
"appearance": "unicopia:sweet_apple"
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:zap_apple", "data": 0 },
|
||||
{ "item": "minecraft:rotten_flesh" }
|
||||
],
|
||||
"result": { "item": "unicopia:zap_apple", "count": 1, "data": 5 }
|
||||
"type": "unicopia:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{ "item": "unicopia:zap_apple" },
|
||||
{ "item": "minecraft:rotten_flesh" }
|
||||
],
|
||||
"result": {
|
||||
"item": "unicopia:zap_apple",
|
||||
"appearance": "unicopia:cooked_zap_apple"
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"type": "unicopia:crafting_shaped",
|
||||
"pattern": [
|
||||
"***",
|
||||
" * ",
|
||||
|
@ -15,8 +15,6 @@
|
|||
},
|
||||
"result": {
|
||||
"item": "minecraft:potion",
|
||||
"data": 0,
|
||||
"count": 1,
|
||||
"nbt": { "Potion": "minecraft:water" }
|
||||
"potion": "minecraft:water"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,5 +13,5 @@
|
|||
{ "item": "unicopia:dew_drop" }
|
||||
]
|
||||
},
|
||||
"result": { "item": "minecraft:water_bucket", "count": 1 }
|
||||
"result": { "item": "minecraft:water_bucket" }
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"minecraft:cornflower",
|
||||
"minecraft:rose_bush",
|
||||
"minecraft:peony",
|
||||
"tall_grass"
|
||||
"minecraft:tall_grass"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"minecraft:fern",
|
||||
"minecraft:dead_bush",
|
||||
"minecraft:poppy",
|
||||
"minecraft:oxey_daisy",
|
||||
"minecraft:oxeye_daisy",
|
||||
"minecraft:large_fern"
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue