You are on page 1of 41

ModLoader 1.3.2/1.3.

1
Hello, my name is jbond98, I am a YouTuber and Minecraft Modder, and welcome to my modding tutorials! You can check out my YouTube Channel, and my most popular mod, The Wolfestone Mod if you would like. I'm going to start off fresh, and perfect for beginners, but eventually I'll have some advanced tutorials here too! My goal is to share my modding knowledge with other minecraft modders, and to eliminate some of the problems that Minecraft 1.3.1+ is causing modders. I will also try to explain everything in as much detail as possible, so not only will you be able to see what to do, you'll also learn what to do!

Setting Up MCP 7.2 with ModLoader 1.3.2 and Eclipse Juno 4.2
Introduction In order to ensure maximum efficiency and comfortably whilst modding, it is highly recommended to use a java IDE, such as NetBeans or Eclipse with your Minecraft MCP. An IDE is an Integrated Development Environment which makes creating classes, testing features in your mod, and bug fixing a lot more convenient. Eclipse and NetBeans also have error highlighting and error quickfix features which make fixing problems much easier. Although I personally recommend Eclipse, I haven't really had much experience with NetBeans. Notepad++ You may use Notepad++ if you don't want to use an IDE for minecraft modding. Notepad++ is a freeware source code editor that supports many different programming languages, most importantly java. It does not have a built-in way to test your game, so you will have to use startclient.bat in your MCP folder to test your mod in-game. MCP 1.3.2 and Eclipse Juno 4.2 and ModLoader In order to correctly use Eclipse on your computer, you have to first set up your PATH variable. First, download the Java JDK link on the far left "Java Platform (JDK) 7u7", and then follow the instructions below:

The following is an example of a PATH environment variable: C:\Java\jdk1.7.0\bin;C:\Windows\System32\;C:\Windows\;C:\Windows\System32\Wbem It is useful to set the PATH environment variable permanently so it will persist after rebooting. To make a permanent change to the PATH variable, use the System icon in the Control Panel. The exact procedure varies depending on the version of Windows: Windows XP: 1. Select Start, select Control Panel. double click System, and select the Advanced tab. 2. Click Environment Variables. In the section System Variables, find the PATH environment variable and select it. Click Edit. If the PATH environment variable does not exist, click New. 3. In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK. Windows Vista: 1. From the desktop, right click the My Computer icon. 2. Choose Properties from the context menu. 3. Click the Advanced tab (Advanced system settings link in Vista). 4. Click Environment Variables. In the section System Variables, find the PATH environment variable and select it. Click Edit. If the PATH environment variable does not exist, click New. 5. In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK. Windows 7: 1. From the desktop, right click the Computer icon. 2. Choose Properties from the context menu. 3. Click the Advanced system settings link. 4. Click Environment Variables. In the section System Variables, find the PATH environment variable and select it. Click Edit. If the PATH environment variable does not exist, click New. 5. In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK.

Alright, now the hard part is over. You've set your PATH variable! Now to set up MCP 1.3.2 with Eclipse Juno 4.2:

Download MCP 1.3.2 (MCP 7.2 for Minecraft 1.3.2) Now you'll need to decompile your minecraft sources. Go to http://www.minecraft.net and login to your account. You'll need to download a fresh minecraft_server.jar for 1.3.2. Now go to your minecraft client. You'll need to force and update. After getting a fresh minecraft client, go to the ModLoader Download Page and download the most recent version of ModLoader. (Note: If there is no ModLoader 1.3.2, in this case wait for modloader to update or this will all crash!) Install ModLoader as you would a regular mod. Now go to your .minecraft folder and copy your bin and resources folders. Now, put all three of these things (minecraft_server.jar, bin, resources) inside of your jars folder inside of your MCP 1.3.2 folder. Now click the decompile.bat in your MCP folder. Wait until the decompiling process is finished. This might take a while! Now run your eclipse.exe, it is inside of the eclipse folder (You get this at the end of installing eclipse). Set the eclipse workspace to your MCP folder/eclipse. That's it! You're now ready to make that dream mod that you've always wanted! Go to the client -> src -> net.minecraft.src package and make your mod_*** file in that package.

Programs Needed:

Eclipse Juno 4.2: http://www.eclipse.org/downloads/ Click the first link from the top "Eclipe IDE for Java EE Developers MCP 7.2 for Minecraft 1.3.2: http://mcp.ocean-lab...hp/MCP_Releases Scroll down and find the download for mcp72.zip for Minecraft 1.3.2 Java JDK: http://www.oracle.co...oads/index.html Download the first link on the left "Java Platform (JDK) 7u7 (Or the most recent version of the JDK) ModLoader 1.3.2: http://www.minecraft...minary-updates/ These tutorials will work with ModLoader 1.3.1 also!

Optional Programs (To Replace Eclipse):


NetBeans: http://netbeans.org/ Download NetBeans IDE 7.2 (Not Recommended) Notepad++: http://notepad-plus-plus.org/ Download Notepad++ 6.1.6

ModLoader Basic Template


Any mod_*** file: package net.minecraft.src; import java.util.Random; public class mod_*** extends BaseMod { public void load() { } public String getVersion() { return "1.3.2"; } } This is a simple ModLoader mod_*** file template. This is how you will start off all of your mod_*** files. What's in the code: package net.minecraft.srcThis tells minecraft what package your class is located in.This line is very important and should be at the top of every class that you ever create.

import java.util.Random; This line is very important if you want to generate ores in the game, or anything like that. This imports java's Random function/methods library. You will see many other types of imports in the game such as import java.util.Map, importa java.util.List and so on. Just remember to do this or you will get many errors in the long run. public class mod_*** extends BaseModAll this line does is define this class as a public class, which means it can be referenced from anywhere, even outside of the package. Protected would mean that it can be referenced only inside of the package, and private would mean that it can be referenced only inside of the class. You would change mod_*** to mod_NameOfYourMod. The extends BaseMod allows you to use methods outside of the mod_*** class, in this case, the main ModLoader methods located in BaseMod.java.

public void load() { } This is ModLoader's main constructor. All ModLoader functions will go inside of the two curly braces. That means anything starting with "ModLoader.", anything else will go outside of this method. That means mehtods starting with "public static void" and the likes.

public String getVersion() { return "1.3.2"; } This function returns the version of your mod. You can simply put "1.3.2" here or something like "MyMod V2.0 Minecraft 1.3.1" It doesn't really matter. This is what is going to show up in the console when ModLoader loads your mod.

