001 package net.minecraftforge.oredict; 002 003 import java.util.ArrayList; 004 import java.util.HashMap; 005 006 import net.minecraft.src.Block; 007 import net.minecraft.src.IRecipe; 008 import net.minecraft.src.InventoryCrafting; 009 import net.minecraft.src.Item; 010 import net.minecraft.src.ItemStack; 011 import net.minecraft.src.ShapedRecipes; 012 013 public class ShapedOreRecipe implements IRecipe 014 { 015 //Added in for future ease of change, but hard coded for now. 016 private static final int MAX_CRAFT_GRID_WIDTH = 3; 017 private static final int MAX_CRAFT_GRID_HEIGHT = 3; 018 019 private ItemStack output = null; 020 private Object[] input = null; 021 private int width = 0; 022 private int height = 0; 023 private boolean mirriored = true; 024 025 public ShapedOreRecipe(Block result, Object... recipe){ this(result, true, recipe);} 026 public ShapedOreRecipe(Item result, Object... recipe){ this(result, true, recipe); } 027 public ShapedOreRecipe(ItemStack result, Object... recipe){ this(result, true, recipe); } 028 public ShapedOreRecipe(Block result, boolean mirrior, Object... recipe){ this(new ItemStack(result), mirrior, recipe);} 029 public ShapedOreRecipe(Item result, boolean mirrior, Object... recipe){ this(new ItemStack(result), mirrior, recipe); } 030 031 public ShapedOreRecipe(ItemStack result, boolean mirrior, Object... recipe) 032 { 033 output = result.copy(); 034 mirriored = mirrior; 035 036 String shape = ""; 037 int idx = 0; 038 039 if (recipe[idx] instanceof String[]) 040 { 041 String[] parts = ((String[])recipe[idx++]); 042 043 for (String s : parts) 044 { 045 width = s.length(); 046 shape += s; 047 } 048 049 height = parts.length; 050 } 051 else 052 { 053 while (recipe[idx] instanceof String) 054 { 055 String s = (String)recipe[idx++]; 056 shape += s; 057 width = s.length(); 058 height++; 059 } 060 } 061 062 if (width * height != shape.length()) 063 { 064 String ret = "Invalid shaped ore recipe: "; 065 for (Object tmp : recipe) 066 { 067 ret += tmp + ", "; 068 } 069 ret += output; 070 throw new RuntimeException(ret); 071 } 072 073 HashMap<Character, Object> itemMap = new HashMap<Character, Object>(); 074 075 for (; idx < recipe.length; idx += 2) 076 { 077 Character chr = (Character)recipe[idx]; 078 Object in = recipe[idx + 1]; 079 Object val = null; 080 081 if (in instanceof ItemStack) 082 { 083 itemMap.put(chr, ((ItemStack)in).copy()); 084 } 085 else if (in instanceof Item) 086 { 087 itemMap.put(chr, new ItemStack((Item)in)); 088 } 089 else if (in instanceof Block) 090 { 091 itemMap.put(chr, new ItemStack((Block)in, 1, -1)); 092 } 093 else if (in instanceof String) 094 { 095 itemMap.put(chr, OreDictionary.getOres((String)in)); 096 } 097 else 098 { 099 String ret = "Invalid shaped ore recipe: "; 100 for (Object tmp : recipe) 101 { 102 ret += tmp + ", "; 103 } 104 ret += output; 105 throw new RuntimeException(ret); 106 } 107 } 108 109 input = new Object[width * height]; 110 int x = 0; 111 for (char chr : shape.toCharArray()) 112 { 113 input[x++] = itemMap.get(chr); 114 } 115 } 116 117 @Override 118 public ItemStack getCraftingResult(InventoryCrafting var1){ return output.copy(); } 119 120 @Override 121 public int getRecipeSize(){ return input.length; } 122 123 @Override 124 public ItemStack getRecipeOutput(){ return output; } 125 126 @Override 127 public boolean matches(InventoryCrafting inv) 128 { 129 for (int x = 0; x <= MAX_CRAFT_GRID_WIDTH - width; x++) 130 { 131 for (int y = 0; y <= MAX_CRAFT_GRID_HEIGHT - height; ++y) 132 { 133 if (checkMatch(inv, x, y, true)) 134 { 135 return true; 136 } 137 138 if (mirriored && checkMatch(inv, x, y, false)) 139 { 140 return true; 141 } 142 } 143 } 144 145 return false; 146 } 147 148 private boolean checkMatch(InventoryCrafting inv, int startX, int startY, boolean mirrior) 149 { 150 for (int x = 0; x < MAX_CRAFT_GRID_WIDTH; x++) 151 { 152 for (int y = 0; y < MAX_CRAFT_GRID_HEIGHT; y++) 153 { 154 int subX = x - startX; 155 int subY = y - startY; 156 Object target = null; 157 158 if (subX >= 0 && subY >= 0 && subX < width && subY < height) 159 { 160 if (mirrior) 161 { 162 target = input[width - subX - 1 + subY * width]; 163 } 164 else 165 { 166 target = input[subX + subY * width]; 167 } 168 } 169 170 ItemStack slot = inv.getStackInRowAndColumn(x, y); 171 172 if (target instanceof ItemStack) 173 { 174 if (!checkItemEquals((ItemStack)target, slot)) 175 { 176 return false; 177 } 178 } 179 else if (target instanceof ArrayList) 180 { 181 boolean matched = false; 182 183 for (ItemStack item : (ArrayList<ItemStack>)target) 184 { 185 matched = matched || checkItemEquals(item, slot); 186 } 187 188 if (!matched) 189 { 190 return false; 191 } 192 } 193 else if (target == null && slot != null) 194 { 195 return false; 196 } 197 } 198 } 199 200 return true; 201 } 202 203 private boolean checkItemEquals(ItemStack target, ItemStack input) 204 { 205 if (input == null && target != null || input != null && target == null) 206 { 207 return false; 208 } 209 return (target.itemID == input.itemID && (target.getItemDamage() == -1 || target.getItemDamage() == input.getItemDamage())); 210 } 211 212 public void setMirriored(boolean mirrior) 213 { 214 mirriored = mirrior; 215 } 216 }