diff --git a/src/main/java/com/minelittlepony/unicopia/enchanting/SpellIngredient.java b/src/main/java/com/minelittlepony/unicopia/enchanting/SpellIngredient.java new file mode 100644 index 00000000..e2524254 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/enchanting/SpellIngredient.java @@ -0,0 +1,115 @@ +package com.minelittlepony.unicopia.enchanting; + +import java.util.List; + +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.minelittlepony.unicopia.spell.SpellRegistry; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +public interface SpellIngredient { + + @Nullable + static SpellIngredient parse(JsonElement json) { + if (json.isJsonArray()) { + return Compound.parse(json.getAsJsonArray()); + } + + return Single.parse(json.getAsJsonObject()); + } + + boolean matches(ItemStack other, int materialMult); + + class Compound implements SpellIngredient { + private final List items; + + Compound(List items) { + this.items = items; + } + + @Override + public boolean matches(ItemStack other, int materialMult) { + return items.stream().anyMatch(item -> item.matches(other, materialMult)); + } + + @Nullable + static SpellIngredient parse(JsonArray json) { + if (json.size() > 0) { + List items = Lists.newArrayList(); + + for (JsonElement j : json) { + SpellIngredient item = SpellIngredient.parse(j); + + if (item != null) { + items.add(item); + } + } + + if (!items.isEmpty()) { + return new Compound(items); + } + } + + return null; + } + } + + class Single implements SpellIngredient { + + private final ItemStack contained; + private final boolean ignoreMeta; + + Single(ItemStack stack, boolean meta) { + contained = stack; + ignoreMeta = meta; + } + + @Override + public boolean matches(ItemStack other, int materialMult) { + if (other.isEmpty() != contained.isEmpty()) { + return false; + } else if (other.isEmpty()) { + return true; + } + + if (other.isEmpty()) { + return false; + } + + if (contained.getItem() == other.getItem() + && (ignoreMeta || other.getMetadata() == contained.getMetadata()) + && ItemStack.areItemStackTagsEqual(contained, other)) { + return other.getCount() >= (materialMult * contained.getCount()); + } + + return false; + } + + @Nullable + public static Single parse(JsonObject json) { + Item item = json.has("item") ? Item.getByNameOrId(json.get("item").getAsString()) : null; + + if (item != null) { + int metadata = Math.max(0, json.has("data") ? json.get("data").getAsInt() : 0); + int size = Math.max(1, json.has("count") ? json.get("count").getAsInt() : 1); + String spell = json.has("spell") ? json.get("spell").getAsString() : null; + + ItemStack stack = new ItemStack(item, size, metadata); + + if (spell != null) { + stack = SpellRegistry.instance().enchantStack(stack, spell); + } + + return new Single(stack, !json.has("data")); + } + + return null; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/enchanting/SpellRecipe.java b/src/main/java/com/minelittlepony/unicopia/enchanting/SpellRecipe.java index 7c44587e..8909bb5d 100644 --- a/src/main/java/com/minelittlepony/unicopia/enchanting/SpellRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/enchanting/SpellRecipe.java @@ -1,70 +1,63 @@ package com.minelittlepony.unicopia.enchanting; import java.util.ArrayList; +import java.util.List; import com.google.common.collect.Lists; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import com.minelittlepony.unicopia.init.UItems; import com.minelittlepony.unicopia.inventory.InventorySpellBook; import com.minelittlepony.unicopia.spell.SpellRegistry; import net.minecraft.inventory.InventoryCrafting; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.util.NonNullList; -import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.registries.IForgeRegistryEntry.Impl; public class SpellRecipe extends Impl implements IRecipe { - private final ResourceLocation spellitem; + private final SpellIngredient spellitem; private final String spellId; - private final NonNullList ingredients; + private final NonNullList ingredients; public static IRecipe deserialize(JsonObject json) { - NonNullList ingredients = NonNullList.create(); + NonNullList ingredients = NonNullList.create(); for (JsonElement i : json.get("ingredients").getAsJsonArray()) { - JsonObject o = i.getAsJsonObject(); + SpellIngredient ingredient = SpellIngredient.parse(i); - Item item = o.has("item") ? Item.getByNameOrId(o.get("item").getAsString()) : null; + if (ingredient != null) { + ingredients.add(ingredient); + } + } - if (item != null) { - int metadata = Math.max(0, o.has("data") ? o.get("data").getAsInt() : 0); - int size = Math.max(1, o.has("count") ? o.get("count").getAsInt() : 1); - String spell = o.has("spell") ? o.get("spell").getAsString() : null; - - ItemStack stack = new ItemStack(item, size, metadata); - - if (spell != null) { - stack = SpellRegistry.instance().enchantStack(stack, spell); - } - - ingredients.add(new RecipeItem(stack, !o.has("data"))); - } + if (ingredients.isEmpty()) { + throw new JsonParseException("Recipe cannot have 0 ingredients"); } json = json.get("result").getAsJsonObject(); String spellId = json.get("spell").getAsString(); - Item spellitem = json.has("item") ? Item.getByNameOrId(json.get("item").getAsString()) : null; - if (spellitem == null) { - spellitem = UItems.spell; + SpellIngredient result = SpellIngredient.parse(json.get("item")); + + if (result == null) { + throw new JsonParseException("Recipe cannot have no enchantable input"); } - return new SpellRecipe(spellitem, spellId, ingredients); + return new SpellRecipe(result, spellId, ingredients); } - public SpellRecipe(Item spellitem, String spellName, NonNullList ingredients) { - this.spellitem = spellitem.getRegistryName(); + public SpellRecipe(SpellIngredient spellitem, String spellName, NonNullList ingredients) { + this.spellitem = spellitem; this.spellId = spellName; this.ingredients = ingredients; } @@ -77,13 +70,13 @@ public class SpellRecipe extends Impl implements IRecipe { return false; } - if (!spellitem.equals(enchantedStack.getItem().getRegistryName())) { + if (!spellitem.matches(enchantedStack, enchantedStack.getCount())) { return false; } int materialMult = enchantedStack.getCount(); - ArrayList toMatch = Lists.newArrayList(ingredients); + ArrayList toMatch = Lists.newArrayList(ingredients); for (int i = 0; i < inv.getSizeInventory(); i++) { ItemStack stack = inv.getStackInSlot(i); @@ -97,7 +90,7 @@ public class SpellRecipe extends Impl implements IRecipe { return toMatch.isEmpty(); } - private boolean removeMatch(ArrayList toMatch, ItemStack stack, int materialMult) { + private boolean removeMatch(List toMatch, ItemStack stack, int materialMult) { return toMatch.stream() .filter(s -> s.matches(stack, materialMult)) .findFirst() @@ -123,6 +116,7 @@ public class SpellRecipe extends Impl implements IRecipe { @Override public NonNullList getRemainingItems(InventoryCrafting inv) { NonNullList remainers = NonNullList.withSize(inv.getSizeInventory(), ItemStack.EMPTY); + for (int i = 0; i < remainers.size(); i++) { ItemStack stack = inv.getStackInSlot(i); @@ -130,37 +124,9 @@ public class SpellRecipe extends Impl implements IRecipe { remainers.set(i, new ItemStack(stack.getItem().getContainerItem())); } } + return remainers; } - private static class RecipeItem { - private final ItemStack contained; - private final boolean ignoreMeta; - - RecipeItem(ItemStack stack, boolean meta) { - contained = stack; - ignoreMeta = meta; - } - - boolean matches(ItemStack other, int materialMult) { - if (other.isEmpty() != contained.isEmpty()) { - return false; - } else if (other.isEmpty()) { - return true; - } - - if (other.isEmpty()) { - return false; - } - - if (contained.getItem() == other.getItem() - && (ignoreMeta || other.getMetadata() == contained.getMetadata()) - && ItemStack.areItemStackTagsEqual(contained, other)) { - return other.getCount() >= (materialMult * contained.getCount()); - } - - return false; - } - } } diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/charge.json b/src/main/resources/assets/unicopia/enchanting/recipes/charge.json index 43fd5389..d51350c2 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/charge.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/charge.json @@ -6,7 +6,7 @@ { "item": "minecraft:redstone" } ], "result": { - "item": "unicopia:gem", + "item": { "item": "unicopia:gem" }, "spell": "charge" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/drake.json b/src/main/resources/assets/unicopia/enchanting/recipes/drake.json index 9f1633c2..67f2e0e0 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/drake.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/drake.json @@ -6,7 +6,7 @@ { "item": "minecraft:red_flower", "data": 0 } ], "result": { - "item": "unicopia:gem", + "item": { "item": "unicopia:gem" }, "spell": "drake" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/fire.json b/src/main/resources/assets/unicopia/enchanting/recipes/fire.json index 45847d4f..6b60b6ba 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/fire.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/fire.json @@ -6,7 +6,7 @@ { "item": "minecraft:lava_bucket" } ], "result": { - "item": "unicopia:gem", + "item": { "item": "unicopia:gem" }, "spell": "fire" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/ice.json b/src/main/resources/assets/unicopia/enchanting/recipes/ice.json index b13642ec..90b6b775 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/ice.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/ice.json @@ -6,7 +6,7 @@ { "item": "minecraft:water_bucket" } ], "result": { - "item": "unicopia:gem", + "item": { "item": "unicopia:gem" }, "spell": "ice" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/inferno.json b/src/main/resources/assets/unicopia/enchanting/recipes/inferno.json index 5543efbe..76787208 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/inferno.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/inferno.json @@ -6,7 +6,7 @@ { "item": "minecraft:lava_bucket" } ], "result": { - "item": "unicopia:corrupted_gem", + "item": { "item": "unicopia:corrupted_gem" }, "spell": "inferno" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/light.json b/src/main/resources/assets/unicopia/enchanting/recipes/light.json index 48ad8a26..1ad4859c 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/light.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/light.json @@ -6,7 +6,7 @@ { "item": "unicopia:apple_green" } ], "result": { - "item": "unicopia:gem", + "item": { "item": "unicopia:gem" }, "spell": "light" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/necromancy.json b/src/main/resources/assets/unicopia/enchanting/recipes/necromancy.json index 81896500..5b0780e7 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/necromancy.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/necromancy.json @@ -6,7 +6,7 @@ { "item": "minecraft:rotten_flesh" } ], "result": { - "item": "unicopia:corrupted_gem", + "item": { "item": "unicopia:corrupted_gem" }, "spell": "necromancy" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/portal.json b/src/main/resources/assets/unicopia/enchanting/recipes/portal.json index fad6e838..4def4794 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/portal.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/portal.json @@ -7,7 +7,7 @@ { "item": "unicopia:gem", "spell": "fire" } ], "result": { - "item": "unicopia:gem", + "item": { "item": "unicopia:gem" }, "spell": "portal" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/repulsion.json b/src/main/resources/assets/unicopia/enchanting/recipes/repulsion.json index 981cedaf..498adc45 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/repulsion.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/repulsion.json @@ -7,7 +7,7 @@ { "item": "minecraft:egg" } ], "result": { - "item": "unicopia:corrupted_gem", + "item": { "item": "unicopia:corrupted_gem" }, "spell": "shield" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/reveal.json b/src/main/resources/assets/unicopia/enchanting/recipes/reveal.json index ba61485e..52bd3646 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/reveal.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/reveal.json @@ -6,7 +6,7 @@ { "item": "unicopia:gem", "spell": "light" } ], "result": { - "item": "unicopia:gem", + "item": { "item": "unicopia:gem" }, "spell": "reveal" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/shield.json b/src/main/resources/assets/unicopia/enchanting/recipes/shield.json index 205afed1..5d922157 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/shield.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/shield.json @@ -6,7 +6,7 @@ { "item": "minecraft:blaze_powder" } ], "result": { - "item": "unicopia:gem", + "item": { "item": "unicopia:gem" }, "spell": "shield" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/suffering.json b/src/main/resources/assets/unicopia/enchanting/recipes/suffering.json index 91a9823e..d5c272cd 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/suffering.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/suffering.json @@ -5,7 +5,7 @@ { "item": "unicopia:gem", "spell": "fire" } ], "result": { - "item": "unicopia:corrupted_gem", + "item": { "item": "unicopia:corrupted_gem" }, "spell": "vortex" } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/enchanting/recipes/vortex.json b/src/main/resources/assets/unicopia/enchanting/recipes/vortex.json index 50eac4ae..eb1b6727 100644 --- a/src/main/resources/assets/unicopia/enchanting/recipes/vortex.json +++ b/src/main/resources/assets/unicopia/enchanting/recipes/vortex.json @@ -6,7 +6,7 @@ { "item": "unicopia:gem", "spell": "portal" } ], "result": { - "item": "unicopia:gem", + "item": { "item": "unicopia:gem" }, "spell": "vortex" } } \ No newline at end of file