From 7b6925171323dc8a4ca3cf2a51d63e216d98b391 Mon Sep 17 00:00:00 2001 From: WayofTime Date: Tue, 29 Dec 2015 18:30:36 -0500 Subject: [PATCH] Added shaped/shapeless orb recipes. --- .../java/WayofTime/bloodmagic/BloodMagic.java | 7 + .../api/recipe/ShapedBloodOrbRecipe.java | 245 ++++++++++++++++++ .../api/recipe/ShapelessBloodOrbRecipe.java | 157 +++++++++++ .../bloodmagic/registry/ModRecipes.java | 7 +- 4 files changed, 415 insertions(+), 1 deletion(-) create mode 100644 src/main/java/WayofTime/bloodmagic/api/recipe/ShapedBloodOrbRecipe.java create mode 100644 src/main/java/WayofTime/bloodmagic/api/recipe/ShapelessBloodOrbRecipe.java diff --git a/src/main/java/WayofTime/bloodmagic/BloodMagic.java b/src/main/java/WayofTime/bloodmagic/BloodMagic.java index df9ef93a..2f30852d 100644 --- a/src/main/java/WayofTime/bloodmagic/BloodMagic.java +++ b/src/main/java/WayofTime/bloodmagic/BloodMagic.java @@ -11,7 +11,11 @@ import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.oredict.RecipeSorter; +import net.minecraftforge.oredict.RecipeSorter.Category; import WayofTime.bloodmagic.api.Constants; +import WayofTime.bloodmagic.api.recipe.ShapedBloodOrbRecipe; +import WayofTime.bloodmagic.api.recipe.ShapelessBloodOrbRecipe; import WayofTime.bloodmagic.api.util.helper.LogHelper; import WayofTime.bloodmagic.network.BloodMagicPacketHandler; import WayofTime.bloodmagic.proxy.CommonProxy; @@ -51,6 +55,9 @@ public class BloodMagic { MinecraftForge.EVENT_BUS.register(new EventHandler()); + RecipeSorter.register("BloodMagic:shapedorb", ShapedBloodOrbRecipe.class, Category.SHAPED, "before:minecraft:shapeless"); + RecipeSorter.register("BloodMagic:shapelessorb", ShapelessBloodOrbRecipe.class, Category.SHAPELESS, "after:minecraft:shapeless"); + ModBlocks.init(); ModItems.init(); ModPotions.init(); diff --git a/src/main/java/WayofTime/bloodmagic/api/recipe/ShapedBloodOrbRecipe.java b/src/main/java/WayofTime/bloodmagic/api/recipe/ShapedBloodOrbRecipe.java new file mode 100644 index 00000000..54dccfc8 --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/api/recipe/ShapedBloodOrbRecipe.java @@ -0,0 +1,245 @@ +package WayofTime.bloodmagic.api.recipe; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import net.minecraft.block.Block; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.ShapedRecipes; +import net.minecraft.world.World; +import net.minecraftforge.oredict.OreDictionary; +import WayofTime.bloodmagic.api.orb.IBloodOrb; + +/** + * Shaped Blood Orb Recipe Handler by joshie * + */ +public class ShapedBloodOrbRecipe implements IRecipe { + private static final int MAX_CRAFT_GRID_WIDTH = 3; + private static final int MAX_CRAFT_GRID_HEIGHT = 3; + + private ItemStack output = null; + private Object[] input = null; + public int width = 0; + public int height = 0; + private boolean mirrored = true; + + public ShapedBloodOrbRecipe(Block result, Object... recipe) { + this(new ItemStack(result), recipe); + } + + public ShapedBloodOrbRecipe(Item result, Object... recipe) { + this(new ItemStack(result), recipe); + } + + public ShapedBloodOrbRecipe(ItemStack result, Object... recipe) { + output = result.copy(); + + String shape = ""; + int idx = 0; + + if (recipe[idx] instanceof Boolean) { + mirrored = (Boolean) recipe[idx]; + if (recipe[idx + 1] instanceof Object[]) { + recipe = (Object[]) recipe[idx + 1]; + } else { + idx = 1; + } + } + + if (recipe[idx] instanceof String[]) { + String[] parts = ((String[]) recipe[idx++]); + + for (String s : parts) { + width = s.length(); + shape += s; + } + + height = parts.length; + } else { + while (recipe[idx] instanceof String) { + String s = (String) recipe[idx++]; + shape += s; + width = s.length(); + height++; + } + } + + if (width * height != shape.length()) { + String ret = "Invalid shaped ore recipe: "; + for (Object tmp : recipe) { + ret += tmp + ", "; + } + ret += output; + throw new RuntimeException(ret); + } + + HashMap itemMap = new HashMap(); + + for (; idx < recipe.length; idx += 2) { + Character chr = (Character) recipe[idx]; + Object in = recipe[idx + 1]; + + if (in instanceof IBloodOrb || (in instanceof ItemStack && ((ItemStack) in).getItem() instanceof IBloodOrb)) { + // If the item is an instanceof IBloodOrb then save the level of the orb. + if (in instanceof ItemStack) + itemMap.put(chr, ((IBloodOrb) ((ItemStack) in).getItem()).getOrbLevel(((ItemStack) in).getItemDamage())); + else + itemMap.put(chr, ((IBloodOrb) in).getOrbLevel(((ItemStack) in).getItemDamage())); + } else if (in instanceof ItemStack) { + itemMap.put(chr, ((ItemStack) in).copy()); + } else if (in instanceof Item) { + itemMap.put(chr, new ItemStack((Item) in)); + } else if (in instanceof Block) { + itemMap.put(chr, new ItemStack((Block) in, 1, OreDictionary.WILDCARD_VALUE)); + } else if (in instanceof String) { + itemMap.put(chr, OreDictionary.getOres((String) in)); + } else { + String ret = "Invalid shaped orb recipe: "; + for (Object tmp : recipe) { + ret += tmp + ", "; + } + ret += output; + throw new RuntimeException(ret); + } + } + + input = new Object[width * height]; + int x = 0; + for (char chr : shape.toCharArray()) { + input[x++] = itemMap.get(chr); + } + } + + ShapedBloodOrbRecipe(ShapedRecipes recipe, Map replacements) { + output = recipe.getRecipeOutput(); + width = recipe.recipeWidth; + height = recipe.recipeHeight; + + input = new Object[recipe.recipeItems.length]; + + for (int i = 0; i < input.length; i++) { + ItemStack ingred = recipe.recipeItems[i]; + + if (ingred == null) + continue; + + input[i] = recipe.recipeItems[i]; + + for (Entry replace : replacements.entrySet()) { + if (OreDictionary.itemMatches(replace.getKey(), ingred, true)) { + input[i] = OreDictionary.getOres(replace.getValue()); + break; + } + } + } + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting var1) { + return output.copy(); + } + + @Override + public int getRecipeSize() { + return input.length; + } + + @Override + public ItemStack getRecipeOutput() { + return output; + } + + @Override + public boolean matches(InventoryCrafting inv, World world) { + for (int x = 0; x <= MAX_CRAFT_GRID_WIDTH - width; x++) { + for (int y = 0; y <= MAX_CRAFT_GRID_HEIGHT - height; ++y) { + if (checkMatch(inv, x, y, false)) { + return true; + } + + if (mirrored && checkMatch(inv, x, y, true)) { + return true; + } + } + } + + return false; + } + + @SuppressWarnings("unchecked") + private boolean checkMatch(InventoryCrafting inv, int startX, int startY, boolean mirror) { + for (int x = 0; x < MAX_CRAFT_GRID_WIDTH; x++) { + for (int y = 0; y < MAX_CRAFT_GRID_HEIGHT; y++) { + int subX = x - startX; + int subY = y - startY; + Object target = null; + + if (subX >= 0 && subY >= 0 && subX < width && subY < height) { + if (mirror) { + target = input[width - subX - 1 + subY * width]; + } else { + target = input[subX + subY * width]; + } + } + + ItemStack slot = inv.getStackInRowAndColumn(x, y); + // If target is integer, then we should be check the blood orb + // value of the item instead + if (target instanceof Integer) { + if (slot != null && slot.getItem() instanceof IBloodOrb) { + IBloodOrb orb = (IBloodOrb) slot.getItem(); + if (orb.getOrbLevel(slot.getItemDamage()) < (Integer) target) { + return false; + } + } else + return false; + } else if (target instanceof ItemStack) { + if (!OreDictionary.itemMatches((ItemStack) target, slot, false)) { + return false; + } + } else if (target instanceof ArrayList) { + boolean matched = false; + + Iterator itr = ((ArrayList) target).iterator(); + while (itr.hasNext() && !matched) { + matched = OreDictionary.itemMatches(itr.next(), slot, false); + } + + if (!matched) { + return false; + } + } else if (target == null && slot != null) { + return false; + } + } + } + + return true; + } + + public ShapedBloodOrbRecipe setMirrored(boolean mirror) { + mirrored = mirror; + return this; + } + + public Object[] getInput() { + return this.input; + } + + public ItemStack[] getRemainingItems(InventoryCrafting inv) { + ItemStack[] aitemstack = new ItemStack[inv.getSizeInventory()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inv.getStackInSlot(i); + aitemstack[i] = net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack); + } + + return aitemstack; + } +} \ No newline at end of file diff --git a/src/main/java/WayofTime/bloodmagic/api/recipe/ShapelessBloodOrbRecipe.java b/src/main/java/WayofTime/bloodmagic/api/recipe/ShapelessBloodOrbRecipe.java new file mode 100644 index 00000000..a94c78ff --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/api/recipe/ShapelessBloodOrbRecipe.java @@ -0,0 +1,157 @@ +package WayofTime.bloodmagic.api.recipe; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import net.minecraft.block.Block; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.ShapelessRecipes; +import net.minecraft.world.World; +import net.minecraftforge.oredict.OreDictionary; +import WayofTime.bloodmagic.api.orb.IBloodOrb; + +/** + * Shapeless Blood Orb Recipe Handler by joshie * + */ +public class ShapelessBloodOrbRecipe implements IRecipe { + private ItemStack output = null; + private ArrayList input = new ArrayList(); + + public ShapelessBloodOrbRecipe(Block result, Object... recipe) { + this(new ItemStack(result), recipe); + } + + public ShapelessBloodOrbRecipe(Item result, Object... recipe) { + this(new ItemStack(result), recipe); + } + + public ShapelessBloodOrbRecipe(ItemStack result, Object... recipe) { + output = result.copy(); + for (Object in : recipe) { + if (in instanceof ItemStack) { + if (((ItemStack) in).getItem() instanceof IBloodOrb) { + input.add(((IBloodOrb) ((ItemStack) in).getItem()).getOrbLevel(((ItemStack) in).getItemDamage())); + } else + input.add(((ItemStack) in).copy()); + } else if (in instanceof Item) { + input.add(new ItemStack((Item) in)); + } else if (in instanceof Block) { + input.add(new ItemStack((Block) in)); + } else if (in instanceof String) { + input.add(OreDictionary.getOres((String) in)); + } else { + String ret = "Invalid shapeless ore recipe: "; + for (Object tmp : recipe) { + ret += tmp + ", "; + } + ret += output; + throw new RuntimeException(ret); + } + } + } + + ShapelessBloodOrbRecipe(ShapelessRecipes recipe, Map replacements) { + output = recipe.getRecipeOutput(); + + for (ItemStack ingred : ((List) recipe.recipeItems)) { + Object finalObj = ingred; + for (Entry replace : replacements.entrySet()) { + if (OreDictionary.itemMatches(replace.getKey(), ingred, false)) { + finalObj = OreDictionary.getOres(replace.getValue()); + break; + } + } + input.add(finalObj); + } + } + + @Override + public int getRecipeSize() { + return input.size(); + } + + @Override + public ItemStack getRecipeOutput() { + return output; + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting var1) { + return output.copy(); + } + + @SuppressWarnings("unchecked") + @Override + public boolean matches(InventoryCrafting var1, World world) { + ArrayList required = new ArrayList(input); + + for (int x = 0; x < var1.getSizeInventory(); x++) { + ItemStack slot = var1.getStackInSlot(x); + + if (slot != null) { + boolean inRecipe = false; + Iterator req = required.iterator(); + + while (req.hasNext()) { + boolean match = false; + + Object next = req.next(); + + // If target is integer, then we should be check the blood + // orb value of the item instead + if (next instanceof Integer) { + if (slot != null && slot.getItem() instanceof IBloodOrb) { + IBloodOrb orb = (IBloodOrb) slot.getItem(); + if (orb.getOrbLevel(slot.getItemDamage()) < (Integer) next) { + return false; + } + } else + return false; + match = true; + } else if (next instanceof ItemStack) { + match = OreDictionary.itemMatches((ItemStack) next, slot, false); + } else if (next instanceof ArrayList) { + Iterator itr = ((ArrayList) next).iterator(); + while (itr.hasNext() && !match) { + match = OreDictionary.itemMatches(itr.next(), slot, false); + } + } + + if (match) { + inRecipe = true; + required.remove(next); + break; + } + } + + if (!inRecipe) { + return false; + } + } + } + + return required.isEmpty(); + } + + public ArrayList getInput() { + return this.input; + } + + @Override + public ItemStack[] getRemainingItems(InventoryCrafting inv) { + ItemStack[] aitemstack = new ItemStack[inv.getSizeInventory()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inv.getStackInSlot(i); + aitemstack[i] = net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack); + } + + return aitemstack; + } +} \ No newline at end of file diff --git a/src/main/java/WayofTime/bloodmagic/registry/ModRecipes.java b/src/main/java/WayofTime/bloodmagic/registry/ModRecipes.java index e65e0413..6ee81c21 100644 --- a/src/main/java/WayofTime/bloodmagic/registry/ModRecipes.java +++ b/src/main/java/WayofTime/bloodmagic/registry/ModRecipes.java @@ -8,6 +8,8 @@ import net.minecraftforge.fml.common.registry.GameRegistry; import WayofTime.bloodmagic.alchemyArray.CraftingArrayEffectBinding; import WayofTime.bloodmagic.api.altar.EnumAltarTier; import WayofTime.bloodmagic.api.compress.CompressionRegistry; +import WayofTime.bloodmagic.api.recipe.ShapedBloodOrbRecipe; +import WayofTime.bloodmagic.api.recipe.ShapelessBloodOrbRecipe; import WayofTime.bloodmagic.api.registry.AlchemyArrayRecipeRegistry; import WayofTime.bloodmagic.api.registry.AltarRecipeRegistry; import WayofTime.bloodmagic.api.registry.OrbRegistry; @@ -27,7 +29,10 @@ public class ModRecipes { } public static void addCraftingRecipes() { - GameRegistry.addShapedRecipe(ItemComponent.getStack(ItemComponent.REAGENT_BINDING), "xox", "o o", "xSx", 'S', new ItemStack(ModItems.slate, 1, 2), 'o', new ItemStack(Items.redstone), 'x', new ItemStack(Items.glowstone_dust)); + GameRegistry.addRecipe(new ShapedBloodOrbRecipe(ItemComponent.getStack(ItemComponent.REAGENT_BINDING), "xox", "oSo", "xox", 'S', OrbRegistry.getOrbStack(ModItems.orbMagician), 'o', new ItemStack(Items.redstone), 'x', new ItemStack(Items.glowstone_dust))); + //Added for testing + GameRegistry.addRecipe(new ShapelessBloodOrbRecipe(new ItemStack(Items.gold_ingot), new ItemStack(ModItems.slate, 1, 1), OrbRegistry.getOrbStack(ModItems.orbApprentice))); + GameRegistry.addRecipe(new ShapedBloodOrbRecipe(new ItemStack(Items.diamond), " ", " s ", " o ", 's', new ItemStack(ModItems.slate), 'o', OrbRegistry.getOrbStack(ModItems.orbWeak))); } public static void addAltarRecipes() {