001package net.minecraft.item.crafting;
002
003import java.util.ArrayList;
004import java.util.Collections;
005import java.util.HashMap;
006import java.util.List;
007import net.minecraft.block.Block;
008import net.minecraft.inventory.InventoryCrafting;
009import net.minecraft.item.Item;
010import net.minecraft.item.ItemStack;
011import net.minecraft.world.World;
012
013public class CraftingManager
014{
015    /** The static instance of this class */
016    private static final CraftingManager instance = new CraftingManager();
017
018    /** A list of all the recipes added */
019    private List recipes = new ArrayList();
020
021    /**
022     * Returns the static instance of this class
023     */
024    public static final CraftingManager getInstance()
025    {
026        return instance;
027    }
028
029    private CraftingManager()
030    {
031        (new RecipesTools()).addRecipes(this);
032        (new RecipesWeapons()).addRecipes(this);
033        (new RecipesIngots()).addRecipes(this);
034        (new RecipesFood()).addRecipes(this);
035        (new RecipesCrafting()).addRecipes(this);
036        (new RecipesArmor()).addRecipes(this);
037        (new RecipesDyes()).addRecipes(this);
038        this.recipes.add(new RecipesArmorDyes());
039        this.recipes.add(new RecipesMapCloning());
040        this.recipes.add(new RecipesMapExtending());
041        this.recipes.add(new RecipeFireworks());
042        this.addRecipe(new ItemStack(Item.paper, 3), new Object[] {"###", '#', Item.reed});
043        this.addShapelessRecipe(new ItemStack(Item.book, 1), new Object[] {Item.paper, Item.paper, Item.paper, Item.leather});
044        this.addShapelessRecipe(new ItemStack(Item.writableBook, 1), new Object[] {Item.book, new ItemStack(Item.dyePowder, 1, 0), Item.feather});
045        this.addRecipe(new ItemStack(Block.fence, 2), new Object[] {"###", "###", '#', Item.stick});
046        this.addRecipe(new ItemStack(Block.cobblestoneWall, 6, 0), new Object[] {"###", "###", '#', Block.cobblestone});
047        this.addRecipe(new ItemStack(Block.cobblestoneWall, 6, 1), new Object[] {"###", "###", '#', Block.cobblestoneMossy});
048        this.addRecipe(new ItemStack(Block.netherFence, 6), new Object[] {"###", "###", '#', Block.netherBrick});
049        this.addRecipe(new ItemStack(Block.fenceGate, 1), new Object[] {"#W#", "#W#", '#', Item.stick, 'W', Block.planks});
050        this.addRecipe(new ItemStack(Block.jukebox, 1), new Object[] {"###", "#X#", "###", '#', Block.planks, 'X', Item.diamond});
051        this.addRecipe(new ItemStack(Block.music, 1), new Object[] {"###", "#X#", "###", '#', Block.planks, 'X', Item.redstone});
052        this.addRecipe(new ItemStack(Block.bookShelf, 1), new Object[] {"###", "XXX", "###", '#', Block.planks, 'X', Item.book});
053        this.addRecipe(new ItemStack(Block.blockSnow, 1), new Object[] {"##", "##", '#', Item.snowball});
054        this.addRecipe(new ItemStack(Block.blockClay, 1), new Object[] {"##", "##", '#', Item.clay});
055        this.addRecipe(new ItemStack(Block.brick, 1), new Object[] {"##", "##", '#', Item.brick});
056        this.addRecipe(new ItemStack(Block.glowStone, 1), new Object[] {"##", "##", '#', Item.lightStoneDust});
057        this.addRecipe(new ItemStack(Block.cloth, 1), new Object[] {"##", "##", '#', Item.silk});
058        this.addRecipe(new ItemStack(Block.tnt, 1), new Object[] {"X#X", "#X#", "X#X", 'X', Item.gunpowder, '#', Block.sand});
059        this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 3), new Object[] {"###", '#', Block.cobblestone});
060        this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 0), new Object[] {"###", '#', Block.stone});
061        this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 1), new Object[] {"###", '#', Block.sandStone});
062        this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 4), new Object[] {"###", '#', Block.brick});
063        this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 5), new Object[] {"###", '#', Block.stoneBrick});
064        this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 6), new Object[] {"###", '#', Block.netherBrick});
065        this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 0), new Object[] {"###", '#', new ItemStack(Block.planks, 1, 0)});
066        this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 2), new Object[] {"###", '#', new ItemStack(Block.planks, 1, 2)});
067        this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 1), new Object[] {"###", '#', new ItemStack(Block.planks, 1, 1)});
068        this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 3), new Object[] {"###", '#', new ItemStack(Block.planks, 1, 3)});
069        this.addRecipe(new ItemStack(Block.ladder, 3), new Object[] {"# #", "###", "# #", '#', Item.stick});
070        this.addRecipe(new ItemStack(Item.doorWood, 1), new Object[] {"##", "##", "##", '#', Block.planks});
071        this.addRecipe(new ItemStack(Block.trapdoor, 2), new Object[] {"###", "###", '#', Block.planks});
072        this.addRecipe(new ItemStack(Item.doorSteel, 1), new Object[] {"##", "##", "##", '#', Item.ingotIron});
073        this.addRecipe(new ItemStack(Item.sign, 3), new Object[] {"###", "###", " X ", '#', Block.planks, 'X', Item.stick});
074        this.addRecipe(new ItemStack(Item.cake, 1), new Object[] {"AAA", "BEB", "CCC", 'A', Item.bucketMilk, 'B', Item.sugar, 'C', Item.wheat, 'E', Item.egg});
075        this.addRecipe(new ItemStack(Item.sugar, 1), new Object[] {"#", '#', Item.reed});
076        this.addRecipe(new ItemStack(Block.planks, 4, 0), new Object[] {"#", '#', new ItemStack(Block.wood, 1, 0)});
077        this.addRecipe(new ItemStack(Block.planks, 4, 1), new Object[] {"#", '#', new ItemStack(Block.wood, 1, 1)});
078        this.addRecipe(new ItemStack(Block.planks, 4, 2), new Object[] {"#", '#', new ItemStack(Block.wood, 1, 2)});
079        this.addRecipe(new ItemStack(Block.planks, 4, 3), new Object[] {"#", '#', new ItemStack(Block.wood, 1, 3)});
080        this.addRecipe(new ItemStack(Item.stick, 4), new Object[] {"#", "#", '#', Block.planks});
081        this.addRecipe(new ItemStack(Block.torchWood, 4), new Object[] {"X", "#", 'X', Item.coal, '#', Item.stick});
082        this.addRecipe(new ItemStack(Block.torchWood, 4), new Object[] {"X", "#", 'X', new ItemStack(Item.coal, 1, 1), '#', Item.stick});
083        this.addRecipe(new ItemStack(Item.bowlEmpty, 4), new Object[] {"# #", " # ", '#', Block.planks});
084        this.addRecipe(new ItemStack(Item.glassBottle, 3), new Object[] {"# #", " # ", '#', Block.glass});
085        this.addRecipe(new ItemStack(Block.rail, 16), new Object[] {"X X", "X#X", "X X", 'X', Item.ingotIron, '#', Item.stick});
086        this.addRecipe(new ItemStack(Block.railPowered, 6), new Object[] {"X X", "X#X", "XRX", 'X', Item.ingotGold, 'R', Item.redstone, '#', Item.stick});
087        this.addRecipe(new ItemStack(Block.railDetector, 6), new Object[] {"X X", "X#X", "XRX", 'X', Item.ingotIron, 'R', Item.redstone, '#', Block.pressurePlateStone});
088        this.addRecipe(new ItemStack(Item.minecartEmpty, 1), new Object[] {"# #", "###", '#', Item.ingotIron});
089        this.addRecipe(new ItemStack(Item.cauldron, 1), new Object[] {"# #", "# #", "###", '#', Item.ingotIron});
090        this.addRecipe(new ItemStack(Item.brewingStand, 1), new Object[] {" B ", "###", '#', Block.cobblestone, 'B', Item.blazeRod});
091        this.addRecipe(new ItemStack(Block.pumpkinLantern, 1), new Object[] {"A", "B", 'A', Block.pumpkin, 'B', Block.torchWood});
092        this.addRecipe(new ItemStack(Item.minecartCrate, 1), new Object[] {"A", "B", 'A', Block.chest, 'B', Item.minecartEmpty});
093        this.addRecipe(new ItemStack(Item.minecartPowered, 1), new Object[] {"A", "B", 'A', Block.stoneOvenIdle, 'B', Item.minecartEmpty});
094        this.addRecipe(new ItemStack(Item.boat, 1), new Object[] {"# #", "###", '#', Block.planks});
095        this.addRecipe(new ItemStack(Item.bucketEmpty, 1), new Object[] {"# #", " # ", '#', Item.ingotIron});
096        this.addRecipe(new ItemStack(Item.flowerPot, 1), new Object[] {"# #", " # ", '#', Item.brick});
097        this.addRecipe(new ItemStack(Item.flintAndSteel, 1), new Object[] {"A ", " B", 'A', Item.ingotIron, 'B', Item.flint});
098        this.addRecipe(new ItemStack(Item.bread, 1), new Object[] {"###", '#', Item.wheat});
099        this.addRecipe(new ItemStack(Block.stairCompactPlanks, 4), new Object[] {"#  ", "## ", "###", '#', new ItemStack(Block.planks, 1, 0)});
100        this.addRecipe(new ItemStack(Block.stairsWoodBirch, 4), new Object[] {"#  ", "## ", "###", '#', new ItemStack(Block.planks, 1, 2)});
101        this.addRecipe(new ItemStack(Block.stairsWoodSpruce, 4), new Object[] {"#  ", "## ", "###", '#', new ItemStack(Block.planks, 1, 1)});
102        this.addRecipe(new ItemStack(Block.stairsWoodJungle, 4), new Object[] {"#  ", "## ", "###", '#', new ItemStack(Block.planks, 1, 3)});
103        this.addRecipe(new ItemStack(Item.fishingRod, 1), new Object[] {"  #", " #X", "# X", '#', Item.stick, 'X', Item.silk});
104        this.addRecipe(new ItemStack(Item.carrotOnAStick, 1), new Object[] {"# ", " X", '#', Item.fishingRod, 'X', Item.carrot}).func_92100_c();
105        this.addRecipe(new ItemStack(Block.stairCompactCobblestone, 4), new Object[] {"#  ", "## ", "###", '#', Block.cobblestone});
106        this.addRecipe(new ItemStack(Block.stairsBrick, 4), new Object[] {"#  ", "## ", "###", '#', Block.brick});
107        this.addRecipe(new ItemStack(Block.stairsStoneBrickSmooth, 4), new Object[] {"#  ", "## ", "###", '#', Block.stoneBrick});
108        this.addRecipe(new ItemStack(Block.stairsNetherBrick, 4), new Object[] {"#  ", "## ", "###", '#', Block.netherBrick});
109        this.addRecipe(new ItemStack(Block.stairsSandStone, 4), new Object[] {"#  ", "## ", "###", '#', Block.sandStone});
110        this.addRecipe(new ItemStack(Item.painting, 1), new Object[] {"###", "#X#", "###", '#', Item.stick, 'X', Block.cloth});
111        this.addRecipe(new ItemStack(Item.itemFrame, 1), new Object[] {"###", "#X#", "###", '#', Item.stick, 'X', Item.leather});
112        this.addRecipe(new ItemStack(Item.appleGold, 1, 0), new Object[] {"###", "#X#", "###", '#', Item.goldNugget, 'X', Item.appleRed});
113        this.addRecipe(new ItemStack(Item.appleGold, 1, 1), new Object[] {"###", "#X#", "###", '#', Block.blockGold, 'X', Item.appleRed});
114        this.addRecipe(new ItemStack(Item.goldenCarrot, 1, 0), new Object[] {"###", "#X#", "###", '#', Item.goldNugget, 'X', Item.carrot});
115        this.addRecipe(new ItemStack(Block.lever, 1), new Object[] {"X", "#", '#', Block.cobblestone, 'X', Item.stick});
116        this.addRecipe(new ItemStack(Block.tripWireSource, 2), new Object[] {"I", "S", "#", '#', Block.planks, 'S', Item.stick, 'I', Item.ingotIron});
117        this.addRecipe(new ItemStack(Block.torchRedstoneActive, 1), new Object[] {"X", "#", '#', Item.stick, 'X', Item.redstone});
118        this.addRecipe(new ItemStack(Item.redstoneRepeater, 1), new Object[] {"#X#", "III", '#', Block.torchRedstoneActive, 'X', Item.redstone, 'I', Block.stone});
119        this.addRecipe(new ItemStack(Item.pocketSundial, 1), new Object[] {" # ", "#X#", " # ", '#', Item.ingotGold, 'X', Item.redstone});
120        this.addRecipe(new ItemStack(Item.compass, 1), new Object[] {" # ", "#X#", " # ", '#', Item.ingotIron, 'X', Item.redstone});
121        this.addRecipe(new ItemStack(Item.emptyMap, 1), new Object[] {"###", "#X#", "###", '#', Item.paper, 'X', Item.compass});
122        this.addRecipe(new ItemStack(Block.stoneButton, 1), new Object[] {"#", '#', Block.stone});
123        this.addRecipe(new ItemStack(Block.woodenButton, 1), new Object[] {"#", '#', Block.planks});
124        this.addRecipe(new ItemStack(Block.pressurePlateStone, 1), new Object[] {"##", '#', Block.stone});
125        this.addRecipe(new ItemStack(Block.pressurePlatePlanks, 1), new Object[] {"##", '#', Block.planks});
126        this.addRecipe(new ItemStack(Block.dispenser, 1), new Object[] {"###", "#X#", "#R#", '#', Block.cobblestone, 'X', Item.bow, 'R', Item.redstone});
127        this.addRecipe(new ItemStack(Block.pistonBase, 1), new Object[] {"TTT", "#X#", "#R#", '#', Block.cobblestone, 'X', Item.ingotIron, 'R', Item.redstone, 'T', Block.planks});
128        this.addRecipe(new ItemStack(Block.pistonStickyBase, 1), new Object[] {"S", "P", 'S', Item.slimeBall, 'P', Block.pistonBase});
129        this.addRecipe(new ItemStack(Item.bed, 1), new Object[] {"###", "XXX", '#', Block.cloth, 'X', Block.planks});
130        this.addRecipe(new ItemStack(Block.enchantmentTable, 1), new Object[] {" B ", "D#D", "###", '#', Block.obsidian, 'B', Item.book, 'D', Item.diamond});
131        this.addRecipe(new ItemStack(Block.anvil, 1), new Object[] {"III", " i ", "iii", 'I', Block.blockSteel, 'i', Item.ingotIron});
132        this.addShapelessRecipe(new ItemStack(Item.eyeOfEnder, 1), new Object[] {Item.enderPearl, Item.blazePowder});
133        this.addShapelessRecipe(new ItemStack(Item.fireballCharge, 3), new Object[] {Item.gunpowder, Item.blazePowder, Item.coal});
134        this.addShapelessRecipe(new ItemStack(Item.fireballCharge, 3), new Object[] {Item.gunpowder, Item.blazePowder, new ItemStack(Item.coal, 1, 1)});
135        Collections.sort(this.recipes, new RecipeSorter(this));
136        System.out.println(this.recipes.size() + " recipes");
137    }
138
139    public ShapedRecipes addRecipe(ItemStack par1ItemStack, Object ... par2ArrayOfObj)
140    {
141        String var3 = "";
142        int var4 = 0;
143        int var5 = 0;
144        int var6 = 0;
145
146        if (par2ArrayOfObj[var4] instanceof String[])
147        {
148            String[] var7 = (String[])((String[])par2ArrayOfObj[var4++]);
149
150            for (int var8 = 0; var8 < var7.length; ++var8)
151            {
152                String var9 = var7[var8];
153                ++var6;
154                var5 = var9.length();
155                var3 = var3 + var9;
156            }
157        }
158        else
159        {
160            while (par2ArrayOfObj[var4] instanceof String)
161            {
162                String var11 = (String)par2ArrayOfObj[var4++];
163                ++var6;
164                var5 = var11.length();
165                var3 = var3 + var11;
166            }
167        }
168
169        HashMap var12;
170
171        for (var12 = new HashMap(); var4 < par2ArrayOfObj.length; var4 += 2)
172        {
173            Character var13 = (Character)par2ArrayOfObj[var4];
174            ItemStack var14 = null;
175
176            if (par2ArrayOfObj[var4 + 1] instanceof Item)
177            {
178                var14 = new ItemStack((Item)par2ArrayOfObj[var4 + 1]);
179            }
180            else if (par2ArrayOfObj[var4 + 1] instanceof Block)
181            {
182                var14 = new ItemStack((Block)par2ArrayOfObj[var4 + 1], 1, -1);
183            }
184            else if (par2ArrayOfObj[var4 + 1] instanceof ItemStack)
185            {
186                var14 = (ItemStack)par2ArrayOfObj[var4 + 1];
187            }
188
189            var12.put(var13, var14);
190        }
191
192        ItemStack[] var15 = new ItemStack[var5 * var6];
193
194        for (int var16 = 0; var16 < var5 * var6; ++var16)
195        {
196            char var10 = var3.charAt(var16);
197
198            if (var12.containsKey(Character.valueOf(var10)))
199            {
200                var15[var16] = ((ItemStack)var12.get(Character.valueOf(var10))).copy();
201            }
202            else
203            {
204                var15[var16] = null;
205            }
206        }
207
208        ShapedRecipes var17 = new ShapedRecipes(var5, var6, var15, par1ItemStack);
209        this.recipes.add(var17);
210        return var17;
211    }
212
213    public void addShapelessRecipe(ItemStack par1ItemStack, Object ... par2ArrayOfObj)
214    {
215        ArrayList var3 = new ArrayList();
216        Object[] var4 = par2ArrayOfObj;
217        int var5 = par2ArrayOfObj.length;
218
219        for (int var6 = 0; var6 < var5; ++var6)
220        {
221            Object var7 = var4[var6];
222
223            if (var7 instanceof ItemStack)
224            {
225                var3.add(((ItemStack)var7).copy());
226            }
227            else if (var7 instanceof Item)
228            {
229                var3.add(new ItemStack((Item)var7));
230            }
231            else
232            {
233                if (!(var7 instanceof Block))
234                {
235                    throw new RuntimeException("Invalid shapeless recipy!");
236                }
237
238                var3.add(new ItemStack((Block)var7));
239            }
240        }
241
242        this.recipes.add(new ShapelessRecipes(par1ItemStack, var3));
243    }
244
245    public ItemStack findMatchingRecipe(InventoryCrafting par1InventoryCrafting, World par2World)
246    {
247        int var3 = 0;
248        ItemStack var4 = null;
249        ItemStack var5 = null;
250        int var6;
251
252        for (var6 = 0; var6 < par1InventoryCrafting.getSizeInventory(); ++var6)
253        {
254            ItemStack var7 = par1InventoryCrafting.getStackInSlot(var6);
255
256            if (var7 != null)
257            {
258                if (var3 == 0)
259                {
260                    var4 = var7;
261                }
262
263                if (var3 == 1)
264                {
265                    var5 = var7;
266                }
267
268                ++var3;
269            }
270        }
271
272        if (var3 == 2 && var4.itemID == var5.itemID && var4.stackSize == 1 && var5.stackSize == 1 && Item.itemsList[var4.itemID].isRepairable())
273        {
274            Item var11 = Item.itemsList[var4.itemID];
275            int var13 = var11.getMaxDamage() - var4.getItemDamageForDisplay();
276            int var8 = var11.getMaxDamage() - var5.getItemDamageForDisplay();
277            int var9 = var13 + var8 + var11.getMaxDamage() * 5 / 100;
278            int var10 = var11.getMaxDamage() - var9;
279
280            if (var10 < 0)
281            {
282                var10 = 0;
283            }
284
285            return new ItemStack(var4.itemID, 1, var10);
286        }
287        else
288        {
289            for (var6 = 0; var6 < this.recipes.size(); ++var6)
290            {
291                IRecipe var12 = (IRecipe)this.recipes.get(var6);
292
293                if (var12.matches(par1InventoryCrafting, par2World))
294                {
295                    return var12.getCraftingResult(par1InventoryCrafting);
296                }
297            }
298
299            return null;
300        }
301    }
302
303    /**
304     * returns the List<> of all recipes
305     */
306    public List getRecipeList()
307    {
308        return this.recipes;
309    }
310}