Modding Tutorials
All tutorials are 1.3.2 ModLoader Compatible! They will also work for 1.3.1. Tutorial 1 - How to Make a New Block - 1.3.2 Ready mod_*** File package net.minecraft.src; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Random; public class mod_wolfestone extends BaseMod { public static final Block oreWolfestone = new BlockWolfestoneOre(160, 0).setStepSound(Block.soundStoneFootstep).setBlockName("oreWolfestone").setHardness(4.5F).se tResistance(5F).setLightValue(0.375F); public void load() { oreWolfestone.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/textures/Wolfestone Ore.png"); ModLoader.registerBlock(oreWolfestone); ModLoader.addName(oreWolfestone, "Wolfestone Ore"); } public String getVersion() { return "Wolfestone Mod V2.0 Minecraft 1.3.2"; } }

What's in the code: import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Random; These are probably all of the imports that you will possibly need in your mod_*** file. Adding an

import that you don't need won't hurt you, but forgetting to add one that you do need will cause some serious problems. In my various tutorials I will be showing what imports are needed for the specific tutorial, and for this one you don't need any of them. It is still good practice to put those at the top though. To name a few of them, java.util,Arrays; is a java library that includes Array functions, java.util.Map is for adding renderers to the map, but you don't need to worry about that right now.

public static final Block oreWolfestone = new BlockWolfestoneOre(160, 0).setStepSound(Block.soundStoneFootstep).setBlockName("oreWolfestone").setHardness(4.5F).se tResistance(5F).setLightValue(0.375F); This is the function that tells ModLoader to add your blocks to Minecraft. I will go over each part in greater detail below:

public static final Block oreWolfestone = new BlockWolfestoneOre public static final Block is the actual function, and oreWolfestone is whatever you want the coding name for your block to be. This is not the name that will show up for the ore in-game. That comes later.

new BlockWolfestoneOre This is the class that all of your block data is located it. You would change BlockWolfestoneOre to the class where you block data is stored. Usually block classes start of with Block*** but this is just an organizational preference. More information about the Block*** file is further down the tutorial.

(160, 0) The number on the left, "160" is the block ID that you want your block to be registered to. To stay safe, start at 160, but make sure to pick numbers above 138(The last minecraft block ID that is in use by real minecraft blocks) and lower than 256(This is where item IDs start. I will explain this later.) The 0 used to tell minecraft where your item texture appears on the terrain.png. In this tutorial we will be setting the number to 0 because we will be overriding the terrain.png using ModLoader's override function, and making our own texture.

.setStepSound(Block.soundStoneFootstep) This tells ModLoader what sound to tie to your block. It is crucial to put Block in front of the .soundStoneFootstep because it is not referenced in your class. You can put many other sounds here, .soundGrassFootstep and .soundMetalFootstep, to name a few. Look in the Block.java class for the full list of sounds.

.setBlockName("oreWolfestone") This is only the coding name used for your block, not the name that will appear in-game. Use the same name you put at the beginning of the function.

.setHardness(4.5F) This sets your block's hardness. Since the number is a float, you will need to put "F" after the number. This number can be positive or negative. If you put a negative number here, that will make your block unbreakable in Survival Mode, like bedrock. (In java, a float is any number with a decimal point. An integer on the other hand, or an int has no decimal points and is a positive or negative number.)

.setResistance(5F) This sets your block's resistance to TNT or any other explosives. Normal blocks have any where from 1 to about 5 resistance. Obsidian has a resistance of 2000, which makes it immune to explosive damage.

.setLightValue(0.375F) This sets your block's light value. Since it is a float it can be a decimal number. Light values in minecraft range from 0F to 1F. 0 Meaning no light, 1 meaning full light. Light values cannot be negative numbers, and if you go over 1, nothing will happen because minecraft will not recognize anything over 1F. Note: If you decide to set your light value to 0, you do not need this .setLightValue function, and you can remove it. Same goes for .setResistance and .setHardness

oreWolfestone.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/textures/Wolfestone Ore.png"); This will set your block's texture in minecraft, and override the terrain.png, meaning that you will not have to put your textures in that file. You will now need 16x16 pixel textures for each block in your mod. When you have those textures put them inside a folder, I named mine textures. You don't have to but it helps organize your textures, so they are not cluttered in the main bin folder. The /texture/WolfestoneOre.png is where you have placed your texture inside of the minecraft.jar file. Mine is inside of a textures folder.

ModLoader.registerBlock(oreWolfestone); This code registers your block. If you do not do this, your game will crash! Also, make sure that it is inside of your public void load method. All you have to do here is change oreWolfestone to the coding name of your new block.

ModLoader.addName(oreWolfestone, "Wolfestone Ore"); This is where you will set the in-game name of your block. Change oreWolfestone to the coding name of your block, and change "Wolfestone Ore" to what you want the in-game name of your block to be. Make sure it is in quotations! Or else java will not read this as a string, and give you problems

public String getVersion() { return "Wolfestone Mod V2.0 Minecraft 1.3.2"; } This is the version of your mod. You can pretty much put anything here, as long as it is in quotations. I put the version of my mod along with what Minecraft version that it runs in. This is what will show up in the console when ModLoader loads your mod.

Block*** File package net.minecraft.src; import java.util.Random; public class BlockWolfestoneOre extends Block

{ public BlockWolfestoneOre(int par1, int par2) { super(par1, par2, Material.rock); this.setCreativeTab(CreativeTabs.tabBlock); } public int quantityDropped(int par1) { return (1); } public int idDropped(int par1, Random par2Random, int par3) { return mod_wolfestone.wolfestone.shiftedIndex; } }

What's in the code: I won't go into too much detail about this class, but here is what you need to know:

public class BlockWolfestoneOre extends Block This is your main method. It names the class, and tells minecraft that it extends the Block.java class, which means that you'll be able to use many functions from Block.java in your own Block*** class.

public BlockWolfestoneOre(int par1, int par2) This is your class constructor, and it is telling your mod_*** that it takes two parameters, int par1 and int par2. par1 and par2 are two different integer variables.

super(par1, par2, Material.rock); This is the super constructor, all you need to do here is change Material.rock to whatever material you want. Material.glass and Material.wood, to name a few. Each different material has different properties, and they are all listed in the Materials.java class.

this.setCreativeTab(CreativeTabs.tabBlock); This sets your block to the "Blocks" tab in Creative mode. You can also use .tabMaterials or .tabTools instead of .tabBlock, to name a few. The full list of Creative tabs is in the CreativeTabs.java class.

public int quantityDropped(int par1) { return (1); } This is telling minecraft to drop one of 'whatever it drops' ('whatever it drops' is set in the next function). You can change this to whatever you want, as long as it is an integer. You can also set this to a random number, but I won't really get into that. If you really want to know, ask me of look in the code for lapis lazuli.

public int idDropped(int par1, Random par2Random, int par3) { return mod_wolfestone.wolfestone.shiftedIndex; } This is what the block will drop once you break it. Here it is a wolfestone gem, but you can literally put anything. If it is an item, make sure to put Item. in front of it. If it is in your mod_*** class, put mod_***. in front of it, and same goes for blocks, put Block. in front of it. The .shiftedIndex only works for items, so if you want it to drop a block, make sure to put .blockID after your item. If you do not want to create a separate Block*** file: If your block doesn't really do anything too special, you don't have to make a separate Block*** class for it! In your mod_*** class, just change the following:

public static final Block oreWolfestone = new BlockWolfestoneOre(160, 0).setStepSound(Block.soundStoneFootstep).setBlockName("oreWolfestone").setHardness(4.5F).se tResistance(5F).setLightValue(0.375F);

public static final Block oreWolfestone = new Block(160, 0).setStepSound(Block.soundStoneFootstep).setBlockName("oreWolfestone").setHardness(4.5F).se tResistance(5F).setLightValue(0.375F); All this does is change the class extension for oreWolfestone to Block, instead of BlockWolfestoneOre. This is useful for simple blocks that don't really need much customization. You can not add your block to the creative inventory if it doesn't have a separate class! This should do it for the adding a new block tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 2 - How to Make a New Item - 1.3.2 Ready mod_*** package net.minecraft.src; import java.util.Random; public class mod_YourMod extends BaseMod { public static final Item yourItem = new ItemYourItem(5000).setItemName("yourItem"); public void load() { yourItem.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourItem.png"); ModLoader.addName(yourItem, "Your Item"); yourItem.setTabToDisplayOn(CreativeTabs.tabMaterials); } public String getVersion() { return "1.3.2"; } }

What's in the code: public static final Item yourItem = new ItemYourItem(5000).setItemName("yourItem"); This method adds your item to Minecraft. new ItemYourItem(5000) is the item ID, and ItemYourItem is the class that your item will extend, you can put "Item" here instead if your items doesn't have any special characteristics. I chose 5000 for the ID just to be safe. .setItemName("yourItem") sets the coding name for your item. This should be the same as the name here: public static final Item yourItem.

wolfestone.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/Wolfestone.png"); This overrides the regular items.png with your custom texture. I put my textures in a folder named textures. This folder would go inside of your minecraft.jar

ModLoader.addName(yourItem, "Your Item"); This sets the in-game name for your item.

yourItem.setTabToDisplayOn(CreativeTabs.tabMaterials); This will set your new item to the Creative inventory tab "Materials." Use this only if you don't have a separate class that extends your item. Look at my Creative Inventory tutorial for more information. This should do it for the adding a new item tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 3 - How to Add Items/Blocks to the Creative Inventory - 1.3.2 Ready Block***/Item*** File package net.minecraft.src; import java.util.Random; public class BlockWolfestoneOre extends Block { public BlockWolfestoneOre(int par1, int par2) { super(par1, par2, Material.rock); this.setCreativeTab(CreativeTabs.tabBlock); } public int quantityDropped(int par1) { return (1); } public int idDropped(int par1, Random par2Random, int par3) { return mod_wolfestone.wolfestone.shiftedIndex; } } Now, in 1.3.2, adding items to the Creative Inventory is very easy! All you have to do is add one line in your Block***/Item*** file! This will work for both.

this.setCreativeTab(CreativeTabs.tabBlock); All you need to do is add this line in your main Block***/Item*** constructor function. Right below the super constructor. What this line of code will do is add your block to the Blocks tab. You can change CreativeTabs.tabBlock to any tab you want, such as .tabMaterials or .tabTools. The full list is in the CreativeTabs.java class. If you do not have separate classes for Items: If you do not have separate classes for your Items you can still add them to the Creative Inventory by putting this line of code inside of the public void load method inside of your mod_*** class: YourItem.setTabToDisplayOn(CreativeTabs.tabMaterials); In this case you would change YourItem to the item that you would like to add to the Creative inventory. This should do it for the adding items/blocks to the creative inventory tutorial! Ask any questions below, or tell me what to add to this tutorial.[

Tutorial 4 - Adding Textures to your Items and Blocks - 1.3.2 Ready Adding Custom Textures to Items: yourItem.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/YourItem.png"); This ModLoader method overrides the in-game items.png, so that you can use your own textures without worrying about compatibility problems with other mods. Replace yourItem with the coding name of your item. Now, all you have to do is tell ModLoader where the texture is. putting "/YourItem.png" as the second parameter to the .addOverride function will tell ModLoader that your item is on the root directory of the minecraft.jar, but if you put it in a folder, such as textures, it will be more organized, which is what I did here. Adding Custom Textures to Blocks: yourBlock.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/textures/YourBlock.png"); Adding custom textures to blocks is almost identical to adding textures to items, just instead of .iconIndex, it is .blockIndexInTexture. Same rules apply for the rest of the function. Remember that both the item and block texture override methods go INSIDE of the public void load method! This should do it for the adding textures to your blocks/items tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 5 - Adding New Crafting Recipes (Including Dyes!) - 1.3.2 Ready Adding new recipes is easy with ModLoader. Just add the following code from this tutorial to your mod_*** file in the public void load() method. ModLoader.addRecipe(new ItemStack(blockWolfestone, 1), new Object [] {"###", "###", "###", Character.valueOf('#'), mod_wolfestone.wolfestone}); Adding new crafting recipes with ModLoader is easy! I'll be using some recipes from The Wolfestone Mod in this tutorial. Imagine the the "###", "###, "###", as the minecraft crafting grid. "###", "###", "###", Like this. This is how you will input your new crafting recipes. Top row is first, then second row, and last row.

Character.valueOf('#'), mod_wolfestone.wolfestone This function tells ModLoader what the # is supposed to be in the recipe. You can use almost any character for this, but try to keep it down to simple symbols and letters. The crafting recipe listed above is one for a Wolfestone Block, but that is pretty easy. Let's try a crafting recipe that is a little bit harder.

ModLoader.addRecipe(new ItemStack(wolfestoneBow, 1), new Object [] {" #X", "M X", " #X", Character.valueOf('#'), Item.stick, Character.valueOf('X'), Item.silk, Character.valueOf('M'), mod_wolfestone.wolfestoneShard}); Here is a recipe that is a bit more complicated. Look at how there are now three different symbols in the crafting grid. You have to tell ModLoader what each of them are, so you have to make a new Character.valueOf() function for each new symbol.

ModLoader.addRecipe(new ItemStack(wolfestoneShard, 4), new Object [] {"#", Character.valueOf('#'), mod_wolfestone.wolfestone}); Some recipes are shapeless, meaning that you can put them anywhere on the grid and they will still work. So for this recipe as long as there is one piece of wolfestone in the crafting grid, whether it is the 2x2 or 3x3, it will still produce four wolfestone shards.

ModLoader.addShapelessRecipe(new ItemStack(wolfestoneShard, 4), new Object[]{ wolfestone }); This is another way to add a shapeless recipe. As long as there is a piece of wolfestone in the crafting grid, it will give me 4 wolfestone shards.

ModLoader.addRecipe(new ItemStack(torchWolfestone, 8), new Object [] {"#", "X", Character.valueOf('#'), mod_wolfestone.wolfestoneShard, Character.valueOf('X'), Item.stick}); Same goes with torches. Look at the CraftingManager.java to get a better idea of crafting recipes, and what they look like for every craftable item in the game. Now you know how to make your very own crafting recipes!

This should do it for the adding new crafting recipes tutorial! Ask any questions below, or tell me what to add to this tutorial. Tutorial 6 - Adding A New Food - 1.3.2 Ready mod_*** package net.minecraft.src; public class mod_YourModName extends BaseMod { public static final Item nameHere = new ItemFood(5000, 6, 1F, true).setItemName("anyNameHere"); public void load() { foodNameHere.iconIndex = ModLoader.addOverride("/gui/items.png", "/image.png"); ModLoader.addName(foodNameHere, "My Food"); } public String getVersion() { return "1.3.1 MyModDescription"; } } There are no new lines of code here. The only part that you would need to change is where you initialize your item. And no, you can not make blocks edible! In the case of my own mod, I made it so that you can craft an edible item out of the block. If anyone needs further explanation, I can add it to this tutorial. What's in the code: public static final Item nameHere = new ItemFood(5000, 6, 1F, true).setItemName("anyNameHere"); The only thing that is new here is the ItemFood(5000, 6, 1F, true). You MUST make your item extend the class ItemFood! The 5000 is your item ID, the 6 stands for how many half food icons that your food can heal, not hearts! These are the icons that resemble a corndog right next to your regular hearts. This item will heal 3 full 'food icons.' The 1F stands for how long you can go before you get hungry again, the food saturation level. Lastly, true is a boolean that tells minecraft if your food can be fed to wolves. I put true here just for kicks. This should do it for the adding new food tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 7 - Adding New Smelting Recipes - 1.3.2 Ready Adding New Smelting Recipes For Items: ModLoader.addSmelting(yourItem.shiftedIndex, new ItemStack(yourSmeltedItem, 1), 1.0F); If you want to add new smelting recipes to your mod you will need to add this line of code above, into your public void load() method in your mod_*** class. It takes three parameters: 1. yourItem.shiftedIndex, this parameter has to be an integer, so we would use .shiftedIndex to find the item ID of our item. Put the name of your item you want to input into your furnace where it says yourItem. 2. new ItemStack(yourSmeltedItem, 1), this parameter takes a new instance of the class ItemStack, which takes two more parameters: yourSmeltedItem which is what the furnace will output once the input is smelted, and 1, this number is the amount you will get of the output once it is smelted. 3. 1.0F, the last parameter is a float, which means that it can be a decimal number. This is how much XP you will receive after each successful smelt. Adding New Smelting Recipes For Blocks: ModLoader.addSmelting(yourBlock.blockID, new ItemStack(yourSmeltedBlock, 1), 1.0F); Adding smelting recipes for blocks is almost identical to adding smelting recipes for items. The only thing that changes is the first parameter:

1. yourBlock.blockID, this parameter has to be an integer, so we would use .blockID to find the block ID of our block. This is the only difference between items and blocks. Put the name of your item you want to input into your furnace where it says yourBlock. 2. new ItemStack(yourSmeltedBlock, 1), this parameter takes a new instance of the class ItemStack, which takes two more parameters: yourSmeltedBlock which is what the furnace will output once the input is smelted, and 1, this number is the amount you will get of the output once it is smelted. Even though this references the class ItemStack, this still works for Blocks! 3. 1.0F, the last parameter is a float, which means that it can be a decimal number. This is how much XP you will receive after each successful smelt. This should do it for the adding new smelting recipes tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 8 - Adding New Fuels - 1.3.2 Ready public int addFuel(int par1, int par2) { if(par1 == yourFuelItem.shiftedIndex) { return 9600; } if(par1 == yourFuelBlock.blockID) { return 14400; } return 0; } In order to add new fuels to your mod you need to put this function in your mod_*** file. Make sure that it is NOT inside of the public void load() method! A fuel is and item or block that will power a furnace, such as coal or a block of wood, for example. If you want to add a new fuel that is an item: if(par1 == yourFuelItem.shiftedIndex) { return 9600; } If you want to add a new fuel that is an item, use this if-statement inside of the public int addFuel() function. yourFuelItem.shiftedIndex is the item that you want to be a fuel. Since this requires an integer, and we are dealing with items, we will be using .shiftedIndex. return 9600 returns the amount of ticks the furnace fuel will last. The number of ticks required to smelt one item is 200. Coal smelts for 1600 ticks. This particular item will smelt 48 blocks. If you want to add a new fuel that is an item: if(par1 == yourFuelBlock.blockID) { return 14400; } If you want to add a new fuel that is a block, use this if-statement inside of the public int addFuel() function. yourFuelBlock.blockID is the block that you want to be a fuel. Since this requires an integer, and we are dealing with blocks, we will be using .blockID. return 14400 returns the amount of ticks the furnace fuel will last. The number of ticks required to smelt one item is 200. Coal smelts for 1600 ticks. This particular item will smelt 72 blocks. This should do it for the adding new fuels tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 9 - How To Generate Your Own Ore In The Overworld - 1.3.2 Ready public void generateSurface(World world, Random random, int i, int j) { for(int k = 0; k < 5; k++) { int randPosX = i + random.nextInt(16); int randPosY = random.nextInt(128); int randPosZ = j + random.nextInt(16); (new WorldGenMinable(yourOreBlockName.blockID, 17)).generate(world, random, randPosX, randPosY, randPosZ); } } In order to generate your own ore on the surface (overworld) you will need to use this code outside of the public void load() method.

public void generateSurface(World world, Random random, int i, int j) This is the ModLoader function that allows modders to generate ores in the overworld.

for(int k = 0; k < 5; k++) This is the initialization for your 'for-loop' The only thing that you need to change here is the k < 5, to any number that you want. This number changes the amount of times that your ore vein can generate per chunk. In laymen's terms, this number controls the rarity of your ore.

int randPosX = i + random.nextInt(16); int randPosY = random.nextInt(128); int randPosZ = j + random.nextInt(16); This code is used to find a random x, y, and z variable to spawn the ore vein. Since the y and z coordinates are "flipped" in minecraft (usually the height would be a z coordinate, but here y is the height coordinate) you will have to use the y coordinate as your height coordinate. Basically, this code will find random coordinates in a chunk (16 X 16 X 128) to spawn your ore in. If you want your ore to be found only in underground areas, consider changing int randPosY = random.nextInt(128); to something more like int randPosY = random.nextInt(48); Diamond is found at int randPosY = random.nextInt(16); for reference.

(new WorldGenMinable(yourOreBlockName.blockID, 17)).generate(world, random, randPosX, randPosY, randPosZ); This code uses the information above (the random x, y, and coordinate) as well as the WorldGenMineable class to find the most suitable place to generate your ore. The only thing that you would need to change here is this: (yourOreBlockName.blockID, 17), you would put the name of your block, with .blockID here. The 17 is the maximum amount of ore that can spawn in each vein. Diamond is 7, for reference. This should do it for the generating your own ore in the overworld tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 10 - How To Generate Your Own Ore In The Nether - 1.3.2 Ready Generating an ore in the nether is simple, and almost identical to generating an ore in the overworld! The only difference are some parts in the function.

public void generateNether(World world, Random rand, int i, int j) { for(int m = 0; m < 7; m++) { int randPosX = i + rand.nextInt(16); int randPosY = rand.nextInt(128); int randPosZ = j + rand.nextInt(16); (new NetherGenMinable(yourNetherOre.blockID, 15)).generate(world, rand, randPosX, randPosY, randPosZ); } } I won't go into too much detail on this function. Look at the previous tutorial if you want a full explanation. What you have to do here is change int randPosY = rand.nextInt(128); to the maximum height you want your ore to generate in the nether. (new NetherGenMinable(yourNetherOre.blockID, 15)), this is the key to properly generating your ore in the nether. Change the 15 to what you want the max vein size to be.Also, you must create a new class. Call if whatever you want, but I called mine NetherGenMinable. NetherGenMinable package net.minecraft.src; import java.util.Random; public class NetherGenMinable extends WorldGenerator { /** The block ID of the ore to be placed using this generator. */ private int minableBlockId; /** The number of blocks to generate. */ private int numberOfBlocks; public NetherGenMinable(int par1, int par2) { this.minableBlockId = par1; this.numberOfBlocks = par2; } public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { float var6 = par2Random.nextFloat() * (float)Math.PI; double var7 = (double)((float)(par3 + 8) + MathHelper.sin(var6) * (float)this.numberOfBlocks / 8.0F); double var9 = (double)((float)(par3 + 8) - MathHelper.sin(var6) * (float)this.numberOfBlocks / 8.0F); double var11 = (double)((float)(par5 + 8) + MathHelper.cos(var6) * (float)this.numberOfBlocks / 8.0F); double var13 = (double)((float)(par5 + 8) - MathHelper.cos(var6) * (float)this.numberOfBlocks / 8.0F); double var15 = (double)(par4 + par2Random.nextInt(3) - 2); double var17 = (double)(par4 + par2Random.nextInt(3) - 2);

for (int var19 = 0; var19 <= this.numberOfBlocks; ++var19) { double var20 = var7 + (var9 - var7) * (double)var19 / (double)this.numberOfBlocks; double var22 = var15 + (var17 - var15) * (double)var19 / (double)this.numberOfBlocks; double var24 = var11 + (var13 - var11) * (double)var19 / (double)this.numberOfBlocks; double var26 = par2Random.nextDouble() * (double)this.numberOfBlocks / 16.0D; double var28 = (double)(MathHelper.sin((float)var19 * (float)Math.PI / (float)this.numberOfBlocks) + 1.0F) * var26 + 1.0D; double var30 = (double)(MathHelper.sin((float)var19 * (float)Math.PI / (float)this.numberOfBlocks) + 1.0F) * var26 + 1.0D; int var32 = MathHelper.floor_double(var20 - var28 / 2.0D); int var33 = MathHelper.floor_double(var22 - var30 / 2.0D); int var34 = MathHelper.floor_double(var24 - var28 / 2.0D); int var35 = MathHelper.floor_double(var20 + var28 / 2.0D); int var36 = MathHelper.floor_double(var22 + var30 / 2.0D); int var37 = MathHelper.floor_double(var24 + var28 / 2.0D); for (int var38 = var32; var38 <= var35; ++var38) { double var39 = ((double)var38 + 0.5D - var20) / (var28 / 2.0D); if (var39 * var39 < 1.0D) { for (int var41 = var33; var41 <= var36; ++var41) { double var42 = ((double)var41 + 0.5D - var22) / (var30 / 2.0D); if (var39 * var39 + var42 * var42 < 1.0D) { for (int var44 = var34; var44 <= var37; ++var44) { double var45 = ((double)var44 + 0.5D - var24) / (var28 / 2.0D); if (var39 * var39 + var42 * var42 + var45 * var45 < 1.0D && par1World.getBlockId(var38, var41, var44) == Block.netherrack.blockID) { par1World.setBlock(var38, var41, var44, this.minableBlockId); } } } } } } } return true; } } This seems like a very complicated class, but don't worry, it is. Luckily you don't have to do anything! Just use this class for your own mod. If you want to know how I created it, all I did was copy the WorldGenMinable class, and changed the part where is says == Block.stone.blockID to == Block.netherrack.blockID. What this does is let minecraft search for an optimal place to put your ore in netherrack, instead of stone. This should do it for the generating your own ore in the nether tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 11 - How To Create/Add Your Own Custom Achievements - 1.3.2 Creating and adding your own achievements to the Achievement map is pretty easy! In order to initiate your achievement use the following code: public static final Achievement achievementName = new Achievement(5000, "achievementName", 4, 9, Item.diamond, null).registerAchievement(); This initializes your new achievement. Make sure to place this code outside of your public void load() method! Change achievementName to the coding name of your achievement. Now, i'll explain (5000, "achievementName", 4, 9, Item.diamond, null) in greater detail:

5000 is your achievement ID. Try to go over 5,000 just to be safe. "achievementName" this is again, just the coding name of your achievement. Make sure that is the same as the achievementName before it. 4, 9, is the position of your achievement on the achievement grid. You'll pretty much have to just guess and check this one. Item.diamond this is what the achievement image will look like when you get it. You can change this to anything you want. null keep this as is for now, I'll explain what this does further in the tutorial.

Now, inside of your public void load() method, you need to put this line of code: ModLoader.addAchievementDesc(achievementName, "Achievement Name", "Achievement Description"); This is a ModLoader function for adding a new achievement name and description to your achievement:

Where it says achievementName you must put the coding name of your achievement. Change "Achievement Name" to what you want the actual in-game name of the achievement to be when you get it. Lastly, change "Achievement Description" this is what will be underneath your achievement name in the achievement grid; moreover, the achievement description. Try not to make this too long.

Finally, underneath your public void load() method, you want to add: public void takenFromCrafting(EntityPlayer entityplayer, ItemStack itemstack, IInventory iinventory) { if(itemstack.itemID == Block.blockDiamond.blockID) { entityplayer.addStat(achievementName, 1); } } What this does is trigger the achievement when something is crafted, more specifically a diamond

block. This is one of the many ways to trigger an achievement. Some of the others are a bit more complicated.

Change Block.blockDiamond.blockID to the block or item that you want to trigger the achievement once crafted. Lastly, change achievementName to the coding name of your achievement.

Making An Achievement Require Another Achievement:


This will make it so that you need to trigger another achievement first, before getting your own achievement. I will be using the "Build Better Pickaxe" in-game achievement for this tutorial:

static Achievement buildBetterPickaxe = AchievementList.buildBetterPickaxe; This sets up a variable for the in-game achievement so that it can be used inside of your mod_ class. You can change the buildBetterPickaxe in both cases to any achievement in the game, or even some of your own custom achievements (if you have multiple custom achievements). Look in AchievementList.java for the whole list of minecraft achievements. public static final Achievement achievementName = new Achievement(5000, "achievementName", 4, 9, Item.diamond, null).registerAchievement(); Now we can go back and change our original achievement declaration. Rembember the 'null' part that I was talking about? Well you can now change null to the name of the achievement that you want yours to "offspring" off of, or, in this case make it so that in order to get your achievement, it requires the "Build Better Pickaxe" achievement first:

public static final Achievement achievementName = new Achievement(5000, "achievementName", 4, 9, Item.diamond, buildBetterPickaxe).registerAchievement();

Making An Achievement Special: This means that the achievement will have a spiky frame around it in the achievement GUI, or grid, as I call it. All that you have to do is add the following code to your achievement initiation: .setSpecial()

The finished code will look like this in your initiation: public static final Achievement achievementName = new Achievement(5000, "achievementName", 4, 9, Item.diamond, buildBetterPickaxe).setSpecial().registerAchievement();

This should do it for the creating and adding your own achievement tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 12 - How To Create Your Own Tool Set - 1.3.2Note: This tutorial will require you to edit base classes! mod_*** package net.minecraft.src; public class mod_yourMod extends BaseMod { public static final Item yourPickaxe = (new ItemPickaxe(200, EnumToolMaterial.MATERIALNAME)).setItemName("yourPickaxe"); public static final Item yourAxe = (new ItemAxe(201, EnumToolMaterial.MATERIALNAME)).setItemName("yourAxe"); public static final Item yourShovel = (new ItemSpade(202, EnumToolMaterial.MATERIALNAME)).setItemName("yourShovel"); public static final Item yourSword = (new ItemSword(203, EnumToolMaterial.MATERIALNAME)).setItemName("yourSword"); public static final Item yourHoe = (new ItemHoe(204, EnumToolMaterial.MATERIALNAME)).setItemName("yourHoe"); public void load() { yourPickaxe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourPickaxe.png"); yourAxe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourAxe.png"); yourShovel.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourShovel.png"); yourSword.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourSword.png"); yourHoe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourHoe.png"); ModLoader.addRecipe(new ItemStack(yourPickaxe, 1), new Object [] {"###", " X ", " X ", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourShovel, 1), new Object [] {"#", "X", "X", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourSword, 1), new Object [] {"#", "#", "X", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourAxe, 1), new Object [] {"##", "#X ", " X", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourAxe, 1), new Object [] {"##", "X#", "X ", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourHoe, 1), new Object [] {"##", " X", " X", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourHoe, 1), new Object [] {"##", "X ", "X ", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addName(yourPickaxe, "Pickaxe Name"); ModLoader.addName(yourAxe, "Axe Pickaxe Name"); ModLoader.addName(yourShovel, "Shovel Pickaxe Name"); ModLoader.addName(yourSword, "Sword Pickaxe Name"); ModLoader.addName(yourHoe, "Hoe Pickaxe Name"); } public String getVersion() { return "1.3.2";

} } You guys should already be familiar with most of the coding here if you have read my earlier tutorials.

