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