Modding: Custom crop part 3: Rendering and drops

In this tutorial I will show you how to render the crop and how to change the drops it gives. In part 2 we ended with this Block file.


package Tutorial.common;

import java.util.Random;

import net.minecraft.src.Block;
import net.minecraft.src.BlockFlower;
import net.minecraft.src.CreativeTabs;
import net.minecraft.src.World;

public class BlockCropTutorial extends BlockFlower
{
protected BlockCropTutorial(int par1, int par2)
    {
        super(par1, par2);
        blockIndexInTexture = par2;
        setTickRandomly(true);
        float f = 0.5F;
        setBlockBounds(0.5F – f, 0.0F, 0.5F – f, 0.5F + f, 0.25F, 0.5F + f);
        this.setCreativeTab((CreativeTabs)null);
        this.disableStats();
        this.setRequiresSelfNotify();
    }

protected boolean canThisPlantGrowOnThisBlockID(int par1)
    {
        return par1 == Block.grass.blockID;
    }

public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    {
        super.updateTick(par1World, par2, par3, par4, par5Random);

        if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9)
        {
            int i = par1World.getBlockMetadata(par2, par3, par4);

            if (i < 2)
            {
                float f = getGrowthRate(par1World, par2, par3, par4);

                if (par5Random.nextInt((int)(25F / f) + 1) == 0)
                {
                    i++;
                    par1World.setBlockMetadataWithNotify(par2, par3, par4, i);
                }
            }
        }
    }

private float getGrowthRate(World par1World, int par2, int par3, int par4)
    {
        float f = 1.0F;
        int i = par1World.getBlockId(par2, par3, par4 – 1);
        int j = par1World.getBlockId(par2, par3, par4 + 1);
        int k = par1World.getBlockId(par2 – 1, par3, par4);
        int l = par1World.getBlockId(par2 + 1, par3, par4);
        int i1 = par1World.getBlockId(par2 – 1, par3, par4 – 1);
        int j1 = par1World.getBlockId(par2 + 1, par3, par4 – 1);
        int k1 = par1World.getBlockId(par2 + 1, par3, par4 + 1);
        int l1 = par1World.getBlockId(par2 – 1, par3, par4 + 1);
        boolean flag = k == blockID || l == blockID;
        boolean flag1 = i == blockID || j == blockID;
        boolean flag2 = i1 == blockID || j1 == blockID || k1 == blockID || l1 == blockID;

        for (int i2 = par2 – 1; i2 <= par2 + 1; i2++)
        {
            for (int j2 = par4 – 1; j2 <= par4 + 1; j2++)
            {
                int k2 = par1World.getBlockId(i2, par3 – 1, j2);
                float f1 = 0.0F;

                if (k2 == Block.grass.blockID)
                {
                    f1 = 1.0F;

                    if (par1World.getBlockMetadata(i2, par3 – 1, j2) > 0)
                    {
                        f1 = 3F;
                    }
                }

                if (i2 != par2 || j2 != par4)
                {
                    f1 /= 4F;
                }

                f += f1;
            }
        }

        if (flag2 || flag && flag1)
        {
            f /= 2.0F;
        }

        return f;
    }
}


The first method I will add is this one.


public String getTextureFile()
    {
            return “/TutTextures.png”;
    }


If you are unfamilliar with this method I suggest reading through the normal Block tutorial.

Another method that you might want is this one.


public int getRenderType()
    {
        return 6;
    }


This method will make sure that the block is shown as a crop.
Now to make sure that this block gets the right textures you will have to add this method.


public int getBlockTextureFromSideAndMetadata(int par1, int par2)
    {
switch(par2)
{
case 0:
return 2;
case 1:
return 3;
case 2:
return 4;
default:
return 0;
}
    }


par2 is the metadata of the block. The way it is coded right now there are 3 metadatas. 0 is the one it starts in and 2 is the last one. The number you return is the location on the sprite sheet.

This is all the code you need to make sure that the crop looks the way you want it to. To get the drops the way you want it you have to add these methods.


public int idDropped(int par1, Random par2Random, int par3)
    {
        if (par1 == 2)
        {
            return Tutorial.yourfood.shiftedIndex;
        }
        else
        {
            return 0;
        }
    }


par1 is this method is the metadata of the block. In this case it checks if the block has reached it’s final stage and it will drop the food we created in an earlier tutorial.
There are 2 more important methods that you will have to add. The first one is used to drop seeds.


public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7)
    {
        super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0);

        if (par1World.isRemote)
        {
            return;
        }

        int i = 3 + par7;

        for (int j = 0; j < i; j++)
        {
            if (par1World.rand.nextInt(5) == 0)
            {
                float f = 0.7F;
                float f1 = par1World.rand.nextFloat() * f + (1.0F – f) * 0.5F;
                float f2 = par1World.rand.nextFloat() * f + (1.0F – f) * 0.5F;
                float f3 = par1World.rand.nextFloat() * f + (1.0F – f) * 0.5F;
                EntityItem entityitem = new EntityItem(par1World, (float)par2 + f1, (float)par3 + f2, (float)par4 + f3, new ItemStack(Tutorial.cropseed));
                entityitem.delayBeforeCanPickup = 10;
                par1World.spawnEntityInWorld(entityitem);
            }
        }
    }