public static final Item yourPickaxe = new ItemPickaxe(200, EnumToolMaterial.MATERIALNAME).setItemName("yourPickaxe"); public static final Item yourAxe = new ItemAxe(201, EnumToolMaterial.MATERIALNAME).setItemName("yourAxe"); public static final Item yourShovel = new ItemSpade(202, EnumToolMaterial.MATERIALNAME.setItemName("yourShovel"); public static final Item yourSword = new ItemSword(203, EnumToolMaterial.MATERIALNAME).setItemName("yourSword"); public static final Item yourHoe = new ItemHoe(204, EnumToolMaterial.MATERIALNAME).setItemName("yourHoe"); These are your tool item initiations:

Change yourPickaxe/Axe/Shovel/Sword/Hoe to the name of your tools. EnumToolMaterial.MATERIALNAME is going to be the material that your tools are made of, change this to whatever you want. The rest should be very familiar to your other item initiations.

yourPickaxe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourPickaxe.png"); yourAxe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourAxe.png"); yourShovel.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourShovel.png"); yourSword.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourSword.png"); yourHoe.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourHoe.png"); These are your tool textures, and this should also be very familiar to you. Just change the appropriate names.

ModLoader.addRecipe(new ItemStack(yourPickaxe, 1), new Object [] {"###", " X ", " X ", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourShovel, 1), new Object [] {"#", "X", "X", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourSword, 1), new Object [] {"#", "#", "X", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourAxe, 1), new Object [] {"##", "#X ", " X", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourAxe, 1), new Object [] {"##", "X#", "X ", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourHoe, 1), new Object [] {"##", " X", " X", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); ModLoader.addRecipe(new ItemStack(yourHoe, 1), new Object [] {"##", "X ", "X ", Character.valueOf('#'), yourItem, Character.valueOf('X'), Item.stick}); These are your tool crafting recipes. Note that there are 7 crafting recipes, and only 5 tools. This is because the axe and the hoe can also be crafted when the recipe is flipped, so I added that in too.

ModLoader.addName(yourPickaxe, "Pickaxe Name"); ModLoader.addName(yourAxe, "Axe Pickaxe Name");

ModLoader.addName(yourShovel, "Shovel Pickaxe Name"); ModLoader.addName(yourSword, "Sword Pickaxe Name"); ModLoader.addName(yourHoe, "Hoe Pickaxe Name"); Add the names of your items, and you're done with the mod_*** file.

EnumToolMaterial (You are going to have to edit this base class for this tutorial to work) package net.minecraft.src; public enum EnumToolMaterial { WOOD(0, 59, 2.0F, 0, 15), STONE(1, 131, 4.0F, 1, 5), IRON(2, 250, 6.0F, 2, 14), EMERALD(3, 1561, 8.0F, 3, 10), GOLD(0, 32, 12.0F, 0, 22), MATERIALNAME(3, 1248, 6F, 3, 10); /** * The level of material this tool can harvest (3 = DIAMOND, 2 = IRON, 1 = STONE, 0 = IRON/GOLD) */ private final int harvestLevel; /** * The number of uses this material allows. (wood = 59, stone = 131, iron = 250, diamond = 1561, gold = 32) */ private final int maxUses; /** * The strength of this tool material against blocks which it is effective against. */ private final float efficiencyOnProperMaterial; /** Damage versus entities. */ private final int damageVsEntity; /** Defines the natural enchantability factor of the material. */ private final int enchantability; private EnumToolMaterial(int par3, int par4, float par5, int par6, int par7) { this.harvestLevel = par3; this.maxUses = par4; this.efficiencyOnProperMaterial = par5; this.damageVsEntity = par6; this.enchantability = par7; } /** * The number of uses this material allows. (wood = 59, stone = 131, iron = 250, diamond = 1561, gold = 32) */ public int getMaxUses() { return this.maxUses; } /** * The strength of this tool material against blocks which it is effective against.

*/ public float getEfficiencyOnProperMaterial() { return this.efficiencyOnProperMaterial; } /** * Damage versus entities. */ public int getDamageVsEntity() { return this.damageVsEntity; } /** * The level of material this tool can harvest (3 = DIAMOND, 2 = IRON, 1 = STONE, 0 = IRON/GOLD) */ public int getHarvestLevel() { return this.harvestLevel; } /** * Return the natural enchantability factor of the material. */ public int getEnchantability() { return this.enchantability; } } The only line of code that you have to worry about in this class is here:

MATERIALNAME(3, 1248, 6F, 3, 10); This is what defines your material, and it's properties

Replace MATERIALNAME with the name of your material. (Caps is proper syntax for this) 3 is the harvest level of your tool material. This is the level of material this tool can harvest (3 = DIAMOND, 2 = IRON, 1 = STONE, 0 = IRON/GOLD) 1248 is the number of uses this material allows before it breaks. (wood = 59, stone = 131, iron = 250, diamond = 1561, gold = 32) 6F is how fast this material can mine blocks that it is supposed to mine; such as how fast a pickaxe mines stone. 3 is how many half hearts of damage your tool will do to a mob or enemy. This will do 1.5 full hearts of damage. 10 is the natural enchantability factor. You'll have to play around with this one.

I will try to make a tutorial that doesn't edit any base classes eventually, but I'm still trying to figure that out. This should do it for the creating your own tool set tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 13 - How To Create Your Own Armor Set - 1.3.2Note: This tutorial will require you to edit base classes, but this is the only way to make your armor show up in-game! mod_*** package net.minecraft.src; public class mod_yourMod extends BaseMod { public static final Item yourHelmet = new ItemArmor(5001, EnumArmorMaterial.ARMORMATERIAL, ModLoader.addArmor("yourarmor"), 0).setItemName("yourHelmet"); public static final Item yourChestplate = new ItemArmor(5002, EnumArmorMaterial.ARMORMATERIAL, ModLoader.addArmor("yourarmor"), 1).setItemName("yourChestplate"); public static final Item yourLeggings = new ItemArmor(5003, EnumArmorMaterial.ARMORMATERIAL, ModLoader.addArmor("yourarmor"), 2).setItemName("yourLeggings"); public static final Item yourBoots = new ItemArmor(5004, EnumArmorMaterial.ARMORMATERIAL, ModLoader.addArmor("yourarmor"), 3).setItemName("yourBoots"); public void load() { yourHelmet.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourHelmet.png"); yourChestplate.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourChestplate.png"); yourLeggings.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourLeggings.png"); yourBoots.iconIndex = ModLoader.addOverride("/gui/items.png", "/textures/yourBoots.png"); ModLoader.addRecipe(new ItemStack(yourHelmet, 1), new Object [] {"###", "# #", Character.valueOf('#'), yourItem}); ModLoader.addRecipe(new ItemStack(yourChestplate, 1), new Object [] {"# #", "###", "###", Character.valueOf('#'), yourItem}); ModLoader.addRecipe(new ItemStack(yourLeggings, 1), new Object [] {"###", "# #", "# #", Character.valueOf('#'), yourItem}); ModLoader.addRecipe(new ItemStack(yourBoots, 1), new Object [] {"# #", "# #", Character.valueOf('#'), yourItem}); ModLoader.addName(yourHelmet, "Helmet"); ModLoader.addName(yourChestplate, "Chestplate"); ModLoader.addName(yourLeggings, "Leggings"); ModLoader.addName(yourBoots, "Boots"); } public String getVersion() { return "1.3.2"; } } Most of this code should be familiar to you, so I won't go into too much detail. Change things as needed.

public static final Item yourHelmet = new ItemArmor(5001, EnumArmorMaterial.ARMORMATERIAL,

ModLoader.addArmor("yourarmor"), 0).setItemName("yourHelmet"); public static final Item yourChestplate = new ItemArmor(5002, EnumArmorMaterial.ARMORMATERIAL, ModLoader.addArmor("yourarmor"), 1).setItemName("yourChestplate"); public static final Item yourLeggings = new ItemArmor(5003, EnumArmorMaterial.ARMORMATERIAL, ModLoader.addArmor("yourarmor"), 2).setItemName("yourLeggings"); public static final Item yourBoots = new ItemArmor(5004, EnumArmorMaterial.ARMORMATERIAL, ModLoader.addArmor("yourarmor"), 3).setItemName("yourBoots"); Here you need to change the following: new ItemArmor(5001, EnumArmorMaterial.ARMORMATERIAL, ModLoader.addArmor("yourarmor"), 0) This part of the code creates a new instance of ItemArmor and registers your armor with ModLoader.

Change EnumArmorMaterial.ARMORMATERIAL to whatever armor material you are planning on making your armor out of. Change ModLoader.addArmor("yourarmor") to whatever you want the prefix of the armor overlay textures to be. You will have to make new png files called yourarmor_1 and yourarmor_2 in order for the overlay to show up in-game. An example of these textures can be found in the bin/minecraft.jar/armor folder.

EnumArmorMaterial (You are going to have to edit this base class for this tutorial to work) package net.minecraft.src; public enum EnumArmorMaterial { CLOTH(5, new int[]{1, 3, 2, 1}, 15), CHAIN(15, new int[]{2, 5, 4, 1}, 12), IRON(15, new int[]{2, 6, 5, 2}, 9), GOLD(7, new int[]{2, 5, 3, 1}, 25), DIAMOND(33, new int[]{3, 8, 6, 3}, 10), ARMORMATERIAL(38, new int[]{4, 12, 8, 4}, 18); /** * Holds the maximum damage factor (each piece multiply this by it's own value) of the material, this is the item * damage (how much can absorb before breaks) */ private int maxDamageFactor; /** * Holds the damage reduction (each 1 points is half a shield on gui) of each piece of armor (helmet, plate, legs * and boots) */ private int[] damageReductionAmountArray; /** Return the enchantability factor of the material */ private int enchantability; private EnumArmorMaterial(int par3, int[] par4ArrayOfInteger, int par5) { this.maxDamageFactor = par3; this.damageReductionAmountArray = par4ArrayOfInteger; this.enchantability = par5;

} /** * Returns the durability for a armor slot of for this type. */ public int getDurability(int par1) { return ItemArmor.getMaxDamageArray()[par1] * this.maxDamageFactor; } /** * Return the damage reduction (each 1 point is a half a shield on gui) of the piece index passed (0 = helmet, 1 = * plate, 2 = legs and 3 = boots) */ public int getDamageReductionAmount(int par1) { return this.damageReductionAmountArray[par1]; } /** * Return the enchantability factor of the material. */ public int getEnchantability() { return this.enchantability; } } This class controls all of the functions of your new armor material.

ARMORMATERIAL(38, new int[]{4, 12, 8, 4}, 18);


The 38 is the overall damage factor that your armor can absorb before it breaks. The new int[]{4, 12, 8, 4} controls the damage factor per item of armor. Helmet, Chestplate, Leggings, Boots. The 18 controls the max enchantibility factor of the armor.

This should do it for the creating your own armor set tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 14 - How To Add Custom Trees/Saplings - 1.3.2 Making a new tree is a very complicated process. For this tutorial, I will be creating a new tree and sapling that will generate in the Forest. Later on I will show you how to make the tree generate in your own biome and even in your own dimension. Note that this tutorial is only for generating your tree in a pre-made minecraft biome in the overworld. mod_*** In order to get your tree to generate in a specific biome, you will need to put this code under the public void load() method in your mod_ file. If you already have a generateSurface() method, make sure to add the code inside of it to your already made method. Make sure that you have defined a new type of wood, leaf, and sapling in your mod_ class also. I go over how to initiate blocks and items in my earlier tutorials.

public void generateSurface(World world, Random rand, int chunkX, int chunkZ) { BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(chunkX, chunkZ); WorldGenYourTree tree = new WorldGenYourTree(); //Change this to the World Gens or your tree and make sure that the parameters match if you get errors! if(biome instanceof BiomeGenForest) { for(int c = 0; c < 3; c++) { int Xcoord = chunkX + rand.nextInt(16); int Zcoord = chunkZ + rand.nextInt(16); int i = world.getHeightValue(Xcoord, Zcoord); tree.generate(world, rand, Xcoord, i, Zcoord); } } } What this code will do is find a random X and Z location within a chunk and generate a tree there. This will generate 3 trees within any given chunk. Lowering the c < 3 will result in less trees, and vice versa. In order to actually generate anything you will need a new WorldGenYourTree class. WorldGenYourTree package net.minecraft.src; import java.util.Random; public class WorldGenYourTree extends WorldGenerator { public WorldGenYourTree() { } public boolean generate(World world, Random random, int i, int j, int k) { int l = random.nextInt(1) + 4; boolean flag = true;

if(j < 1 || j + l + 1 > 256) { return false; } for(int i1 = j; i1 <= j + 1 + l; i1++) { byte byte0 = 1; if(i1 == j) { byte0 = 0; } if(i1 >= (j + 1 + l) - 2) { byte0 = 2; } for(int i2 = i - byte0; i2 <= i + byte0 && flag; i2++) { for(int l2 = k - byte0; l2 <= k + byte0 && flag; l2++) { if(i1 >= 0 && i1 < 256) { int j3 = world.getBlockId(i2, i1, l2); if(j3 != 0 && j3 != mod_yourMod.yourLeaf.blockID) //Change this to your leaf block. { flag = false; } } else { flag = false; } } } } if(!flag) { return false; } int j1 = world.getBlockId(i, j - 1, k); if(j1 != Block.grass.blockID && j1 != Block.dirt.blockID || j >= 256 - l - 1) //This determines on what blocks your tree can generate. { return false; } world.setBlock(i, j - 1, k, Block.dirt.blockID); //Also determines what block your tree can generate on. for(int k1 = (j - 3) + l; k1 <= j + l; k1++) { int j2 = k1 - (j + l); int i3 = 1 - j2 / 2; for(int k3 = i - i3; k3 <= i + i3; k3++) { int l3 = k3 - i; for(int i4 = k - i3; i4 <= k + i3; i4++)

{ int j4 = i4 - k; if((Math.abs(l3) != i3 || Math.abs(j4) != i3 || random.nextInt(2) != 0 && j2 != 0) && !Block.opaqueCubeLookup[world.getBlockId(k3, k1, i4)]) { setBlockAndMetadata(world, k3, k1, i4, mod_yourMod.yourLeaf.blockID, 0); //Change to your leaf block. } } } } for(int l1 = 0; l1 < l; l1++) { int k2 = world.getBlockId(i, j + l1, k); if(k2 == 0 || k2 == mod_yourMod.yourLeaf.blockID) { setBlockAndMetadata(world, i, j + l1, k, mod_yourMod.yourWood.blockID, 0); //Change to your wood block. } } return true; } } This class determines the shape of your tree, and what types of leaves it will use and what type of wood it will use to generate your tree. It also determines what blocks your tree can spawn on. All that you need to do here is change some of the names around, and the rest is explained in the comments. In order to make your own type of wood log you will need the following class BlockYourLog package net.minecraft.src; import java.util.Random;

public class BlockYourLog extends Block { protected BlockYourLog(int i) { super(i, Material.wood); }

public int quantityDropped(Random random) { return 1; } public int idDropped(int i, Random random, int j) { return mod_yourMod.yourLog.blockID; //Change to your wood block }

public void harvestBlock(World world, EntityPlayer entityplayer, int i, int j, int k, int l) { super.harvestBlock(world, entityplayer, i, j, k, l); } public void onBlockRemoval(World world, int i, int j, int k) { byte byte0 = 4; int l = byte0 + 1; if(world.checkChunksExist(i - l, j - l, k - l, i + l, j + l, k + l)) { for(int i1 = -byte0; i1 <= byte0; i1++) { for(int j1 = -byte0; j1 <= byte0; j1++) { for(int k1 = -byte0; k1 <= byte0; k1++) { int l1 = world.getBlockId(i + i1, j + j1, k + k1); if(l1 != mod_yourMod.yourLeaf.blockID) //Change to your leaf block. { continue; } int i2 = world.getBlockMetadata(i + i1, j + j1, k + k1); if((i2 & 8) == 0) { world.setBlockMetadata(i + i1, j + j1, k + k1, i2 | 8); } } } } } } public int getBlockTextureFromSideAndMetadata(int i, int j) { if(i == 0) return mod_yourMod.yourLogBottom; if(i == 1) return mod_yourMod.yourLogBottom; if(i == 2) return mod_yourMod.yourLogSide; if(i == 3) return mod_yourMod.yourLogSide; if(i == 4) return mod_yourMod.yourLogSide; if(i == 5) return mod_yourMod.yourLogSide; if(j == 1) { return 116;

} return j != 2 ? 20 : 117; }

protected int damageDropped(int i) { return i; } } The getBlockTextureFromSideAndMetadata() method is something new, and is something that I will go over in my multi-textured blocks tutorial. That is coming up soon. Basically what this class does it get the texture of your wood block, and it also gets the ID of the item that your block drops, which is the wood block itself. Next you will need a new leaves class. BlockYourLeaf package net.minecraft.src; import java.util.Random; public class BlockYourLeaf extends BlockLeavesBase { private int baseIndexInPNG; int adjacentTreeBlocks[]; protected BlockYourLeaf(int i, int j) { super(i, j, Material.leaves, false); setTickRandomly(true); } public int getBlockColor() { double d = 0.5D; double d1 = 1.0D; return 0; } public void onBlockRemoval(World world, int i, int j, int k) { int l = 1; int i1 = l + 1; if(world.checkChunksExist(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1)) { for(int j1 = -l; j1 <= l; j1++) { for(int k1 = -l; k1 <= l; k1++) { for(int l1 = -l; l1 <= l; l1++) { int i2 = world.getBlockId(i + j1, j + k1, k + l1); if(i2 == mod_yourMod.yourSapling.blockID) //Change to your sapling block. { int j2 = world.getBlockMetadata(i + j1, j + k1, k + l1);

world.setBlockMetadata(i + j1, j + k1, k + l1, j2 | 8); } } } } } } public void updateTick(World world, int i, int j, int k, Random random) { if(world.isRemote) { return; } int l = world.getBlockMetadata(i, j, k); if((l & 8) != 0 && (l & 4) == 0) { byte byte0 = 4; int i1 = byte0 + 1; byte byte1 = 32; int j1 = byte1 * byte1; int k1 = byte1 / 2; if(adjacentTreeBlocks == null) { adjacentTreeBlocks = new int[byte1 * byte1 * byte1]; } if(world.checkChunksExist(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1)) { for(int l1 = -byte0; l1 <= byte0; l1++) { for(int k2 = -byte0; k2 <= byte0; k2++) { for(int i3 = -byte0; i3 <= byte0; i3++) { int k3 = world.getBlockId(i + l1, j + k2, k + i3); if(k3 == mod_yourMod.yourLog.blockID) //Change to your wood block. { adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = 0; continue; } if(k3 == mod_yourMod.yourLeaf.blockID) //Change to your leaf block. { adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = -2; } else { adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = -1; } } } } for(int i2 = 1; i2 <= 4; i2++) { for(int l2 = -byte0; l2 <= byte0; l2++) {

for(int j3 = -byte0; j3 <= byte0; j3++) { for(int l3 = -byte0; l3 <= byte0; l3++) { if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] != i2 - 1) { continue; } if(adjacentTreeBlocks[((l2 + k1) - 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] == -2) { adjacentTreeBlocks[((l2 + k1) - 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] = i2; } if(adjacentTreeBlocks[(l2 + k1 + 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] == -2) { adjacentTreeBlocks[(l2 + k1 + 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] = i2; } if(adjacentTreeBlocks[(l2 + k1) * j1 + ((j3 + k1) - 1) * byte1 + (l3 + k1)] == -2) { adjacentTreeBlocks[(l2 + k1) * j1 + ((j3 + k1) - 1) * byte1 + (l3 + k1)] = i2; } if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1 + 1) * byte1 + (l3 + k1)] == -2) { adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1 + 1) * byte1 + (l3 + k1)] = i2; } if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + ((l3 + k1) - 1)] == -2) { adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + ((l3 + k1) - 1)] = i2; } if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1 + 1)] == -2) { adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1 + 1)] = i2; } } } } } } int j2 = adjacentTreeBlocks[k1 * j1 + k1 * byte1 + k1]; if(j2 >= 0) { world.setBlockMetadata(i, j, k, l & -9); } else { removeLeaves(world, i, j, k); } } } private void removeLeaves(World world, int i, int j, int k) { dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k), 0); world.setBlockWithNotify(i, j, k, 0); } public int quantityDropped(Random random)

{ return random.nextInt(20) != 0 ? 0 : 1; } public int idDropped(int i, Random random, int j) { return mod_yourMod.yourSapling.blockID; //Makes your leaves drop your type of sapling. } public void dropBlockAsItemWithChance(World world, int i, int j, int k, int l, float f, int i1) { super.dropBlockAsItemWithChance(world, i, j, k, l, f, i1); if (!world.isRemote && (l & 3) == 0 && world.rand.nextInt(50) == 0) { dropBlockAsItem_do(world, i, j, k, new ItemStack(Item.apple.shiftedIndex, 1, 0)); //Makes your leaf have a 1/50 chance to drop an apple. } } public void harvestBlock(World world, EntityPlayer entityplayer, int i, int j, int k, int l) { if (!world.isRemote && entityplayer.getCurrentEquippedItem() != null && entityplayer.getCurrentEquippedItem().itemID == Item.shears.shiftedIndex) { entityplayer.addStat(StatList.mineBlockStatArray[blockID], 1); dropBlockAsItem_do(world, i, j, k, new ItemStack(Block.leaves.blockID, 1, l & 3)); } else { super.harvestBlock(world, entityplayer, i, j, k, l); } } protected int damageDropped(int i) { return i & 3; } public boolean isOpaqueCube() { return !graphicsLevel; } public int getBlockTextureFromSideAndMetadata(int i, int j) { if((j & 3) == 1) { return blockIndexInTexture; }else{ return blockIndexInTexture; } } public void setGraphicsLevel(boolean flag) { graphicsLevel = flag; } public void onEntityWalking(World world, int i, int j, int k, Entity entity) { super.onEntityWalking(world, i, j, k, entity);

} } This creates all of the technical things for your new leaf block. Lastly, you need a new sapling block BlockYourSapling package net.minecraft.src; import java.util.Random; public class BlockYourSapling extends BlockFlower { protected BlockYourSapling(int i, int j) { super(i, j); float f = 0.4F; setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f); } protected boolean canThisPlantGrowOnThisBlockID(int i) { return i == Block.grass.blockID; //Makes this grow on grass. }

public void updateTick(World world, int i, int j, int k, Random random) { if(world.isRemote) { return; } super.updateTick(world, i, j, k, random); if(world.getBlockLightValue(i, j + 1, k) >= 9 && random.nextInt(7) == 0) { int l = world.getBlockMetadata(i, j, k); if((l & 8) == 0) { world.setBlockMetadataWithNotify(i, j, k, l | 8); } else { growTree(world, i, j, k, random); } } } public int getBlockTextureFromSideAndMetadata(int i, int j) { j &= 3; if(j == 1) { return blockIndexInTexture; //63 }

if(j == 2) { return blockIndexInTexture; //79 } else { return blockIndexInTexture; } } public void growTree(World world, int i, int j, int k, Random random) { int l = world.getBlockMetadata(i, j, k) & 3; world.setBlock(i, j, k, 0); Object obj = null; obj = new WorldGenYourTree(); if(!((WorldGenerator) (obj)).generate(world, random, i, j, k)) { world.setBlockAndMetadata(i, j, k, blockID, l); } } protected int damageDropped(int i) { return i & 3; } } This creates everything you need for a new sapling. This tutorial will not cover how to make an object instantly grow your tree from your sapling! That will be explained at a later date. This should do it for the creating and generating a new tree/sapling tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 15 - How To Create A New Biome - 1.3.2 Creating a new biome is an interesting, but not very complex process. I will show you the basics, and you can add on to this on your own to make the new biome yours. This tutorial will show how to generate the biome in the overworld using your own top and filler block and also show you how to generate your own tree from the previous tutorial inside of the biome. This tutorial will not show you how to generate your biome in your new dimension, that is for the next tutorial. mod_*** First off, you will need the following lines of code inside of your mod_*** class. public static final BiomeGenBase biomeName = (new BiomeGenYourBiome(40)).setBiomeName("Biome Name"); Put this code outside of the public void load() method.

Change biomeName to the coding name of your biome. (new BiomeGenYourBiome(40) casts your BiomeGen class upon a new Biome ID. Make sure that the number you put here is lower than 127 because of java's byte limit. .setBiomeName("biomeName") sets the in-game name of your biome. This is only visible from the F3 (debug) menu when you're in that biome.

ModLoader.addBiome(nameHere); Put this code inside of the public void load() method. This is the ModLoader function for adding a new biome to the world generation list.

public static void generateSurface(World world, Random rand, int chunkX, int chunkZ) { BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(chunkX, chunkZ); WorldGenYourTree tree = new WorldGenYourTree(); if(biome instanceof BiomeGenYourBiome) { for(int x = 0; x < 8; x++) { tree = new WorldGenYourTree(); int Xcoord = chunkX + rand.nextInt(16); int Zcoord = chunkZ + rand.nextInt(16); int i = world.getHeightValue(Xcoord, Zcoord); tree.generate(world, rand, Xcoord, i, Zcoord); } } } Put this code outside of your public void load() method. If you already have a generateSurface() method with ore generation and such inside of it, then make sure to add the contents of this one to it. Make sure to change the names of the WorldGens to fit your trees. for(int x = 0; x < 8; x++) is the rarity of your trees per chunk. Change the 8 to fit your needs. Make sure that you also add two new blocks, a new type of grass and dirt, to your mod_*** file following my new block tutorial. To make the new type of grass, make sure to use code from BlockGrass.java and my multi-textured block tutorial.

BiomeGenYourBiome package net.minecraft.src; import java.util.Random; public class BiomeGenWolfeland extends BiomeGenBase { public BiomeGenWolfeland(int par1) { super(par1); this.spawnableCreatureList.clear(); this.spawnableMonsterList.clear(); this.spawnableWaterCreatureList.clear(); this.topBlock = (byte)mod_wolfestone.wolfeGrass.blockID; this.fillerBlock = (byte)mod_wolfestone.wolfeDirt.blockID; this.minHeight = -0.4F; this.maxHeight = 0.54F; } This class handles all of the little details included in a biome.

this.spawnableCreatureList.clear(); This clears any passive mobs from spawning in your biome. this.spawnableMonsterList.clear(); This clears any monsters from spawning in your biome at night. this.spawnableWaterCreatureList.clear(); This clears squid from spawning in your biome. If you want to know how to spawn a specific creature in the biome, have a look at the other BiomeGen classes. this.topBlock = (byte)mod_yourMod.yourGrass.blockID; Sets the top block for your biome. This is the first layer that you see, such as grass in most biomes. This will work for any block. You can even set this to lava, but it will get really messy... this.fillerBlock = (byte)mod_yourMod.yourDirt.blockID; This sets the filler block for your biome. The filler block is the block 4-5 layers deep after the top block. This is usually dirt in most cases, but again, you can set this to anything you like. this.minHeight = -0.4F; This sets the minimum height for you biome. Setting this below 0F, makes lakes able to generate in your biome. this.maxHeight = 0.54F; Sets the maximum height for you biome. If you want large mountains, try setting larger numbers.

And that's it! You have now created your own custom biome. Please test this tutorial, and tell me if it works in the comments below. If you are having a problem with this tutorial, please tell me and I will fix it. The Dimension tutorial should come out soon. This should do it for the creating your own biome tutorial! Ask any questions below, or tell me what to add to this tutorial.

Tutorial 16 - Crafting Recipes With Dyes! - 1.3.2 [spoiler] [CODE] ModLoader.addRecipe(new ItemStack(cobblestone, 1), new Object [] {" #", Character.valueOf('#'), new ItemStack(Item.dyePowder, 1, 12)}); [/CODE]What this would do is make one piece of light blue dye give me one piece of cobblestone in the crafting grid. Look at crafting with dyes this way: [CODE] Character.valueOf('#'), new ItemStack(Item.dyePowder, amount, damageValue)}); [/CODE]The amount is how much needs to be present, or the amount. You still have to keep this even if it is as a crafting ingredient. The damage value is what determines the color of the dye. Please refer to this chart for the damage or ID values of each dye:

Credits to RedPoptarts

You might also like