    001package net.minecraftforge.oredict;
    002
    003import java.util.ArrayList;
    004import java.util.Iterator;
    005import java.util.Map;
    006import java.util.Map.Entry;
    007import java.util.List;
    008
    009import net.minecraft.block.Block;
    010import net.minecraft.item.crafting.CraftingManager;
    011import net.minecraft.item.crafting.IRecipe;
    012import net.minecraft.inventory.InventoryCrafting;
    013import net.minecraft.item.Item;
    014import net.minecraft.item.ItemStack;
    015import net.minecraft.item.crafting.ShapelessRecipes;
    016import net.minecraft.world.World;
    017
    018public class ShapelessOreRecipe implements IRecipe
    019{
    020    private ItemStack output = null;
    021    private ArrayList input = new ArrayList();
    022
    023    public ShapelessOreRecipe(Block result, Object... recipe){ this(new ItemStack(result), recipe); }
    024    public ShapelessOreRecipe(Item  result, Object... recipe){ this(new ItemStack(result), recipe); }
    025
    026    public ShapelessOreRecipe(ItemStack result, Object... recipe)
    027    {
    028        output = result.copy();
    029        for (Object in : recipe)
    030        {
    031            if (in instanceof ItemStack)
    032            {
    033                input.add(((ItemStack)in).copy());
    034            }
    035            else if (in instanceof Item)
    036            {
    037                input.add(new ItemStack((Item)in));
    038            }
    039            else if (in instanceof Block)
    040            {
    041                input.add(new ItemStack((Block)in));
    042            }
    043            else if (in instanceof String)
    044            {
    045                input.add(OreDictionary.getOres((String)in));
    046            }
    047            else
    048            {
    049                String ret = "Invalid shapeless ore recipe: ";
    050                for (Object tmp :  recipe)
    051                {
    052                    ret += tmp + ", ";
    053                }
    054                ret += output;
    055                throw new RuntimeException(ret);
    056            }
    057        }
    058    }
    059
    060    ShapelessOreRecipe(ShapelessRecipes recipe, Map<ItemStack, String> replacements)
    061    {
    062        output = recipe.getRecipeOutput();
    063
    064        for(ItemStack ingred : ((List<ItemStack>)recipe.recipeItems))
    065        {
    066            Object finalObj = ingred;
    067            for(Entry<ItemStack, String> replace : replacements.entrySet())
    068            {
    069                if(OreDictionary.itemMatches(replace.getKey(), ingred, false))
    070                {
    071                    finalObj = OreDictionary.getOres(replace.getValue());
    072                    break;
    073                }
    074            }
    075            input.add(finalObj);
    076        }
    077    }
    078
    079    @Override
    080    public int getRecipeSize(){ return input.size(); }
    081
    082    @Override
    083    public ItemStack getRecipeOutput(){ return output; }
    084
    085    @Override
    086    public ItemStack getCraftingResult(InventoryCrafting var1){ return output.copy(); }
    087
    088    @Override
    089    public boolean matches(InventoryCrafting var1, World world)
    090    {
    091        ArrayList required = new ArrayList(input);
    092
    093        for (int x = 0; x < var1.getSizeInventory(); x++)
    094        {
    095            ItemStack slot = var1.getStackInSlot(x);
    096
    097            if (slot != null)
    098            {
    099                boolean inRecipe = false;
    100                Iterator req = required.iterator();
    101
    102                while (req.hasNext())
    103                {
    104                    boolean match = false;
    105
    106                    Object next = req.next();
    107
    108                    if (next instanceof ItemStack)
    109                    {
    110                        match = checkItemEquals((ItemStack)next, slot);
    111                    }
    112                    else if (next instanceof ArrayList)
    113                    {
    114                        for (ItemStack item : (ArrayList<ItemStack>)next)
    115                        {
    116                            match = match || checkItemEquals(item, slot);
    117                        }
    118                    }
    119
    120                    if (match)
    121                    {
    122                        inRecipe = true;
    123                        required.remove(next);
    124                        break;
    125                    }
    126                }
    127
    128                if (!inRecipe)
    129                {
    130                    return false;
    131                }
    132            }
    133        }
    134
    135        return required.isEmpty();
    136    }
    137
    138    private boolean checkItemEquals(ItemStack target, ItemStack input)
    139    {
    140        return (target.itemID == input.itemID && (target.getItemDamage() == -1 || target.getItemDamage() == input.getItemDamage()));
    141    }
    142
    143    /**
    144     * Returns the input for this recipe, any mod accessing this value should never
    145     * manipulate the values in this array as it will effect the recipe itself.
    146     * @return The recipes input vales.
    147     */
    148    public ArrayList getInput()
    149    {
    150        return this.input;
    151    }
    152}