This method will drop items when the block is destroyed.
Most of the code in here is just used to randomize location and drop chance of the item. The only important item is the one starting with EntityItem. In there are several parameters. The last one is the itemstack that the block will drop when you destroy it. In this case it will be the seed that we are going to make in the next tutorial.

The second one is used to get the item/block that you will get in creative mode when you use the middle mouse button to click on the block. You should make this the seed that we are going to create in the next tutorial.


public int idPicked(World par1World, int par2, int par3, int par4)
    {
        return Tutorial.cropseed.shiftedIndex;
    }


The whole file should now look something like this.


package Tutorial.common;

import java.util.Random;

import net.minecraft.src.Block;
import net.minecraft.src.BlockFlower;
import net.minecraft.src.CreativeTabs;
import net.minecraft.src.EntityItem;
import net.minecraft.src.ItemStack;
import net.minecraft.src.World;

public class BlockCropTutorial extends BlockFlower
{
protected BlockCropTutorial(int par1, int par2)
    {
        super(par1, par2);
        blockIndexInTexture = par2;
        setTickRandomly(true);
        float f = 0.5F;
        setBlockBounds(0.5F – f, 0.0F, 0.5F – f, 0.5F + f, 0.25F, 0.5F + f);
        this.setCreativeTab((CreativeTabs)null);
        this.disableStats();
        this.setRequiresSelfNotify();
    }

public String getTextureFile()
    {
            return “/TutTextures.png”;
    }

public int getRenderType()
    {
        return 6;
    }

public int getBlockTextureFromSideAndMetadata(int par1, int par2)
    {
switch(par2)
{
case 0:
return 2;
case 1:
return 3;
case 2:
return 4;
default:
return 0;
}
    }

public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7)
    {
        super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0);

        if (par1World.isRemote)
        {
            return;
        }

        int i = 3 + par7;

        for (int j = 0; j < i; j++)
        {
            if (par1World.rand.nextInt(5) == 0)
            {
                float f = 0.7F;
                float f1 = par1World.rand.nextFloat() * f + (1.0F – f) * 0.5F;
                float f2 = par1World.rand.nextFloat() * f + (1.0F – f) * 0.5F;
                float f3 = par1World.rand.nextFloat() * f + (1.0F – f) * 0.5F;
                EntityItem entityitem = new EntityItem(par1World, (float)par2 + f1, (float)par3 + f2, (float)par4 + f3, new ItemStack(Tutorial.cropseed));
                entityitem.delayBeforeCanPickup = 10;
                par1World.spawnEntityInWorld(entityitem);
            }
        }
    }

    public int idDropped(int par1, Random par2Random, int par3)
    {
        if (par1 == 2)
        {
            return Tutorial.yourfood.shiftedIndex;
        }
        else
        {
            return -1;
        }
    }
    
    public int quantityDropped(Random par1Random)
    {
        return 1;
    }
    
    public int idPicked(World par1World, int par2, int par3, int par4)
    {
        return Tutorial.cropseed.shiftedIndex;
    }

protected boolean canThisPlantGrowOnThisBlockID(int par1)
    {
        return par1 == Block.grass.blockID;
    }

public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    {
        super.updateTick(par1World, par2, par3, par4, par5Random);

        if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9)
        {
            int i = par1World.getBlockMetadata(par2, par3, par4);

            if (i < 2)
            {
                float f = getGrowthRate(par1World, par2, par3, par4);

                if (par5Random.nextInt((int)(25F / f) + 1) == 0)
                {
                    i++;
                    par1World.setBlockMetadataWithNotify(par2, par3, par4, i);
                }
            }
        }
    }

private float getGrowthRate(World par1World, int par2, int par3, int par4)
    {
        float f = 1.0F;
        int i = par1World.getBlockId(par2, par3, par4 – 1);
        int j = par1World.getBlockId(par2, par3, par4 + 1);
        int k = par1World.getBlockId(par2 – 1, par3, par4);
        int l = par1World.getBlockId(par2 + 1, par3, par4);
        int i1 = par1World.getBlockId(par2 – 1, par3, par4 – 1);
        int j1 = par1World.getBlockId(par2 + 1, par3, par4 – 1);
        int k1 = par1World.getBlockId(par2 + 1, par3, par4 + 1);
        int l1 = par1World.getBlockId(par2 – 1, par3, par4 + 1);
        boolean flag = k == blockID || l == blockID;
        boolean flag1 = i == blockID || j == blockID;
        boolean flag2 = i1 == blockID || j1 == blockID || k1 == blockID || l1 == blockID;

        for (int i2 = par2 – 1; i2 <= par2 + 1; i2++)
        {
            for (int j2 = par4 – 1; j2 <= par4 + 1; j2++)
            {
                int k2 = par1World.getBlockId(i2, par3 – 1, j2);
                float f1 = 0.0F;

                if (k2 == Block.grass.blockID)
                {
                    f1 = 1.0F;

                    if (par1World.getBlockMetadata(i2, par3 – 1, j2) > 0)
                    {
                        f1 = 3F;
                    }
                }

                if (i2 != par2 || j2 != par4)
                {
                    f1 /= 4F;
                }

                f += f1;
            }
        }

        if (flag2 || flag && flag1)
        {
            f /= 2.0F;
        }

        return f;
    }
}


 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">