[Modding][ModLoader][Forge API] Jotamota's Tutorials!!!

  • #1
  • Forge
  • Tutorial I:
    How to infinite index textures
    And how to smelt metadata items.

    Tutorial II:
    How to multi-texture a block
    with Forge's infinite indexing of sprites!

    Tutorial III:
    How to create a block using metadata and Forge's texture indexing!


    ModLoader Tutorials!!!

    Tutorial I:How to make metadata-Items! (like ItemDye!!!)
    Difficulty: Begginer


    So, what is the point of making a metadata item? The thing is: Minecraft has a maximum number of ids that can be indexed to blocks and items. It is LIMITED so far, so metadata is a very easy (if you know how to use it) and practical solution the game has come up with to index a maximum of 16 (not confirmed) items to one ID, as done with ItemDye (16 items under one id: dyePowder.shiftedIndex).

    I'm assuming you know only a bit of how to create mods so I'm starting with basics.
    Notice that I will NOT explain how to setup MCP (there are plenty tutorials out there about it!!!)

    First of all, you must create a new file for your mod, named as you want. Its a modding convention to name all mod files "mod_" something, as in "mod_MoreCreeps", "mod_Cooking", and else. I'm naming our new mod file mod_ItemMetadata.

    After you created this file, you must extend it as a BaseMod (meaning it can do all a BaseMod can do) and create two functions: getVersion and public void load(). The function getVersion returns the version when asked when Minecraft runs. Public void load() is a void function that runs when the program is executed:

    package net.minecraft.src;
    
    import java.util.Random;
    import net.minecraft.client.Minecraft;
    
    /**
     *
     * @author Jotamota
     */
    public class mod_ItemMetadata extends BaseMod
    {
        //DECLARATION LINES HERE
        @Override
        public void load()
        {
            
        }
        
        @Override
        public String getVersion()
        {
              return "0.1";
        }
        
        //OR HERE :smile.gif:
    }


    Now, lets create our item shall we? First of all, we must declare the item! Note the spaces I've marked for declaration lines. You can do it anywhere, as long as it's inside the mod_ public class and outside any function.

    To create a item, we use this line, that declares a static(non-changeble), public(useable by other scripts) and final (cannot be extended). Then we define what the varible is, it's class. The same way we do...
    String stringVariable = "Hello, World";

    ...we call the Item class through the variable "variableForYourItem":
    public static final Item variableForYourItem;

    Lets call it noUse, shall we? We must now atribute a value for that variable. Since we want to customize, edit the script and we DONT want to mess with the base game files (because that cause mod incompatibilities if other mod also modifies it...) we create a new ItemClass, the ItemNoUse. To make a new Item with the caracteristics of a ItemNoUse and a Item, we use the constructor (a function that recieves input) ItemNoUse to send a id to Item. I'll explain later :smile.gif:. For now, we have this:
    public static Item noUse;
    noUse = new ItemNoUse;

    And then we access the ItemNoUse class that EXTENDS Item and we use a Item's function: setItemName. Since setItemName needs a String as input, we also give it a input. That's all:
    public static Item noUse = new ItemNoUse(idNumberGoesHere).setItemName("noUse");

    Modify the idNumberGoesHere with an Integer (an number) from about 200 to 3000. I would advice to choose around 2000 or 1000 since I'm not totally sure about the maximum of item ids.
    Your file mod_ItemMetadata should look like this now:

    package net.minecraft.src;
    
    import java.util.Random;
    import net.minecraft.client.Minecraft;
    
    /**
     *
     * @author Jotamota
     */
    public class mod_ItemMetadata extends BaseMod
    {
        //DECLARATION LINES HERE
        public static Item noUse = new ItemNoUse(1694).setItemName("noUse");
        
        @Override
        public void load()
        {
            //MOD COMMANDS GOES HERE
        }
        
        @Override
        public String getVersion()
        {
              return "0.1";
        }
        
        //OR HERE :smile.gif:
    }

    Now, we must create an ItemMetadata, or on our case, an ItemNoUse. This is an example of items that I use on my mod and that have no use besides crafting. This way, we save ids from using.
    So, create a file name ItemNoUse.java and make the constructor ItemNoUse(int id). Since this is a metadata item, we must also declare the maxDamage to 0 (that means that there won't be any damage display on the item and call that this IS a itemMetadata with the setHasSubtypes function, like this:
    package net.minecraft.src;
    
    /**
     *
     * @author Jotamota
     */
    public class ItemNoUse extends Item
    {
        public ItemNoUse(int id)
        {
            super(id);
            setHasSubtypes(true);
            setMaxDamage(0);
        }
        
    }

    Note that besides the public class that IS the ItemNoUse.java, we have a function with a constructor: ItemNoUse(int id). This means it recieves as input a Integer. And then it runs super(id);
    super is a method to upper bump the code to the item that its the script's parent. Kinda hard to understand, huh? Since ItemNoUse extends Item, we can say its a "child" of Item. It can do what ever its "parent" can do, and by the function super(id) it sends the input as output to the constructor Item(int i) wich can be found on Item.java.

    Now, we must create a a "multiple string" (on a way) by creating a String called "names". Add this on the declaration space (inside the main public class file function and outside any other function:
    private String[] names = new String[]{};

    We call it private so only this script can access it. This prevents conflicts between two scripts that call a variable named the same and it prevents other scripts to access it.
    Note that this replaces the spot for "public". Instead, its "private".

    So we can easily track the item indexed to each metadata, lets make a annotation here that mimics the line above and shows the damage to each item, like this:
    private String[] names = new String[]{"item1", "item2"};
      //private String[] names = new String[]{"  0  ", "  1  "};

    This makes a String with 2 strings. The first one is "item1" and the second one is "item2". Since the item damage is initially 0, we say that this is the itemDamage(0).

    Now we create the Item function that assigns each "names" to its real name:
    @Override
        public String getItemNameIS(ItemStack itemstack)
        {
            return names[itemstack.getItemDamage()];
        }

    This is a String function. Being a String function, it returns a String. A int function returns a int, a boolean function returns a boolean (true or false), and among many others, a void function just runs.
    It recieves as input a ItemStack called "itemstack", and we Override it to force the code to make sure that is the same function as it's parent (in this case, Item.java).

    Your ItemNoUse should look like this so far:

    package net.minecraft.src;
    
    /**
     *
     * @author Jotamota
     */
    public class ItemNoUse extends Item
    {
        public ItemNoUse(int id)
        {
            super(id);
            setHasSubtypes(true);
            setMaxDamage(0);
        }
        
        private String[] names = new String[]{"item1", "item2"};
      //private String[] names = new String[]{"  0  ", "  1  "};
        
        @Override
        public String getItemNameIS(ItemStack itemstack)
        {
            return names[itemstack.getItemDamage()];
        }
            
        
    }

    Another thing we want for our items is that each one can be able to have a different icon. Item.java already defines that function for us. It's the getIconFromDamage, that selects a icon depending on the item metadata:
    @Override
        public int getIconFromDamage(int i)
        {
            if(i==0){
                setMaxStackSize(1);
                return mod_ItemMetadata.itemIcon1;}
            if(i==1)
            {            
                //setContainerItem(Item.bucketEmpty);    
                return mod_ItemMetadata.itemIcon2;
            }
            else{
                setMaxStackSize(64);
                return mod_ItemMetadata.itemIcon3;}
            
        }

    The int "i" that is called from this function is the item metadata. Meaning that we can index item commands for each specific item, as setting a container Item or setting MaxStackSize for each different item.

    I've used a few commands. Those are located at Item.java. There are many many more commands to be used. I used setMaxStackSize(64), that sets the maxStack for this item to 64. setContainerItem(Item.bucketEmpty) that would set a container item (in this case, a empty bucket) if it wasnt after // (those two slashes make the line after that comment. It means that the code doesn't read it. It's for reading or disabling the line).

    Note that this is a int function. As I said before, a int function returns a int. Look that we check the if condition to see if the metadata of the item ("i") is equal to 1,2 or else. Meaning that if its 1, it will run between 1 if condition. Else is for the non defined if conditions (if a item is beyond 1 or 2, it will run else instead of crash).

    Since this is a ModLoader tutorial, we must create a itemIcon index for each item. Let's go to our mod_ItemMetadata now and add each itemIcon with the addOverride command.

    Go to our declaration lines and add this line:
    public static int itemIcon1 = ModLoader.addOverride("/gui/items.png", "/YourFileFolderHere/nameOfYourIcon.png");

    This overrides the items.png file to include one more, the file that you want your icon to have. Your "YourFileFolderHere" folder must be in the /MCP/bin/minecraft/ directory, and your nameOfYourIcon image file should be there. You can always change the path if you want. So, we need 3 icons, lets copy and paste 2 times!
    public static int itemIcon1 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon1.png");
    public static int itemIcon2 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon2.png");
    public static int itemIcon3 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon3.png");

    Your icon.png files should be 16x16 and be saved as a PNG file.
    Your mod_ItemMetadata should look like this:

    package net.minecraft.src;
    
    import java.util.Random;
    import net.minecraft.client.Minecraft;
    
    /**
     *
     * @author Jotamota
     */
    public class mod_ItemMetadata extends BaseMod
    {
        //DECLARATION LINES HERE
        public static Item noUse = new ItemNoUse(1694).setItemName("noUse");
        public static int itemIcon1 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon1.png");
        public static int itemIcon2 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon2.png");
        public static int itemIcon3 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon3.png");
        
        @Override
        public void load()
        {
            //MOD COMMANDS GOES HERE
        }
        
        @Override
        public String getVersion()
        {
              return "0.1";
        }
        
        //OR HERE :smile.gif:
    }

    Now, we must add names to each of our items. This must be done on mod_ItemMetadata, inside public void load() or inside a function called by public void load():
    @Override
        public void load()
        {
            //MOD COMMANDS GOES HERE
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 0), "Item 1 Name");
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 1), "Item 2 Name");
        }

    This calls the function "AddName" inside ModLoader.java (hence the ModLoader.FunctionName...) and it offers as input a ItemStack( will be explained later ) a String: the item's name. For a short, the new ItemStack creates a new function that recieves as input (in this case) a item (variable "noUse" located inside mod_ItemMetadata.java), a quantity (1) and the item damage (0). This makes each noUse item that has a different damage to have different names.

    And now, we need to have some way of getting those items in-game. Lets make recipes!
    ModLoader.AddRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 0), new Object[]
            {
               "XXX","XYX","XXX", Character.valueOf('X'), Item.stick, Character.valueOf('Y'), Block.planks 
            });

    Time for a little explanation. The command AddRecipe calls a itemstack, wich is a item function that embraces quantity, damage, item, respectually, and many other item properties. What we must do is create a new ItemStack that is a noUse type of item, has quantity ONE (first number) and is damage 0 (second number), and then we create the shape of the recipe and its character.
    Basically, everytime you need a itemstack of a metadata item, you must call THAT particular itemstack (item, quantity, damage). Change damage according to the item you want on your ItemNoUse names String, and also change quantity to your like.
    The Object of the recipe is pretty simple. We first make how our recipe will look like ( if it was a sword, it would be ("x","x","y") and then we say the value of the character 'X'. You can change the characters used as long as you change both in recipe and valueOf function.

    We can also create a shapeless recipe:
    ModLoader.AddShapelessRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 1), new Object[] {Block.dirt, new ItemStack(mod_ItemMetadata.noUse, 1, 0)});

    This is an example recipe where we use one ItemNoUse to create other ItemNoUse. Note that we called the new ItemStack instead of calling Item.blahblahblah or Block.blahblahblah.
    If you want to use this as a furnace PRODUCT, you should use this code:
    ModLoader.AddSmelting(Block.dirt.blockID, new ItemStack(mod_ItemMetadata.noUse, 1, 0));

    Now, if you want to use it as a INGREDIENT, that's where we face a problem. Minecraft default furnace NOR ModLoader AddSmelting methods tolerate using a metadata item as ingredient. However, Forge API accepts it. If you ever want it, you must download Forge API and install it, and meet me here for this same Tutorial on Forge's Version.

    We have met the finale of this tutorial. Here are the full codes for your examination and comparison:

    mod_ItemMetadata:

    package net.minecraft.src;
    
    import java.util.Random;
    import net.minecraft.client.Minecraft;
    
    /**
     *
     * @author Jotamota
     */
    public class mod_ItemMetadata extends BaseMod
    {
        //DECLARATION LINES HERE
        public static Item noUse = new ItemNoUse(1694).setItemName("noUse");
        public static int itemIcon1 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon1.png");
        public static int itemIcon2 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon2.png");
        public static int itemIcon3 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon3.png");
        
        @Override
        public void load()
        {
            //MOD COMMANDS GOES HERE
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 0), "Item 1 Name");
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 1), "Item 2 Name");
            
            ModLoader.AddRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 0), new Object[]
            {
               "XXX","XYX","XXX", Character.valueOf('X'), Item.stick, Character.valueOf('Y'), Block.planks 
            });
            ModLoader.AddShapelessRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 1), new Object[] {Block.dirt, new ItemStack(mod_ItemMetadata.noUse, 1, 0)});
            ModLoader.AddSmelting(Block.dirt.blockID, new ItemStack(mod_ItemMetadata.noUse, 1, 0));
        }
        
        @Override
        public String getVersion()
        {
              return "0.1";
        }
        
        //OR HERE :smile.gif:
    }


    ItemNoUse.java:

    package net.minecraft.src;
    
    /**
     *
     * @author Jotamota
     */
    public class ItemNoUse extends Item
    {
        public ItemNoUse(int id)
        {
            super(id);
            setHasSubtypes(true);
            setMaxDamage(0);
        }
        
        private String[] names = new String[]{"item1", "item2"};
      //private String[] names = new String[]{"  0  ", "  1  "};
        
        @Override
        public String getItemNameIS(ItemStack itemstack)
        {
            return names[itemstack.getItemDamage()];
        }
        
        @Override
        public int getIconFromDamage(int i)
        {
            if(i==0){
                setMaxStackSize(1);
                return mod_ItemMetadata.itemIcon1;}
            if(i==1)
            {            
                //setContainerItem(Item.bucketEmpty);    
                return mod_ItemMetadata.itemIcon2;
            }
            else{
                setMaxStackSize(64);
                return mod_ItemMetadata.itemIcon3;}
            
        }
    }

    If you liked this tutorial, leave a +1 down there at the end of any of my posts;
    If you have any error while doing/copying this tutorial post 'em here that I'll try to help you as far as I can.
    Hope you all liked it!

    EDIT: thanks for callofcrafters for pointing me the weakness of this tutorial power of explanation. I hope this is more elaborated and understandable now. :smile.gif:

    If you have doubts about any matter on modding post them here and I'll see if I can help you. If I CAN help, I'll make a new Tutorial just for you :smile.gif:

    Tutorial II:How to generate structures(using loops and not line-by-line generation)!
    Difficulty: Intermediate


    Hey guys! It's Jota again, with one more Tutorial. This time, we will cover up a very expected tutorial: Generating Structures. Normally people do this line by line, like this:

    Generate Structures

    You don't need to watch that video. Just by the thumbnail you can see the lots of lines with setBlock. I'm teaching you how to do this, the pro-way (:smile.gif:). And that is: using LOOPS.
    But before we get into generating, we must make a new block that when clicked generates our Structure. Let's get into it!
    From our basic layout for blocks we can start working. This is the basic layout:
    package net.minecraft.src;
    import java.util.Random;
    
    public class BlockGenStructure extends Block
    {
    	protected BlockGenStructure(int i, int j)
    	{
    		super(i, j, Material.rock);
    	}
    	
    	public int idDropped(int i, Random random)
    	{
    		return mod_Structures.genStructure.blockID;
    	}
    	
    }

    I've named it BlockGenStructure. You can name it what ever you want. Well, this is the basic from basic. Now let's register our block on mod_Structures:
    public static final Block genStructure = (new BlockGenStructure(1615, 28)).setHardness(3F).setResistance(5F).setBlockName("genStructure");

    public void load()
    {
    genStructure.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/Blocks/genStructure.png");
    		ModLoader.RegisterBlock(genStructure);
    		ModLoader.AddName(genStructure, "House-In-A-Block");
    }

    That's it. I'm not covering this again since I've done it already on ModLoader Tutorial I and if I'm not mistaken on Forge's Tutorial II. Now we add a very special function to our block: blockActivated.

    The thing is: Block.java embraces a LOT of block's functions, including onBlockClicked, blockActivated, blockDestroyed, and many others. We are using blockActivated since this function allows us to check for a item used by the player. This way, we can do a "key" for this block. If we go to Block.java and look for blockActivated this is what we get:
    public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer)
        {
            return false;
        }

    This is the "default" version of blockActivated, that EVERY block have. That is, unless we override this function on the new Block, wich is exactly what we are going to do.
    As covered before, this is a perfect example of a function:
    public CLASS functionNAME(InputClass input1, InputClass input2, InputClass input3,...)
    {
    
    }

    We have a public function of type BOOLEAN (it has only 2 values: true or false) with the name blockActivated, and it has several inputs:
    World world//A variable called "world" of type "World"
    ENtityPlayer entityplayer// A variable "entityplayer" of type "EntityPlayer"
    int j// A integer called "j"

    Again, a integer is a number that is "complete" (e.g: 1,2,4,5671). "2.0" is NOT a int. "2/3" is also not a integer. "2/2" and "2*52" are integers.
    Below a personal message (skip it if desired!):

    Again, guys, this tutorial is not about giving codes. I like to explain what I use so YOU guys can understand and use it at your own advantage. If you guys find it boring and useless, you can skip this chat and go to the final files. YOu won't learn anything if you do so, but I won't stop you.
    Back to our tutorial!
    The function blockActivated offers for us to use a World, a EntityPlayer and coordinates:(i,j,k) meaning (x,y,z) axis (Vector3). This is why when wanting to check for inventory, coordinates and do things in the World we use the blockActivated. Now, how to use it, you ask? Simple thing my good reader!
    public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer)
        {
            if(world.multiplayerWorld)
            {
                return true;
            }
            ItemStack itemstack = entityplayer.inventory.getCurrentItem();
            if(itemstack == null)
            {
                return true;
            }
        }

    Now, we added some conditions to the blockActivated.
    The first one is to prevent crashes on Multiplayer, so we can always activate a block on Multiplayer (again, this is a SinglePlayer mod, I never tried to mod SMP).
    And then we define a new variable called "itemstack". It's the current Item from the entityplayer (the player that activated the block). Now we can use the itemstack and change things around it.
    The last condition is to prevent crashes: when the itemstack DOES NOT EXIST ("null") the function returns true. So if you have no item you will click the block ("punch animation" but nothing will happen.
    Now we do the checking for the item. We can do so checking the itemstack itemID or it's damage (for a metadata item):
    if(itemstack.itemID == Item.stick.shiftedIndex)
            {
                //our code goes here
                itemstack.stackSize--;
                return true;
            }
    
    if(itemstack.itemID == mod_Metadata.metadataItem.shiftedIndex&&itemstack.getItemDamage() == 2)
            {
                //our code goes here
                itemstack.stackSize--;
                return true;
            }

    The first condition is for normal Items. We check if the player is holding a stick. If he is, we take off one of the stack and we run our code.
    The second is for metadata Items. We check for the itemID AND ("&&" operator) the itemDamage "2". Meaning we will only use the item if he is metadataItem "2".

    Now we run the generation part. This is really tricky, so I'm explaining step by step.

    As I said, most people use line-by-line codes. We can short it up and make the code run faster by using loops (a piece of code that runs several times). In java we have several loops ("while", "for"). This time we are using the "for" loop:

    for(int clock = 0; clock<20; clock++)
    {
    	System.out.println(clock);
    }

    The for loop declares a variable, imposes a condition, and sets a "add" system.
    This loops declare a int variable of value 0. Then it sets a condition: it will only run if the clock variable "value" is lower than 20. Then it increases the value of clock. (clock++ is the same as clock=clock+1 or clock+=1). Then it prints the clock value. The output of this code would be 0,1,2,3,4,5,6,7,8,...18,19. Remember that "<" means lower, so the loop will stop one number before 20. If you want it to stop ON 20, we use "<=" (lower or equal).
    Now that we understand the basic for loop, lets apply it to generating:
    for(int a = -3; a<4; a++)
    {
    	world.setBlockWithNotify(i+a,j-1,k, Block.planks.blockID);
    }

    Now THIS loop is gold! It sets a as -3 and it runs until a = 3.
    Then it sets a block of type "Block.planks" with notify. The thing about using setBlock or setBlockWithNotify is that when you generate a world, you can use setBlock. But you need notify to tell the world that a new block appeared. If you don't you will only see the blockBounds but you won't be able to see the block. Since we want to generate on normal gameplay we use notify. Then we say the coordinates for the world to generate the block. We want it to generate one block below the actual block (j-1 is the same as y-1). And then it generates a block in the x coordinate i+a. On the first run of this loop it will generate a block on coordinates (i-3, j-1, k). On the second run it will generate on (i-2, j-1, k) and so on until it reaches (i+3, j-1, k). Basicly this 3 lines of code are the same as writing this code below:
    world.setBlockWithNotify(i-3,j-1,k, Block.planks.blockID);
    world.setBlockWithNotify(i-2,j-1,k, Block.planks.blockID);
    world.setBlockWithNotify(i-1,j-1,k, Block.planks.blockID);
    world.setBlockWithNotify(i,j-1,k, Block.planks.blockID);
    world.setBlockWithNotify(i+1,j-1,k, Block.planks.blockID);
    world.setBlockWithNotify(i+2,j-1,k, Block.planks.blockID);
    world.setBlockWithNotify(i+3,j-1,k, Block.planks.blockID);

    See what I meant about line-by-line code?
    And that was just 7 blocks! Imagine how much lines we would have to write to generate a 7x7x7 cube! (:ohmy.gif:)
    Meaning this will make a line of planks from i+(-3) to i+3 x axis.
    Now we must add another coordinate! For this we can add a for loop INSIDE a for loop. Sounds trippy!
    for(int a = -3; a<4; a++)
    {
    	for(int c = -3; c<4; c++)
    	{
    		world.setBlockWithNotify(i+a,j-1,k+c, Block.planks.blockID);
    	}
    }

    Amazing! 5 lines to generate 49 blocks! This 2 loops will generate from -3 to 3 on X line and -3 to 3 on Z line. You can mess around with the coordinates, because they work FINE. :smile.gif:
    This generates a 7x7 square on the ground (-3 to 0 and 0 to 3 = 7 blocks on each axis) one block below the genStructure block.
    But we want a house, don't we?
    Now we will get into my code (the code I've used to create a house from one block). Things are gonna get REALLY intense now.
    First of all we need pillars. Let's do one 4 tall pillar of wood on each house corner, shall we? For that we must set a condition: "this will only run if it is on the certain coordinates!":
    for(int a = -3; a<4; a++)
    {
    	for(int c = -3; b<4; c++)
    	{
    		if(a==-3&&c==-3)
    		{
    			world.setBlockWithNotify(i+a,j,k+c, Block.wood.blockID);
    		}
    
    		world.setBlockWithNotify(i+a,j-1,k+c, Block.planks.blockID);
    	}
    }

    This says that it will only run the "new generation code" if it is on a coordinate -3 and c coordinate -3. This will create a block of wood on the coordinates i-3, j, and k-3. But we need 4 pillars right?
    for(int a = -3; a<4; a++)
    {
    	for(int c = -3; b<4; c++)
    	{
    		if((a==-3&&c==-3)||(a==-3&&c==+3)||(a==+3&&c==-3)||(a==+3&&c==+3))
    		{
    			world.setBlockWithNotify(i+a,j,k+c, Block.wood.blockID);
    		}
    
    		world.setBlockWithNotify(i+a,j-1,k+c, Block.planks.blockID);
    	}
    }

    This seems weird, but it's really simple. It sets a condition with 4 conditions blended with the OR operator ("||"). Meaning it will only run if it's on one of the 4 coordinates. This will create 4 blocks of wood on the corners. Now we want them to branch up! For that we need a new loop. This time it will go on the "y" axis, called "j" on our code. We can do it from 0 to 4 since we don't want it to grow "down":
    for(int a = -3; a<4; a++)
    {
    	for(int b = -3; b<4; b++)
    	{
    		if((a==-3&&c==-3)||(a==-3&&c==+3)||(a==+3&&c==-3)||(a==+3&&c==+3))
    		{	
    			for(int b=0; b<4; b++)
    			{
    				world.setBlockWithNotify(i+a,j+b,k+c, Block.wood.blockID);
    			}		
    		world.setBlockWithNotify(i+a,j-1,k+c, Block.planks.blockID);
    	}
    }

    Yep. Done. This creates a 3 blocks tall of normal wood from the coordinates -3,-3, -3,3, 3,-3, and 3,3 on x and z axis. We used a new loop to create the pillars. Now we need some walls on our house, right? For that, (you guessed right!) we use NEW loops (but with new conditions). This time, we will generate 2 walls in each axis (x and z, in here "i" and "k"):
    if((c==-3||c==3)&&(a>-3&&a<3))
    {
          for(int b=0; b<4; b++)
          {
                world.setBlockWithNotify(i+a,j+b,k+c, Block.planks.blockID);
          }
    }

    This creates a wall in c "-3" and c "3". I said AND, even though the code says "OR". That's because when I say -3 or 3 on the code the loop will generate the wall in -3 OR 3, meaning, it will generate on both coordinates -3 and 3. Then we set a AND condition: when a is between -2 and 2 we will make a 3 tall pillar of planks. This pillar will be made on each "a" coordinate, meaning it will make 5 pillars of planks, also know as a wall! Now that we got 2 walls done, we make the other one!
    if((a==-3||a==3)&&(c>-3&&c<3))
    {
          for(int b=0; b<4; b++)
          {
                world.setBlockWithNotify(i+a,j+b,k+c, Block.planks.blockID);
          }
    }

    It looks like a lot, but it isnt the same. This time, it generates 5 pillars in (-3 a, -2 :cool.gif:, (-3 a, -1 :cool.gif:, (-3 a, 0 :cool.gif: and so on until it reaches (-3 a, 2 :cool.gif:. It also does the same on (3 a, from -2 b to 2 :cool.gif:. Now bleding this code with the rest, we get this:
    for(int a = -3; a<4; a++)
    {
    	for(int b = -3; b<4; b++)
    	{
    		if((c==-3||c==3)&&(a>-3&&a<3))
    		{
          		for(int b=0; b<4; b++)
          		{
                	world.setBlockWithNotify(i+a,j+b,k+c, Block.planks.blockID);
          		}
    		}
    		
    		if((a==-3||a==3)&&(c>-3&&c<3))
    		{
         		for(int b=0; b<4; b++)
          		{
                	world.setBlockWithNotify(i+a,j+b,k+c, Block.planks.blockID);
          		}
    		}
    
    		if((a==-3&&c==-3)||(a==-3&&c==+3)||(a==+3&&c==-3)||(a==+3&&c==+3))
    		{	
    			for(int b=0; b<4; b++)
    			{
    				world.setBlockWithNotify(i+a,j+b,k+c, Block.wood.blockID);
    			}		
    		world.setBlockWithNotify(i+a,j-1,k+c, Block.planks.blockID);
    	}
    }

    Wow this code is becoming a monster! It seems like a not, but this house has no roof, or doors! The roof is easy peasy. We only need to generate a new 7x7 square. Only this time it will be made of wood and it will be above. Lets put this code right below the last line of our code, still inside the loop, out of the conditions:
    world.setBlockWithNotify(i+a,j-1,k+c, Block.planks.blockID);
    world.setBlockWithNotify(i+a,j+4,k+c, Block.wood.blockID);

    There. Roof done. This generates the same square as the line above, only it does on "x" axis +4 and it's made out of wood instead of -1 planks.
    Last but not least, we need doors! Let's do 2 doors to 2 walls:
    if((a==-3||a==3)&&(c>-3&&c<3))
    		{
         		for(int b=0; b<4; b++)
                        {
                            if((a==-3||a==3)&&c==0&&b==1)
                            {
                            world.setBlockAndMetadataWithNotify(i+a,j+b,k+c, Block.doorWood.blockID, 8);
                            }
                            if((a==-3||a==3)&&c==0&&b==0)
                            {
                                world.setBlockAndMetadataWithNotify(i+a,j,k+c, Block.doorWood.blockID, 0);
                            }
                            else if(!((a==-3||a==3)&&c==0&&(b==1||b==0)))
                            {
                            world.setBlockWithNotify(i+a,j+b,k+c, Block.planks.blockID);
                            }
                        }
    		}

    Now THAT's freaky. But have no fear, young (or... "experienced") modders! We only applied our checking coordinates techniques to 2 sides.
    Let's break the code down:
    if((a==-3||a==3)&&c==0&&b==1)
                            {
                            world.setBlockAndMetadataWithNotify(i+a,j+b,k+c, Block.doorWood.blockID, 8);
                            }

    This runs when a is -3 and a is 3 in c 0 and b 1. Why so much specification? It's because a door is not one block. It's 2 blocks. The bootom block is door metadata 0, and the upper block is door metadata 8. So we set the generation of a upper door on b1, and...
    if((a==-3||a==3)&&c==0&&b==0)
                            {
                                world.setBlockAndMetadataWithNotify(i+a,j,k+c, Block.doorWood.blockID, 0);
                            }

    ... and we set the generation of the bottom door on b0. Note that this will run on both sides of a (-3 and 3).
    Then we add a else if condition.
    else if(!((a==-3||a==3)&&c==0&&(b==1||b==0)))
    It will only run when it's not one of the if conditions above AND when the a is -3 or 3, when the c is 0 and when the b is 1 or 0. This condition prevents the other conditions of overlapping them selves and bugging.
    So we can end this cake with icing on top, lets add a glowstone on top!
    world.setBlockWithNotify(i+a,j+4,k+c, Block.wood.blockID);
                    if(a==0&&c==0)
                    {
                        world.setBlockWithNotify(i+a,j+4,k+c, Block.glowStone.blockID);
                    }

    Meaning it will create a glowstone on a 0 and c 0 and b 4.

    This is the complete BlockGenStructure file:

    // Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://www.kpdus.com/jad.html
    // Decompiler options: packimports(3) braces deadcode 
    package net.minecraft.src;
    
    import java.util.Random;
    
    public class BlockGenStructure extends Block
    {
        protected BlockGenStructure(int i, int j)
        {
            super(i, Material.wood);
            blockIndexInTexture = j;
        }
        @Override
        public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer)
        {
            world.setBlockWithNotify(i,j,k, 0);
            for(int i1=-3; i1<4; i1++)
            {
                //System.out.println(i1);
                for(int k1=-3;k1<4; k1++)
                {
                //System.out.println(k1);
                world.setBlockWithNotify(i+i1,j-1,k+k1, Block.planks.blockID);
                    if((i1==-3&&k1==-3)||(i1==-3&&k1==+3)||(i1==+3&&k1==-3)||(i1==+3&&k1==+3))
                    {
                        for(int j1=0; j1<4; j1++)
                        {
                            world.setBlockWithNotify(i+i1,j+j1,k+k1, Block.wood.blockID);
                        }
                    }
                    if((i1==-3||i1==3)&&(k1>-3&&k1<3))
                    {
                        for(int j1=0; j1<4; j1++)
                        {
                            if((i1==-3||i1==3)&&k1==0&&j1==1)
                            {
                            world.setBlockAndMetadataWithNotify(i+i1,j+j1,k+k1, Block.doorWood.blockID, 8);
                            }
                            if((i1==-3||i1==3)&&k1==0&&j1==0)
                            {
                                world.setBlockAndMetadataWithNotify(i+i1,j,k+k1, Block.doorWood.blockID, 0);
                            }
                            else if(!((i1==-3||i1==3)&&k1==0&&(j1==1||j1==0)))
                            {
                            world.setBlockWithNotify(i+i1,j+j1,k+k1, Block.planks.blockID);
                            }
                        }  
                    }
                    if((k1==-3||k1==3)&&(i1>-3&&i1<3))
                    {
                        for(int j1=0; j1<4; j1++)
                        {
                            world.setBlockWithNotify(i+i1,j+j1,k+k1, Block.planks.blockID);
                        }
                    }
                    world.setBlockWithNotify(i+i1,j+4,k+k1, Block.wood.blockID);
                    if(i1==0&&k1==0)
                    {
                        world.setBlockWithNotify(i+i1,j+4,k+k1, Block.glowStone.blockID);
                    }
                }
            }
            return true;
        }
        @Override
        public int idDropped(int i, Random random, int j)
        {
            return mod_Structure.genStructure.blockID;
        }
    
    }

    I've added a line to delete the block genStructures when clicked
    world.setBlockWithNotify(i,j,k, 0);

    And here is our silly mod_Structures file:

    package net.minecraft.src;
    
    
    /**
     *
     * @author Jotamota
     */
    public class mod_Structures extends BaseMod
    {
        //DECLARATION LINES HERE
        public static final Block genStructure = (new BlockGenStructure(1615, 28)).setHardness(3F).setResistance(5F).setBlockName("genStructure");
        
        @Override
        public void load()
        {
            //MOD COMMANDS GOES HERE
            genStructure.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/Blocks/genStructure.png");
    	ModLoader.RegisterBlock(genStructure);
    	ModLoader.AddName(genStructure, "House-In-A-Block");
            ModLoader.AddShapelessRecipe(new ItemStack(genStructure, 1), new Object[] {Block.dirt, Block.sand});
            }
        
        @Override
        public String getVersion()
        {
              return "0.1";
        }
        
        //OR HERE :smile.gif:
    }

    It's all done! You get the block by mixing dirt with sand (for testing purposes) and when you right click it, BAM. A house is spawned.
    Hope you liked this tutorial! As always, if you get any errors, post them on this thread and I'll reply as soon as possible. If you liked this tutorial hit the +1 Button for support! If you want more tutorials post below what kind of tutorial you want. See you later!

    More tutorials on their way!!!

    Forge Tutorials!!!

    Tutorial I:How to index infinite texture and how to smelt metadata items! (like ItemDye!!!)
    Difficulty: Begginer


    There is not much to add with Forge. This is a COMPLEMENTORY tutorial, meaning that this only adds things. You should start looking at ModLoader's tutorial I, and then come back here :smile.gif:.

    Already back, are we? Lets get into it!

    Among other things, what makes Forge a supreme modding tool is it's "Hooks" for metadata and "infinite texture indexing". A hook is when a mod modifys a base file (a original game code file) so that people don't have to. This way, you can call for the hook, instead of scrambling the original files. Much like a middle man that stops both from getting to know eachother.

    Anyways, Forge adds several hooks for metadata. Without Forge, you cannot make a furnace use cocoa beans. This shall be our first lesson.

    Again, you should start reading the ModLoader's TUTORIAL I and THEN come back here. We are using the finished code files once used before.

    Here's the mod_ItemMetadata:

    package net.minecraft.src;
    
    import java.util.Random;
    import net.minecraft.client.Minecraft;
    
    /**
     *
     * @author Jotamota
     */
    public class mod_ItemMetadata extends BaseMod
    {
        //DECLARATION LINES HERE
        public static Item noUse = new ItemNoUse(1694).setItemName("noUse");
        public static int itemIcon1 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon1.png");
        public static int itemIcon2 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon2.png");
        public static int itemIcon3 = ModLoader.addOverride("/gui/items.png", "/MetadataIcons/icon3.png");
        
        @Override
        public void load()
        {
            //MOD COMMANDS GOES HERE
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 0), "Item 1 Name");
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 1), "Item 2 Name");
            
            ModLoader.AddRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 0), new Object[]
            {
               "XXX","XYX","XXX", Character.valueOf('X'), Item.stick, Character.valueOf('Y'), Block.planks 
            });
            ModLoader.AddShapelessRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 1), new Object[] {Block.dirt, new ItemStack(mod_ItemMetadata.noUse, 1, 0)});
            ModLoader.AddSmelting(Block.dirt.blockID, new ItemStack(mod_ItemMetadata.noUse, 1, 0));
        }
        
        @Override
        public String getVersion()
        {
              return "0.1";
        }
        
        //OR HERE :smile.gif:
    }

    ... and here's ItemNoUse:

    package net.minecraft.src;
    
    /**
     *
     * @author Jotamota
     */
    public class ItemNoUse extends Item
    {
        public ItemNoUse(int id)
        {
            super(id);
            setHasSubtypes(true);
            setMaxDamage(0);
        }
        
        private String[] names = new String[]{"item1", "item2"};
      //private String[] names = new String[]{"  0  ", "  1  "};
        
        @Override
        public String getItemNameIS(ItemStack itemstack)
        {
            return names[itemstack.getItemDamage()];
        }
        
        @Override
        public int getIconFromDamage(int i)
        {
            if(i==0){
                setMaxStackSize(1);
                return mod_ItemMetadata.itemIcon1;}
            if(i==1)
            {            
                //setContainerItem(Item.bucketEmpty);    
                return mod_ItemMetadata.itemIcon2;
            }
            else{
                setMaxStackSize(64);
                return mod_ItemMetadata.itemIcon3;}
            
        }
            
        
    }

    Now, first of all, lets make infinite indexing of texture. Instead of overriding the original textures with ModLoader, we can preload a new texture and index items and blocks to that new texture. Much like creating a new terrain.png with 256 new icons to go.

    To use Forge's methods, we need to import the whole segment of Forge's code. Java created this line to import sources. It's a line that goes BEFORE the public class and it drags all the code related to so our code can handle it. One example of it it's the:
    import Java.util.Random;

    If we want to create Random variables on our code, we must import the java code that MAKES random. In our case, we will import forge's code. It's a folder called "forge" inside the folder SRC, that is inside the folder MINECRAFT, and that is inside the folder NET.
    This is why our code must be like this:
    import net.minecraft.src.forge.*;

    This imports all the code inside the forge folder (hence the "*"). If you wanted only import ONE file, you could do import net.minecraft.src.forge.IBonemealHandler.
    Anyways, we are getting a little diverted, lets get back on track! This is the mod_ItemMetadata after we import forge's code.
    package net.minecraft.src;
    
    import net.minecraft.src.forge.*;
    
    /**
     * @author Jotamota
     */
    public class mod_ItemMetadata extends BaseMod

    Now before we can use the new texture files, we need to import it, so that forge can LOAD it before we can USE it. We can do it by using the method preloadTexture from MinecraftForgeClient. Main methods that Forge uses are located either on MinecraftForge.java or in MinecraftForgeClient.java. If you want to play around with new methods, you should look into these. Forge has no javadoc ("documentation" that explains the java methods) but it is all written in the code as commenteries.
    To use the preloadTexture we must call the main file (MinecraftForgeClient) and access it by putting a dot in it.
    MinecraftForgeClient.preloadTexture();

    If you run this line, you will get a error, because preloadTexture requires a String to run. It's the string that tells the path so that the code can find the texture file. Just like the path from addOverride, we add the path to our texture file here.
    @Override
        public void load()
        {
            //MOD COMMANDS GOES HERE
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 0), "Item 1 Name");
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 1), "Item 2 Name");
            
            ModLoader.AddRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 0), new Object[]
            {
               "XXX","XYX","XXX", Character.valueOf('X'), Item.stick, Character.valueOf('Y'), Block.planks 
            });
            ModLoader.AddShapelessRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 1), new Object[] {Block.dirt, new ItemStack(mod_ItemMetadata.noUse, 1, 0)});
            ModLoader.AddSmelting(Block.dirt.blockID, new ItemStack(mod_ItemMetadata.noUse, 1, 0));
    		
    		MinecraftForgeClient.preloadTexture("/MetadataIcons/items.png");
        }

    Now we can use this items.png. The name of the file does NOT matter, as long as you name it the same as it's in code. I'm putting the items.png file inside our new folder (already created) MetadataIcons.
    Now, let's delete the override functions on the declaration space. The deal about Forge is that it does NOT override the texture. This means that it doesn't "invades" Minecraft code and "imposes" a new texture to be accepted by the default texture file. It presents a "brother" that lives independently. We have our texture file ready, now let's go to ItemNoUse.java!
    package net.minecraft.src;
    
    /**
     *
     * @author Jotamota
     */
    public class ItemNoUse extends Item
    {

    Since we are using forge's code, we need to import it again. We must import forge's code to each file that uses forge. Lets add the same line into the import space (after package, before public class):
    package net.minecraft.src;
    import net.minecraft.src.forge.*;
    /**
     * @author Jotamota
     */

    We must implement the class. Implementing a new class means it inherits all of the implemented class functions, or none. When we extend a class, we can call it a "son". When we implement, we call it a "brother". The difference is: the "son" class can only have one father. The "brother" can have many many brothers. We can only extend one class to be a descendent but we can implement many classes to be alike.
    Being sad, we must implement the forge's code ITextureProvider. It's a file code that makes the code use the new texture file instead of the old one. We implement classes after extending them or after declaring them as public classes, like this:
    package net.minecraft.src;
    
    import net.minecraft.src.forge.*;
    /**
     *
     * @author Jotamota
     */
    public class ItemNoUse extends Item implements ITextureProvider

    Since we implemented it, if we need to add the function that ITextureProvider uses, or the game will crash. It's the function getTextureFile that is required, needed, priority, for the code to run when implementing ITextureProvider.
    Lets add the function shall we?
    public ItemNoUse(int id)
        {
            super(id);
            setHasSubtypes(true);
            setMaxDamage(0);
        }
    	@Override
    	public String getTextureFile()
    	{
    		return "/MetadataIcons/items.png";
    	}

    Again, we want it public (so other scripts can access it, like the Forge code that will replace the original items.png by this one) and it is a String function. Meaning we need to return a String. The path to find the texture. It must be the same path that we declared to preload the Texture. We override the function so it denies it's implemented function. It "replaces" the function's "getTextureFile" from ITextureProvider insides with this one.
    Now that we preloaded the Texture and we implemented it, we can use it. Delete the whole function getIconFromDamage. We will rewrite it!
    @Override
        public int getIconFromDamage(int i)
        {
            if(i==0){
                setMaxStackSize(1);
                return ;
            if(i==1)
            {            
                return ;
            }
            else{
                return ;}
            
        }

    Now, instead of returning the mod_ItemMetadata icons, we will just add a number between 0 and 255.
    We can do it to return 0 for the first damage item, 1 for the second and 2 for the rest.
    @Override
        public int getIconFromDamage(int i)
        {
            if(i==0)
    		{
                return 0;
    		}
            if(i==1)
            {            
                return 1;
            }
            else
    		{
                return 2;
    		}
            
        }

    Now, we need to create a 256x256 png file called items.png and located inside MetadataIcons. I've made this file as an example:


    The first item will return the value 0, wich represents the first icon from items.png (remembering it starts in 0). The second returns the second icon (space 1) and all the other items will return the icon 2.

    This concludes the texture indexing with Forge.

    Now let's temper with metadata furnaces, shall we?

    Back to mod_ItemMetadata, let's replace the AddSmelting line with another one:

    @Override
        public void load()
        {
            //MOD COMMANDS GOES HERE
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 0), "Item 1 Name");
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 1), "Item 2 Name");
            
            ModLoader.AddRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 0), new Object[]
            {
               "XXX","XYX","XXX", Character.valueOf('X'), Item.stick, Character.valueOf('Y'), Block.planks 
            });
            ModLoader.AddShapelessRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 1), new Object[] {Block.dirt, new ItemStack(mod_ItemMetadata.noUse, 1, 0)});
            ModLoader.AddSmelting(Block.dirt.blockID, new ItemStack(mod_ItemMetadata.noUse, 1, 0));
    		
    		MinecraftForgeClient.preloadTexture("/MetadataIcons/items.png");
        }

    ModLoader uses the method AddSmelting from the file ModLoader.java, but Forge uses the method smelting from the game's file FurnaceRecipes. This methods (you can look it up on FurnaceRecipes.java) returns a new recipeBase that creates a new FurnaceRecipes. We now use the method inside that new FurnaceRecipe called addSmelting:
    FurnaceRecipes.smelting().addSmelting()); 

    If you go into FurnaceRecipes, you will find these two functions:

    public void addSmelting(int i, ItemStack itemstack)
        {
            smeltingList.put(Integer.valueOf(i), itemstack);
        }
    
        /* FORGE: Add a metadata-sensitive furnace recipe.
         */
        public void addSmelting(int i, int meta, ItemStack itemstack)
        {
            metaSmeltingList.put(Arrays.asList(i,meta), itemstack);
        }

    They have the same name, but that is no problem, since each one recieves different inputs. One uses 2 inputs, and the other one, created by Forge, uses 3 inputs. That means that if you apply 2 inputs to that method, you will call the addSmelting(int i, ItemStack itemstack). If you use 3, it'll call the other one. We can use both, but for now let's use the metadata-sensitive version. It recieves a int i, a int meta, and a ItemStack. The first int is the item/block's id. The second is the item/block's metadata. The third one is the RESULT from the smelting.
    FurnaceRecipes.smelting().addSmelting(mod_ItemMetadata.noUse.shiftedIndex, 0, new ItemStack(mod_ItemMetadata.noUse.shiftedIndex, 1, 1));

    Now when we smelt the itemMetadata 0 we will make the itemMetadata 1.

    And that concludes the first Tutorial for Forge. Here are full files for comparison and learning. Remember, copying this code won't take out far. But if you understand it, your mind is the limit.
    mod_ItemMetadata:

    package net.minecraft.src;
    
    import net.minecraft.src.forge.*;
    
    /**
     *
     * @author Jotamota
     */
    public class mod_ItemMetadata extends BaseMod
    {
        //DECLARATION LINES HERE
        public static Item noUse = new ItemNoUse(1694).setItemName("noUse");
        
        @Override
        public void load()
        {
            //MOD COMMANDS GOES HERE
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 0), "Item 1 Name");
            ModLoader.AddName(new ItemStack(mod_ItemMetadata.noUse, 1, 1), "Item 2 Name");
            
            ModLoader.AddRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 0), new Object[]
            {
               "XXX","XYX","XXX", Character.valueOf('X'), Item.stick, Character.valueOf('Y'), Block.planks 
            });
            ModLoader.AddShapelessRecipe(new ItemStack(mod_ItemMetadata.noUse, 1, 1), new Object[] {Block.dirt, new ItemStack(mod_ItemMetadata.noUse, 1, 0)});
            ModLoader.AddSmelting(Block.dirt.blockID, new ItemStack(mod_ItemMetadata.noUse, 1, 0));
    		
    		MinecraftForgeClient.preloadTexture("/MetadataIcons/items.png");
    		
    				FurnaceRecipes.smelting().addSmelting(mod_ItemMetadata.noUse.shiftedIndex, 0, new ItemStack(mod_ItemMetadata.noUse.shiftedIndex, 1, 1));
        }
        
        @Override
        public String getVersion()
        {
              return "0.1";
        }
        
        //OR HERE :smile.gif:
    }


    ItemNoUse:

    package net.minecraft.src;
    
    import net.minecraft.src.forge.*;
    /**
     *
     * @author Jotamota
     */
    public class ItemNoUse extends Item implements ITextureProvider
    {
        public ItemNoUse(int id)
        {
            super(id);
            setHasSubtypes(true);
            setMaxDamage(0);
        }
    	@Override
    	public String getTextureFile()
    	{
    		return "/MetadataIcons/items.png";
    	}
    	
    	
        private String[] names = new String[]{"item1", "item2"};
      //private String[] names = new String[]{"  0  ", "  1  "};
        
        @Override
        public String getItemNameIS(ItemStack itemstack)
        {
            return names[itemstack.getItemDamage()];
        }
        
        @Override
        public int getIconFromDamage(int i)
        {
            if(i==0)
    		{
                return 0;
    		}
            if(i==1)
            {            
                return 1;
            }
            else
    		{
                return 2;
    		}
            
        }
            
        
    }


    I hope you enjoyed. If you have any error, post them here and I'll try to help. If you want a new tutorial about something you don't understand well, post your idea here too! If you liked this tutorial hit the +1 greenie over there, since it bumps my reputation. Stay tuned for more!

    Tutorial II:How to multi-texture a block with Forge's infinite indexing of sprites!
    Difficulty: Begginer

    Hello guys again! This is Jotamota, your friendly Modder, for one more Tutorial. This time, we will cover up how to multi texture a block (like a workbench, with one texture for each side). Note that this isnt a multi-rendering tutorial (custom shaping of blocks), we will only multi-texture it.

    First of all, read Forge's Tutorial I. That tutorial explains how to use the infinite indexing feature of Forge. I will use it in this tutorial as well, but I won't explain it as clear as I did on the last Tutorial.

    So, we need a fresh mod_XXX file. Here's the ModLoader 1.0.0 + Forge's API mod_XXX layout:
    package net.minecraft.src;
    
    import net.minecraft.src.forge.*;
    
    /**
     *
     * @author Jotamota
     */
    public class mod_NewBlock extends BaseMod
    {
        //DECLARATION LINES HERE
        
        @Override
        public void load()
        {
            
        }
        
        @Override
        public String getVersion()
        {
              return "0.1";
        }
        
        //OR HERE :smile.gif:
    }


    We have the public void load(), the getVersion function, and our class mod_NewBlock. As in any block, we must declare it, register it, and build it. To declare a block, we apply the declaring line, similar to declaring a Item, on our Declaration Space:
    public static final Block multiTexture = new BlockTexture(IdNumberGoesHere, BlockIndexInTextureGoesHere).setBlockName("nameGoesHere");

    Lets break it down, shall we?
    public static final Block multiTexture declares a new variable (type of Block) that is public (can be called by other scripts), final(cannot be extended), and static (cannot be changed). Then we apply a new value to this variable:
    new BlockTexture(IdNumberGoesHere, BlockIndexInTextureGoesHere).setBlockName("nameGoesHere");

    This piece creates a new BlockTexture Block, with the constructor BlockTexture(int i, int j), wich we will create in a few minutes. As I mentioned before, a constructor is a function that recieves inputs and create a class. This constructor will create a new Block, add it a NumberID and a BlockIndexInTexture. The numberID is what defines the block. We will use it many many times while on this tutorial. The BlockIndexInTexture is the number that says to the code where is the texture that we are going to use for our Block.
    The last part of the code, ".setBlockName("nameGoesHere")", simply tells the game it's name to make sure it isnt the same block. If you put the same name that other block/item your new block will have the old block's icon and name. This is a common bug among modders.

    Let's put the idNumber as 230 (it has to be over around 130 and under 256) and the indexTexture 0 for now:

    public static final Block multiTexture = new BlockTexture(230, 0).setBlockName("nameGoesHere");


    Good. Now we need to declare and set the block's name on our public void load() function:

    @Override
        public void load()
        {
            ModLoader.RegisterBlock(multiTexture);
    	ModLoader.AddName(multiTexture, "Multi-Textured Block");
        }


    To do so, we use ModLoader features. ModLoader uses the function RegisterBlock(Block block) to add our block to the game's original block's list. This way, our block is added to the game.
    ModLoader has one function called AddName that adds a string name to a variable that is shown in-game. That is what we use to add names, as we did on Tutorial I for Metadata-Items.

    Now, last but not least, we need to preload the Texture that we are going to use for our block. We now use a Forge's feature, the preloadTexture:

    @Override
        public void load()
        {
            ModLoader.RegisterBlock(multiTexture);
    	ModLoader.AddName(multiTexture, "Multi-Textured Block");
    	MinecraftForgeClient.preloadTexture("/NewTextures/terrain.png");
        }


    This loads the texture before the game run's so when the game calls the new texture it won't crash due to missing texture. Create our path inside MCP/bin/minecraft/, meaning that "/terrain.png" leads to MCP/bin/minecraft/terrain.png. Our new terrain file should be on /MCP/bin/minecraft/NewTextures/ with the name of terrain.png

    Now, we must create our new BlockTexture.java. For a block file. THis is the simpliest of simple layouts you will ever find:
    package net.minecraft.src;
    import java.util.Random;
    
    public class BlockXXX extends Block
    {
    	protected BlockXXX(int i, int j)
    	{
    		super(i, j, Material.rock);
    	}
    	
    	public int idDropped(int i, Random random)
    	{
    		return mod_NewBlock.xxx.blockID;
    	}
    	
    }


    Now, let's see what do we do here:
    We first import the package of the code, so the code can load ALL the files inside net.minecraft.src.
    Then we import java's Random utilitie so we can use the Random generator on our code.
    And then we declare the class and the constructor. Our constructor recieves 2 inputs, but we can always modify it! What is important is the super function.
    A super function (on our case) bumps the code to a constructor on the extended class. On our case, it uses the int i and j from our constructor and it applies to Block(int i,int j, Material material) constructor. This means it creates a new Block.java.
    The idDropped just tells what is the ID that the Block will drop when broken. Note that the "i" is the block's metadata.

    Now, let's assemble our OWN block file:
    1)We want it to run on a constructor of 2 integers, and we want it to drop the same block.

    package net.minecraft.src;
    import java.util.Random;
    
    public class BlockTexture extends Block
    {
    	protected BlockTexture(int i, int j)
    	{
    		super(i, j, Material.rock);
    	}
    	
    	public int idDropped(int i, Random random)
    	{
    		return mod_NewBlock.multiTexture.blockID;
    	}
    	
    }


    Easy peasy no?

    Now, we will get into the multiTexturing. First, all blocks have the function getBlockTextureFromSide and getBlockTextureFromSideAndMetadata. These two function, when not defined, are defaultly defined by Block.java, rendering the block on one texture independently from it's metadata. Since we are not messing with metadata, we will use the getBlockTextureFromSide:

    @Override
         public int getBlockTextureFromSide(int i)
        {
            
        }

    This is our function. The int "i" represents the side, being 0 the bottom of the block, and 1 the top of it. 2,3,4 and 5 are it's sides.

    Before we construct the getBlockTextureFromSide, we must implement ITextureProvider from Forge that possibilitate us from using our OWN textures to render the block!

    I already taught this on Forge's Tutorial I, so I'll just do it here. If you wanna fully understand why do I do it, go uppost and check that out!

    We implement the ITextureProvider after extending:
    public class BlockTexture extends Block implements ITextureProvider

    We import Forge's code on import lines:
    package net.minecraft.src;
    import java.util.Random;
    import net.minecraft.src.forge.*;

    And we set the path so the code can find the texture:
    	public String getTextureFile()
    	{
    		return "/NewTextures/terrain.png"
    	}

    Now back to getTextureFromSide:
    package net.minecraft.src;
    import java.util.Random;
    import net.minecraft.src.forge.*;
    
    public class BlockTexture extends Block
    {
    	protected BlockTexture(int i, int j)
    	{
    		super(i, j, Material.wood);
    	}
    	
    	public int idDropped(int i, Random random)
    	{
    		return mod_NewBlock.multiTexture.blockID;
    	}
    	@Override
         	public int getBlockTextureFromSide(int i)
        	{
            
        	}
    	public String getTextureFile()
    	{
    		return "/NewTextures/terrain.png"
    	}
    	
    }

    We need it to return a different texture from each side. Instead of doing conditions to each side and putting else conditions to the other sides, we can use Java's switch command. It is much like a if, only code-economic and runs smoother and faster than a lot of cogged-up if conditions. This is how switch works:
    	switch(metadata)
    	{
    		case 1: System.out.println("metadata is equal to 1.");
    			break;
    		case 0: System.out.println("metadata is equal to 0.");
    			break;
    		default: System.out.println("metadata is different than 1 and 0.");
    			break;
    	}

    This makes the code switches between the values of the variable "metadata". In the case it's 1, it will print that metadata equals 1. Then the code breaks so it resets the switch.
    Default case runs if metadata's value isnt covered by any case lines.
    Now, in our code, we will run it on a "int" function. Int functions return a number. This way, we don't need the "break" line since the code will already stop when returned a value. This is how we use it:
    	@Override
         	public int getBlockTextureFromSide(int i)
        	{
            	switch(i)
    		{
    			case 0: return blockIndexInTexture;
    			case 1: return 4;
    			default: return 15;
    		}
        	}

    This switches around the side of the block, and it returns a number. What number is that, you ask? It's the blockIndexInTexture. The number that tells wich 16x16 sprite to use on terrain.png. Now we get our own terrain.png:


    All the new terrain.png or items.png files MUST be 256x256 png files. I've made this one with random localization of the sprites. The first one we see is the sprite number 0 (we count it from left to right and from up to down), the second is the sprite number 4, and the third one is ONE SPRITE BEFORE THE SECOND LINE!!!(since there are 16 sprites each line, the first sprite will be sprite 0, the first sprite on the second line 16, on third line 32, and on and on)This way, it is one sprite before sprite 16, therefore, sprite 15.
    You can order it where you want, as long as you tell the code where is it!
    Last but not least, we must define the blockIndexInTexture. That variable is defined on our super(int i, int j, Material.wood). We declared it on mod_NewBlock:

    package net.minecraft.src;
    
    import net.minecraft.src.forge.*;
    
    /**
     *
     * @author Jotamota
     */
    public class mod_NewBlock extends BaseMod
    {
        //DECLARATION LINES HERE
        public static final Block multiTexture = new BlockTexture(130, 0).setBlockName("nameGoesHere");
    
        @Override
        public void load()
        {
            ModLoader.RegisterBlock(multiTexture);
    	ModLoader.AddName(multiTexture, "Multi-Textured Block");
    	MinecraftForgeClient.preloadTexture("/NewTextures/terrain.png");
        }
        
        @Override
        public String getVersion()
        {
              return "0.1";
        }
        
        //OR HERE :smile.gif:
    }

    Last but not least, we need to find a way to get that block in-game!
    Let's use ModLoader.AddShapelessRecipe!
    ModLoader.AddShapelessRecipe(new ItemStack(mod_NewBlock.multiTexture, 64), new Object []{
    		Block.dirt, Block.dirt, Block.dirt, Block.dirt
    		});


    The code is done. Your block should be rendered differently on each sides, and all code should run smoothly. Here are ready files:
    mod_NewBlock:

    package net.minecraft.src;
    
    import net.minecraft.src.forge.*;
    
    /**
     *
     * @author Jotamota
     */
    public class mod_NewBlock extends BaseMod
    {
        //DECLARATION LINES HERE
        public static final Block multiTexture = new BlockTexture(130, 0).setBlockName("nameGoesHere");
    
        @Override
        public void load()
        {
            ModLoader.RegisterBlock(multiTexture);
    	ModLoader.AddName(multiTexture, "Multi-Textured Block");
    	MinecraftForgeClient.preloadTexture("/NewTextures/terrain.png");
    	ModLoader.AddShapelessRecipe(new ItemStack(mod_NewBlock.multiTexture, 64), new Object []{
    	Block.dirt, Block.dirt, Block.dirt, Block.dirt
    	});
        }
        
        @Override
        public String getVersion()
        {
              return "0.1";
        }
        
        //OR HERE :smile.gif:
    }

    BlockTexture:

    package net.minecraft.src;
    import java.util.Random;
    import net.minecraft.src.forge.*;
    
    public class BlockTexture extends Block
    {
    	protected BlockTexture(int i, int j)
    	{
    		super(i, j, Material.wood);
    	}
    	
    	public int idDropped(int i, Random random)
    	{
    		return mod_NewBlock.multiTexture.blockID;
    	}
    	@Override
         	public int getBlockTextureFromSide(int i)
        	{
            	switch(i)
    		{
    			case 0: return blockIndexInTexture;
    			case 1: return 4;
    			default: return 15;
    		}
        	}
    	public String getTextureFile()
    	{
    		return "/NewTextures/terrain.png"
    	}
    	
    }


    And this concludes this tutorial. Hope you all liked and learned a lot by it, although it's still a simple tutorial. As always, don't hesitate posting any recompiling errors that you find on this thread, as well as new tutorial requests, that I'll be happy to make if I'm capable.
    If you liked this tutorial, hit the +1 greenie over there!
    See you in more tutorials!

    More Tutorials to come!!!