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