Here i will be posting tutorials based on users requests. I will try to use only mod-loader but i will edit base classes if necessary. Although the code postings may appear messy her if you paste them into eclipse or notepad they will look right. Note i try to describe almost all parts off the code in comments but parts that are to long to explain i explain at the bottom of the page
Here i will teach you how to get Setup for modding TO SETUP
1. download mcp from here http://mcp.ocean-lab...eleases#MCP_7.x
2. download modloader from here http://www.minecraft...s-mods-updated/
3. open minecraft .jar and copy all files from modloader into it
4. extract mcp zip folder into your modding folder
5. copy bin folder from .minecraft into jars folder in modding folder
6. run decompile.bat
7. install eclipse from here http://www.eclipse.org/downloads/
8. run eclipse and set workspace to mcpfolder/eclipse
9. start modding java files
TO EXPORT MODS
1. run recompile.bat
2. run reobfuscate.bat
3. go in to reobf.bat and copy all files into new zip folder
TO USE MOD
1. install modloader(remember to delete meta-inf)
2. place zip folder in mods folder(mod should work)(note! if you edit any existing minecraft files those must be placed directly in jar)
This should be the basic structure of all your mod_files
package net.minecraft.src;
public class mod_test extends BaseMod
{
//variables go up here
public String getVersion()// returns the version of your mod
{
return "anything";
}
public void load()//mod code goes in here
{
}
}
Here we will be adding a basic item that doesnt do anything but can be used in recipes
package net.minecraft.src;
public class mod_test extends BaseMod
{
public static final Item testItem = new Item(5000).setItemName("test");//creates an item with an id of 5000
public String getVersion()
{
return "anything";
}
public void load()
{
testItem.iconIndex = ModLoader.addOverride("/gui/items.png", "/test.png");//sets the image of the item to a image called test.png notice test.png should be placed in bin/minecraft if you are using mcp or just in src if you are using eclipse, when you use your mod for real it just gets fropped in the jar
testItem.setCreativeTab(CreativeTabs.tabMisc);
ModLoader.addName(testItem, "Test Item");
}
}
If you want your item to do something special such as doing something on right click you will have to create a custom item class. Here i will demonstrate creating an item with a custom class
mod_test.java
package net.minecraft.src;
public class mod_test extends BaseMod
{
public static final Item testItem = new ItemTest(5000).setItemName("test");//creates an item with an id of 5000
public String getVersion()
{
return "anything";
}
public void load()
{
ModLoader.addName(testItem, "Test Item");
}
}
ItemTest.java
package net.minecraft.src;
public class ItemTest extends Item
{
protected ItemTest(int par1)
{
super(par1);
setCreativeTab(CreativeTabs.tabMisc);
iconIndex = ModLoader.addOverride("/gui/items.png", "/test.png");
}
}
Any special code goes in the new item class
Here we will be adding a basic block that doesnt do anything but can be used in recipes
package net.minecraft.src;
public class mod_test extends BaseMod
{
public static final Block testBlock = new Block(165,ModLoader.addOverride("/terrain.png","/test.png"),Material.ground).setBlockName("test");//creates a block with an id of 165, and a custom texture see item tutorial for more info, as well as a material
public String getVersion()
{
return "anything";
}
public void load()
{
ModLoader.registerBlock(testBlock);//registers the block
testBlock.setCreativeTab(CreativeTabs.tabBlock);
ModLoader.addName(testBlock, "Test Block");
}
}
If you want your block to do something special such as damagig the player you will have to create a custom block class. Here i will demonstrate creating a block with a custom class
mod_test.java
package net.minecraft.src;
public class mod_test extends BaseMod
{
public static final Block testBlock = new BlockTest(165,ModLoader.addOverride("/terrain.png","/test.png"),Material.ground).setBlockName("test");//creates a block with an id of 165, and a custom texture see item tutorial for more info, as well as a material
public String getVersion()
{
return "anything";
}
public void load()
{
ModLoader.registerBlock(testBlock);//registers the block
ModLoader.addName(testBlock, "Test Block");
}
}
BlockTest.java
package net.minecraft.src;
public class BlockTest extends Block
{
protected BlockTest(int par1, int par2, Material par3Material)
{
super(par1, par2, par3Material);
setCreativeTab(CreativeTabs.tabBlock);
}
}
Any special code goes in the new block class
If you want to use a custom item in a recipe or for another purpose you do
mod_urmodname.uritem
instead of
Item.uritem
If you want to use a custom block in a recipe or for another purpose you do
mod_urmodname.urblock
instead of
Block.urblock
Here we will be adding our own crafting recipe for a portal block made by surrounding a flint an steel with obsidian, just put this in your load method
So the first paramater is the item you are adding the recipe for and the quantity, the nect 3 strings are the recipe itself where the first one is the top row of the crafting table etc, and then the rest of it is just defining each character we used in the recipe with its item or block
Here i will teach you how to add your own smelting recipe, just put this in your load method
ModLoader.addSmelting(Item.axeDiamond.shiftedIndex, new ItemStack(Item.bed, 1), 1.0F);
Note!! in ModLoader.addSmelting(Item.axeDiamond.shiftedIndex, new ItemStack(Item.bed, 1), 1.0F);
the diamond axe is what you put in the furnace, the bed is what it smelts into and the 1 is the amount of experiance you recieve
Here i will teach you how to add your own fuel, in the example we will make arrows and apples fuel just put this in your mod_ class
public int addFuel(int a, int
{
switch(a)
{
case 260:{return 1000;}//makes apples a fuel, with a fuel value of 1000
case 262:{return 2000;}//makes arrows a fuel, with a fuel value of 2000
default:{return 0;}
}
}
Note!!! The number after the case statement is the value of the item you are adding as a fuel
Here we will be adding a shapeless recipe, it is an easy task. just put this in your load method
ModLoader.addShapelessRecipe(new ItemStack(Item.magmaCream), new Object[] {Block.melon, Block.tnt, Item.arrow});
So the way this works, the item where the magma cream is, is the product of the recipe, the array of other items and blocks are the ingredients.
Here we will make an ore generate in our world. Just put this method in your mod_ class
public void generateSurface(World world, Random random, int a, int
{
for(int rarity = 0; rarity < 7; rarity++)//defines rarity start of for loop
{
int veinSize = 10;//replace with size of vein
int x = a + random.nextInt(16);
int y = random.nextInt(128);
int z = b + random.nextInt(16);
new WorldGenMinable(Block.blockGold.blockID, veinSize).generate(world, random, x, y, z);//replace gold with your ore
}
}
Here i will teach how to make an ore only generate in a specific biome
mod_test.java
package net.minecraft.src;
import java.util.Random;
public class mod_test extends BaseMod
{
public void load()
{
}
public String getVersion()
{
return "1.3.2";
}
public void generateSurface(World world, Random random, int a, int
{
for(int rarity = 0; rarity < 7; rarity++)//defines rarity start of for loop
{
int veinSize = 10;//replace with size of vein
int x = a + random.nextInt(16);
int y = random.nextInt(128);
int z = b + random.nextInt(16);
if(world.getBiomeGenForCoords(a, B)==BiomeGenBase.desert)//replace desert with biome you want ore to generate in
new WorldGenMinable(Block.blockGold.blockID, veinSize).generate(world, random, x, y, z);//replace gold with your ore
}
}
}
here we will be making an ore spawn in the end
start by creating a class called WorldGenNetherMinable copy all the code from WorldGenMinable except at the end of the file on line 60 replace Block.stone.blockID with Block.netherrack.blockID
then put this method in your mod_ class
public void generateNether(World var1, Random var2, int var3, int var4)
{
int var5;
int var6;
int var7;
int var8;
int veinsize=8;//the veinsize of the ore not sure it works
int rarity=12;//the rarity of the ore
for (var5 = 0; var5 < rarity; ++var5)
{
var6 = var3 + var2.nextInt(16);
var7 = var2.nextInt(128);
var8 = var4 + var2.nextInt(16);
new WorldGenNetherMinable(Block.oreEmerald.blockID, veinsize).generate(var1, var2, var6, var7, var8);//replace emerald with your ore
}
}
here we will be making an ore spawn in the end
start by creating a class called WorldGenEndMinable copy all the code from WorldGenMinable except at the end of the file on line 60 replace Block.stone.blockID with Block.whitestone.blockID
just put this in the BiomeGenEnd
public void decorate(World var1, Random var2, int var3, int var4)
{
int var5;
int var6;
int var7;
int var8;
int veinsize=8;//the veinsize of the ore not sure it works
int rarity=12;//the rarity of the ore
for (var5 = 0; var5 < rarity; ++var5)
{
var6 = var3 + var2.nextInt(16);
var7 = var2.nextInt(128);
var8 = var4 + var2.nextInt(16);
new WorldGenEndMinable(Block.oreEmerald.blockID, veinsize).generate(var1, var2, var6, var7, var8);//replace emerald with your ore
}
}
Here we will be making our own structure that generates in the the world that forms a 3d t of diamonds
mod_test.java
package net.minecraft.src;
import java.util.Random;
import net.minecraft.client.Minecraft;
public class mod_test extends BaseMod
{
public String getVersion()
{
return "anything";
}
public void load()
{
}
public void generateSurface(World world, Random random, int x, int z)
{
int rarity = 5;//the rarity of the structure
for(int counter = 0; counter < rarity; counter++)
{
int RandPosX = x + random.nextInt(5);
int RandPosY = random.nextInt(80);
int RandPosZ = z + random.nextInt(5);
(new WorldGenTest()).generate(world, random, RandPosX, RandPosY, RandPosZ);
}
}
}
WorldGenTest.java
package net.minecraft.src;
import java.util.Random;
public class WorldGenTest extends WorldGenerator
{
public boolean generate(World world, Random random, int i, int j, int k)
{
world.setBlockWithNotify(i, j, k, Block.blockDiamond.blockID);
world.setBlockWithNotify(i+1, j, k, Block.blockDiamond.blockID);
world.setBlockWithNotify(i, j+1, k, Block.blockDiamond.blockID);
world.setBlockWithNotify(i, j, k+1, Block.blockDiamond.blockID);
world.setBlockWithNotify(i-1, j, k, Block.blockDiamond.blockID);
world.setBlockWithNotify(i, j-1, k, Block.blockDiamond.blockID);
world.setBlockWithNotify(i, j, k-1, Block.blockDiamond.blockID);
return true;
}
}
Here we will set the burn rate of a block using a hack rather than clean code to get around private variable restrictions
public void load()
{
try
{
Method m = BlockFire.class.getDeclaredMethod("setBurnRate", new Class[]{int.class,int.class,int.class});
m.setAccessible(true);
m.invoke(Block.fire, Block.bedrock.blockID, 5, 20);//this is where everything is done the bedrock you change to the block you want to make flammable, the 5 is the blocks chance to spread fire, and the 20 is the chance of the block catching on fire
}
catch (Exception e){}//Should never happen
}
here we will be making a command to spawn an entity in the world
mod_test.java
package net.minecraft.src;
import net.minecraft.client.Minecraft;
public class mod_test extends BaseMod
{
public static final ICommand spawn = new CommandSpawn();//our command
public String getVersion()
{
return "1.3.2";
}
public void load()
{
ModLoader.addCommand(spawn);//registers the command
}
}
CommandSpawn.java
package net.minecraft.src;
public class CommandSpawn extends CommandBase
{
public String getCommandName()//the name of our command
{
return "spawn";
}
public int func_82362_a()//not sure what this does
{
return 0;
}
public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr)//what our command does the first paramater is the command sender and the second one is the list of args given with the command
{
EntityPlayerMP var3 = getCommandSenderAsPlayer(par1ICommandSender);//gets the player who sent the command
World obj = var3.worldObj;//gets the world associated with the player
Entity a = EntityList.createEntityByID(Integer.parseInt(par2ArrayOfStr[0]), obj);//creates an entity with the id defined by the player
a.setPosition(Integer.parseInt(par2ArrayOfStr[1]), Integer.parseInt(par2ArrayOfStr[2]), Integer.parseInt(par2ArrayOfStr[3]));//sets the entities position based on what the player defines
obj.spawnEntityInWorld(a);//spawns the entity in the world
}
}
so for example to spawn a creeper we would do /spawn 50 x y z
Here we will be making a new food item
package net.minecraft.src;
import java.util.Random;
public class mod_test extends BaseMod
{
public static final Item testFood = new ItemFood(5000,10,false).setItemName("testFood").setCreativeTab(CreativeTabs.tabFood); //5000 is the item id, 10 is the heal amount, and the boolean set to false is if the food can be fed to a wolf
public String getVersion()
{
return "anything";
}
public void load()
{
ModLoader.addName(testFood, "Test Food");
testFood.iconIndex = ModLoader.addOverride("/gui/items.png", "/test.png");
}
}
here we will be making a mob that acts like a zombie and uses the pigman skin
EntityPigman.java
package net.minecraft.src;
public class EntityPigman extends EntityMob//extend this to make mob hostile
{
public EntityPigman(World par1World)
{
super(par1World);//super call
this.texture = "/mob/pigman.png";//specifies texture
this.moveSpeed = .3f;//sets how fast this mob moves
//below this is all the ai tasks that specify how the mob will behave mess around with it to see what happens
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityPlayer.class, this.moveSpeed, false));
this.tasks.addTask(2, new EntityAIMoveTwardsRestriction(this, this.moveSpeed));
this.tasks.addTask(3, new EntityAIWander(this, this.moveSpeed));
this.tasks.addTask(4, new EntityAILookIdle(this));
this.targetTasks.addTask(0, new EntityAIHurtByTarget(this, false));
this.targetTasks.addTask(1, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 16.0F, 0, true));
//end of ai tasks
}
//the amount of damge the mob does i think
public int func_82193_c(Entity par1Entity)
{
return 4;
}
public int getMaxHealth()//says that the mob will have a health of 20
{
return 20;
}
protected boolean isAIEnabled()//says that the tasks we told it to do before will be run
{
return true;
}
}
mod_test.java
package net.minecraft.src;
import java.awt.Color;
import java.util.Map;
public class mod_test extends BaseMod
{
public String getVersion()
{
return "1.3.2";
}
public void load()
{
ModLoader.registerEntityID(EntityPigman.class, "Pigman", 12);//registers the mobs name and id
ModLoader.addSpawn("Pigman", 5, 1, 1, EnumCreatureType.monster);//makes the mob spawn in game see bottom
ModLoader.addLocalization("entity.Pigman.name", "Pigman");//adds the name of the mob to the spawn egg
EntityList.entityEggs.put(Integer.valueOf(12), new EntityEggInfo(12, 894731, (new Color(21, 15, 6)).getRGB()));//creates the spawn egg of the specified colors you will have to mess around with it
}
public void addRenderer(Map var1)
{
var1.put(EntityPigman.class, new RenderLiving(new ModelBiped(),.5f));//says that the pigman should use the living renderer and the biped model note you can change the renderer and the model
}
}
in the add spawn method the first paramater is the name of the mob to spawn the second is the rarity of the mob the third is the minimum group size of the mob the next is the maximum group size of the mob and the last is where the mob can spawn
monster-can only spawn in the dark on easy or higher
watermob-can only spawn in water
creature-can spawn anywhere on land with a few exceptions
In this tutorial i will be teaching how to make a mob that the player creates such as snowmen and iron golems. Because this tutorial is only for exemple purposes the mob that is created is a cow. Were gonna start by creating a new block called block top block which when a structure where an iron block is on the bottom, brick is in the middle, and our new block is on the top
a cow is spawned
BlockTopBlock.java
package net.minecraft.src;
public class BlockTopBlock extends Block
{
public BlockTopBlock(int par1, int par2, Material par3)
{
super(par1, par2, par3);
}
public void onBlockAdded(World par1World, int par2, int par3, int par4)
{
super.onBlockAdded(par1World, par2, par3, par4);
if (par1World.getBlockId(par2, par3 - 1, par4) == Block.brick.blockID && par1World.getBlockId(par2, par3-2, par4)==Block.blockSteel.blockID)//if the block underneath this block is brick and under that is an iron block than spawn a cow
{
par1World.setBlockWithNotify(par2, par3, par4, 0);//erases top block of the structure
par1World.setBlockWithNotify(par2, par3-1, par4, 0);//erases middle block of the structure
par1World.setBlockWithNotify(par2, par3-2, par4, 0);//erases bottom block of the structure
EntityCow var9 = new EntityCow(par1World);//creates the entity
var9.setLocationAndAngles((double)par2 + 0.5D, (double)par3 - 1.95D, (double)par4 + 0.5D, 0.0F, 0.0F);//set entities x,y,z
par1World.spawnEntityInWorld(var9);//spawns entity in world
}
}
}
now all you have to do is register the block in your mod_ class and replace EntityCow with your entity and then try it out
Hey guys in this tutorial we will be doing a custom entity ai tutorial that makes the entity fly upwards and then fall down and die. I thing everything is pretty self explanatory but if you don't understand something feel free to ask. Start by creating this class
EntityAIBeStupid.java
package net.minecraft.src;
import java.util.Iterator;
import java.util.List;
public class EntityAIBeStupid extends EntityAIBase
{
public EntityLiving thing1 = null;//entity ai code should be run on
double height = 0;
public EntityAIBeStupid(EntityLiving thing2)//constructor
{
thing1=thing2;
height=thing1.posY;//set original height
}
public boolean shouldExecute()//returns if the ai code should be run
{
return true;
}
public boolean continueExecuting()//returns if the ai code should continue executing
{
return true;
}
boolean falling = false;//should the entity fall
public void updateTask()//the actual ai code goes here
{
double currentHeight=thing1.posY;
if(!(currentHeight-height>100)&&!falling)
thing1.jump();
else falling = true;
}
}
now just apply this to the entity of your choice by putting this in the entity constructor
this.tasks.addTask(0, new EntityAIBeStupid(this));
and delete any other addTask lines
note! because this ai sends the mob flying in the air you may need to spawn the entity from a spawn egg to see it work
Here i will teach you how to add a throwable entity to the game. Just create the following classes and read the comments.
mod_test.java
package net.minecraft.src;
import java.util.Map;
import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
public class mod_test extends BaseMod
{
public static final Item test = new ItemTest(5000,ModLoader.addOverride("/gui/items.png", "/test.png"));//the item that throws our entity
public String getVersion()
{
return "anything";
}
public void load()
{
/*
This method makes your entity visible the args are
your mod
your entities class
your entities id
the entities view distance(how far away the entity is visible)
the entities update frequency
whether or not the entities motion should be tracked
*/
ModLoader.addEntityTracker(this, EntityTest.class, 101, 64, 20,true);
ModLoader.addDispenserBehavior(test, new BehaviorTestDispense(MinecraftServer.getServer()));//specifies the entities dispense behavior
}
public Entity spawnEntity(int entityId, World worldClient, double x, double y, double z)
{
if(entityId == 101)//if the entity id = our entity id return our entity id
return new EntityTest(worldClient, x, y, z);
else
return null;
}
public Packet23VehicleSpawn getSpawnPacket(Entity entity, int type)
{
if (entity instanceof EntityTest)
return new Packet23VehicleSpawn(entity, type);
else
return null;
}
public void addRenderer(Map var1)
{
var1.put(EntityTest.class, new RenderSnowball(test.iconIndex));//registers the entities renderer to look like the item that it is thrown from
}
}
EntityTest.java
package net.minecraft.src;
public class EntityTest extends EntityThrowable
{
public EntityTest(World par1World)
{
super(par1World);
}
public EntityTest(World par1World, EntityLiving par2EntityLiving)
{
super(par1World, par2EntityLiving);
}
public EntityTest(World par1World, double par2, double par4, double par6)
{
super(par1World, par2, par4, par6);
}
protected void onImpact(MovingObjectPosition par1MovingObjectPosition)//this gets invoked when the entity collides with another entity or block
{
if (par1MovingObjectPosition.entityHit != null)
{
par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 0);//damage a mob with no damage causes knockback
}
if (!this.worldObj.isRemote)
{
this.setDead();
}
}
}
ItemTest.java
package net.minecraft.src;
public class ItemTest extends Item
{
public ItemTest(int par1, int par2)
{
super(par1);
iconIndex = par2;
this.setCreativeTab(CreativeTabs.tabTools);
}
public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)//spawns the entity in the world when this item is right clicked
{
if (!par3EntityPlayer.capabilities.isCreativeMode)
{
--par1ItemStack.stackSize;
}
if (!par2World.isRemote)
{
par2World.spawnEntityInWorld(new EntityTest(par2World, par3EntityPlayer));//spawn our entity
}
return par1ItemStack;
}
}
BehaviorTestDispense.java
package net.minecraft.src;
import net.minecraft.server.MinecraftServer;
public class BehaviorTestDispense extends BehaviorProjectileDispense
{
final MinecraftServer theServer;
public BehaviorTestDispense(MinecraftServer par1)
{
this.theServer = par1;
}
protected IProjectile getProjectileEntity(World par1World, IPosition par2IPosition)//dispenses our entity
{
return new EntityTest(par1World, par2IPosition.getX(), par2IPosition.getY(), par2IPosition.getZ());
}
}
Here we will be adding an enchantment to swords that will send mobs flying in the air when attacked with the sword
mod_test.java
package net.minecraft.src;
import java.util.Random;
public class mod_test extends BaseMod
{
public static final Enchantment airtime = new EnchantmentAirtime(52, 1);//our enchantment
public void load()
{
}
public String getVersion()
{
return "1.3.2";
}
}
EnchantmentAirtime.java
package net.minecraft.src;
public class EnchantmentAirtime extends Enchantment
{
//main constructor
public EnchantmentAirtime(int par1, int par2)
{
super(par1, par2, EnumEnchantmentType.weapon);//says that our enchantment enchants a sword
this.setName("airtime");//sets the in game name of the enchantment
}
//overides enchantments constructor makes it public
public EnchantmentAirtime(int par1, int par2, EnumEnchantmentType par3EnumEnchantmentType)
{
super(par1, par2, par3EnumEnchantmentType);
}
//Returns the minimal value of enchantability needed on the enchantment level passed.
public int getMinEnchantability(int par1)
{
return 20;
}
//Returns the maximum value of enchantability needed on the enchantment level passed.
public int getMaxEnchantability(int par1)
{
return 50;
}
//Returns the maximum level that the enchantment can have.
public int getMaxLevel()
{
return 1;
}
//sets the visual name of our enchantment
public String getTranslatedName(int par1)
{
String enchantmentName = "Airtime";
return enchantmentName + " " + StatCollector.translateToLocal("enchantment.level." + par1);
}
}
and to finish it up replace the hitEntity method in the item sword class with this
public boolean hitEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving)
{
par1ItemStack.damageItem(1, par3EntityLiving);
if (EnchantmentHelper.getEnchantmentLevel(mod_test.airtime.effectId, par1ItemStack) > 0)
par2EntityLiving.motionY+=5;
return true;
}
Here we will be creating our own world type it will be full of large hills and mountains but it will be easily customizable. Doing this is actually an extreemly simple task.
mod_test.java
package net.minecraft.src;
public class mod_test extends BaseMod
{
public static final WorldType ExtremeHills = new WorldTypeTest(3, "ExtremeHills");//our new world type
public String getVersion()//the version
{
return "1.4.2";
}
public void load(){}//leave it empty it dos'nt matter
}
WorldTypeTest.java
package net.minecraft.src;
public class WorldTypeTest extends WorldType
{
public WorldTypeTest(int par1, String par2Str)//constructor
{
super(par1, par2Str);
}
public String getTranslateName()//the name that appears on the screen
{
return "Extreme Hills";
}
public WorldChunkManager getChunkManager(World var1)//the chunk manager to use in our world type i'm just using the hell generator with the specification to generate the extreme hills biome but change it to whatever you want
{
return new WorldChunkManagerHell(BiomeGenBase.extremeHills, 0.5F, 0.5F);
}
}
Here we will be making a biome i made it as kind of a joke but it demonstrates what a biome can do here we will make the surface out of wood and tnt but change it to what you want. Their are tons of variables to mess around with to customize the biome to you liking
mod_test.java
package net.minecraft.src;
public class mod_test extends BaseMod
{
BiomeGenTest test = new BiomeGenTest(23);
public String getVersion()
{
return "1.4.2";
}
public void load()
{
ModLoader.addBiome(test);
}
}
Here I will teach you how to add several different types of plants to the game
Here i will teach you how to make a custom flower and make it generate
mod_test.java
package net.minecraft.src;
import java.util.*;
public class mod_test extends BaseMod
{
public static final Block blueFlower = new BlockFlower(165, ModLoader.addOverride("/terrain.png", "/Blue Flower.png")).setBlockName("blueFlower");
public void load()
{
ModLoader.registerBlock(blueFlower);
ModLoader.addName(blueFlower, "Blue Flower");
}
public String getVersion()
{
return "1.4.2";
}
public void generateSurface(World var1, Random var2, int var3, int var4)
{
int rarity = 1;//increse to make flower more common
for(int i = 0; i<rarity; i++)
{
int var5 = var2.nextInt(128);
new WorldGenFlowers(blueFlower.blockID).generate(var1, var2, var3, var4, var5);
}
}
}
For my flower i used this texture but you can use your own
Here we will be making a plant that grows upwards such as sugar cane and a cactus
mod_test.java
package net.minecraft.src;
import java.util.*;
public class mod_test extends BaseMod
{
Block testPlant = new BlockTestPlant(160,ModLoader.addOverride("/terrain.png", "/test.png")).setBlockName("testPlant");
public void load()
{
ModLoader.registerBlock(testPlant);
ModLoader.addName(testPlant, "Test plant");
}
public String getVersion()
{
return "1.4.2";
}
}
BlockTestPlant.java
package net.minecraft.src;
import java.util.Random;
public class BlockTestPlant extends Block
{
protected BlockTestPlant(int par1, int par2)
{
super(par1, par2, Material.plants);
setTickRandomly(true);
setCreativeTab(CreativeTabs.tabDecorations);
}
public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
{
if (par1World.isAirBlock(par2, par3 + 1, par4))
{
int var6;
for (var6 = 1; par1World.getBlockId(par2, par3 - var6, par4) == this.blockID; ++var6)
{
;
}
if (var6 < 3)//3 is the maximum height the block can grow
{
int var7 = par1World.getBlockMetadata(par2, par3, par4);
if (var7 == 15)
{
par1World.setBlockWithNotify(par2, par3 + 1, par4, this.blockID);
par1World.setBlockMetadataWithNotify(par2, par3, par4, 0);
}
else
{
par1World.setBlockMetadataWithNotify(par2, par3, par4, var7 + 1);
}
}
}
}
public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)//can place on dirt, grass, and itself
{
int var5 = par1World.getBlockId(par2, par3 - 1, par4);
return var5==Block.dirt.blockID||var5==Block.grass.blockID||var5==this.blockID;
}
public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)//drops the block if it cant stay
{
if (!this.canBlockStay(par1World, par2, par3, par4))
{
this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
par1World.setBlockWithNotify(par2, par3, par4, 0);
}
}
public boolean canBlockStay(World par1World, int par2, int par3, int par4)//can the block stay
{
return this.canPlaceBlockAt(par1World, par2, par3, par4);
}
}
Here we will be making a plant that goes through stages like wheat and netherwarts
mod_test.java
package net.minecraft.src;
public class mod_test extends BaseMod
{
public static Block testCrop = new BlockTestCrop(162).setBlockName("testCrop");
public static Item testCropSeeds = (new ItemSeeds(5000, testCrop.blockID, Block.sand.blockID)).setItemName("testCropSeeds").setCreativeTab(CreativeTabs.tabMisc);//see note
public static int stage1 = ModLoader.addOverride("/terrain.png", "/stage1.png");//stage 1 of the block
public static int stage2 = ModLoader.addOverride("/terrain.png", "/stage2.png");//stage 2 of the block
public static int stage3 = ModLoader.addOverride("/terrain.png", "/stage3.png");//stage 3 of the block
public static int stage4 = ModLoader.addOverride("/terrain.png", "/stage4.png");//stage 4 of the block
public String getVersion()
{
return "1.4.2";
}
public void load()
{
ModLoader.registerBlock(testCrop);
ModLoader.addName(testCropSeeds, "Test Crop Seeds");
testCropSeeds.iconIndex=ModLoader.addOverride("/gui/items.png", "/testSeeds.png");
}
}
BlockTestCrop.java
package net.minecraft.src;
import java.util.Random;
public class BlockTestCrop extends Block
{
int numberOfStages = 4;//the amount of stages this crop has
protected BlockTestCrop(int par1)
{
super(par1, 0, Material.plants);
this.setTickRandomly(true);
this.setCreativeTab((CreativeTabs)null);
}
protected boolean canThisPlantGrowOnThisBlockID(int par1)//only grows on sand
{
return par1 == Block.sand.blockID;
}
public boolean canBlockStay(World par1World, int par2, int par3, int par4)
{
return this.canThisPlantGrowOnThisBlockID(par1World.getBlockId(par2, par3 - 1, par4));
}
public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)//block grows
{
int growspeed = 5;//make it higher to grow slower make it lower to grow faster can't be lower than 1 it will also glitch up at 1
int var6 = par1World.getBlockMetadata(par2, par3, par4);
if (var6 < numberOfStages-1 && par5Random.nextInt(growspeed) == 0)
{
++var6;
par1World.setBlockAndMetadataWithNotify(par2, par3, par4, this.blockID, var6);
}
super.updateTick(par1World, par2, par3, par4, par5Random);
}
public int getBlockTextureFromSideAndMetadata(int par1, int stage)//gets the image depending on the stage
{
switch(stage)
{
case 0:{return mod_test.stage1;}
case 1:{return mod_test.stage2;}
case 2:{return mod_test.stage3;}
case 3:{return mod_test.stage4;}
default:{return 0;}
}
}
public int quantityDropped(Random par1Random)//the amount to drop
{
return par1Random.nextInt(4)+3;
}
public int idPicked(World par1World, int par2, int par3, int par4)
{
return mod_test.testCropSeeds.shiftedIndex;
}
public int idDropped(int par1, Random par2Random, int par3)//the item it drops only drop if its fully grown
{
return par1 == numberOfStages-1 ? Item.gunpowder.shiftedIndex : 0;//replace gunpowder with the item your plant drops
}
}
NOTES
1. in this line
public static Item testCropSeeds = (new ItemSeeds(5000, testCrop.blockID, Block.sand.blockID)).setItemName("testCropSeeds").setCreativeTab(CreativeTabs.tabMisc);
we created the seeds for the block. We put our block into the paramaters because that is the blocks the seeds place. We put sand into the paramaters because that is the block our plant can be placed on
Here we will be making a plant like pumpkins and melons where a single stem grows and then grows off blocks to the side. This tutorial builds off of the stage plant and uses the same mod_ class as it so i suggest you read that first
BlockTestCrop.java
package net.minecraft.src;
import java.util.Random;
public class BlockTestCrop extends Block
{
int numberOfStages = 4;//the amount of stages this crop has
protected BlockTestCrop(int par1)
{
super(par1, 0, Material.plants);
this.setTickRandomly(true);
this.setCreativeTab((CreativeTabs)null);
}
protected boolean canThisPlantGrowOnThisBlockID(int par1)//only grows on sand
{
return par1 == Block.sand.blockID;
}
public boolean canBlockStay(World par1World, int par2, int par3, int par4)
{
return this.canThisPlantGrowOnThisBlockID(par1World.getBlockId(par2, par3 - 1, par4));
}
public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)//block grows
{
int growspeed = 5;//make it higher to grow slower make it lower to grow faster can't be lower than 1 it will also glitch up at 1
int chanceToProduceCrop = 5;//make it higher to produce its crop slower make it lower to produce its crop faster can't be lower than 1 it will also glitch up at 1
int var6 = par1World.getBlockMetadata(par2, par3, par4);
if (var6 < numberOfStages-1 && par5Random.nextInt(growspeed) == 0)
{
++var6;
par1World.setBlockAndMetadataWithNotify(par2, par3, par4, this.blockID, var6);
}
if (var6 == numberOfStages-1 && par5Random.nextInt(chanceToProduceCrop) == 0)
{
if(par1World.getBlockId(par2-1, par3, par4)==0)
par1World.setBlock(par2-1, par3, par4, Block.glowStone.blockID);//replace glowstone with the block your plant will produce
else if(par1World.getBlockId(par2+1, par3, par4)==0)
par1World.setBlock(par2+1, par3, par4, Block.glowStone.blockID);//replace glowstone with the block your plant will produce
else if(par1World.getBlockId(par2, par3, par4-1)==0)
par1World.setBlock(par2, par3, par4-1, Block.glowStone.blockID);//replace glowstone with the block your plant will produce
else if(par1World.getBlockId(par2, par3, par4+1)==0)
par1World.setBlock(par2, par3, par4+1, Block.glowStone.blockID);//replace glowstone with the block your plant will produce
}
super.updateTick(par1World, par2, par3, par4, par5Random);
}
public int getBlockTextureFromSideAndMetadata(int par1, int stage)//gets the image depending on the stage
{
switch(stage)
{
case 0:{return mod_test.stage1;}
case 1:{return mod_test.stage2;}
case 2:{return mod_test.stage3;}
case 3:{return mod_test.stage4;}
default:{return 0;}
}
}
public int quantityDropped(Random par1Random)//the amount to drop
{
return 0;
}
public int idPicked(World par1World, int par2, int par3, int par4)
{
return mod_test.testCropSeeds.shiftedIndex;
}
public int idDropped(int par1, Random par2Random, int par3)//the item it drops only drop if its fully grown
{
return 0;
}
}
Here we will be making our own tree and have it generate in the world. Our tree will be missing a few features for simplicity such as the leaves rendering special on fancy and the crafting recipes for the wood although those features will be easy to add.
mod_test.java
package net.minecraft.src;
import java.util.Random;
public class mod_test extends BaseMod
{
public static final int logSide = ModLoader.addOverride("/terrain.png", "/logSide.png");
public static final Block testWood = new BlockLogTest(186).setBlockName("testWood").setHardness(2);
public static final Block testLeaves = new BlockLeavesTest(187,ModLoader.addOverride("/terrain.png", "/testLeaves.png")).setBlockName("testLeaves").setHardness(.2f);
public static final Block testSapling = new BlockSaplingTest(188,ModLoader.addOverride("/terrain.png", "/testSapling.png")).setBlockName("testSapling");
public String getVersion()
{
return "1.4.2";
}
public void load()
{
ModLoader.registerBlock(testWood);
ModLoader.registerBlock(testLeaves);
ModLoader.registerBlock(testSapling);
ModLoader.addName(testSapling, "Test Sapling");
ModLoader.addName(testLeaves, "Test Leaves");
ModLoader.addName(testWood, "Test Wood");
}
public void generateSurface(World world, Random rand, int x, int y)
{
BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(x, y);
int rarity = biome.theBiomeDecorator.treesPerChunk;//the hisher the number the more common the tree is
for(int i = 0; i < rarity; i++)
{
int xPos = x + rand.nextInt(16);
int zPos = y + rand.nextInt(16);
int yPos = world.getHeightValue(xPos, zPos);
new WorldGenTreeTest().generate(world, rand, xPos, yPos, zPos);
}
}
}
BlockLogTest.java
package net.minecraft.src;
import java.util.List;
import java.util.Random;
public class BlockLogTest extends Block
{
protected BlockLogTest(int par1)
{
super(par1, Material.wood);
this.blockIndexInTexture = 20;
this.setCreativeTab(CreativeTabs.tabBlock);
}
public int getRenderType()
{
return 31;
}
public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
{
byte var7 = 4;
int var8 = var7 + 1;
if (par1World.checkChunksExist(par2 - var8, par3 - var8, par4 - var8, par2 + var8, par3 + var8, par4 + var8))
{
for (int var9 = -var7; var9 <= var7; ++var9)
{
for (int var10 = -var7; var10 <= var7; ++var10)
{
for (int var11 = -var7; var11 <= var7; ++var11)
{
int var12 = par1World.getBlockId(par2 + var9, par3 + var10, par4 + var11);
if (var12 == mod_test.testLeaves.blockID)
{
int var13 = par1World.getBlockMetadata(par2 + var9, par3 + var10, par4 + var11);
if ((var13 & 8) == 0)
{
par1World.setBlockMetadata(par2 + var9, par3 + var10, par4 + var11, var13 | 8);
}
}
}
}
}
}
}
public int func_85104_a(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9)
{
int var10 = par9 & 3;
byte var11 = 0;
switch (par5)
{
case 0:
case 1:
var11 = 0;
break;
case 2:
case 3:
var11 = 8;
break;
case 4:
case 5:
var11 = 4;
}
return var10 | var11;
}
public int getBlockTextureFromSideAndMetadata(int par1, int par2)
{
switch(par1)
{
case 0:{return 21;}
case 1:{return 21;}
default:{return mod_test.logSide;}
}
}
}
Here we will be making a block that spreads like grass or mycelium and will conclude our plant tutorials. I dont comment this tutorial becuase everythingis very simple or very complicated, however if you have questions feel free to ask. Just create these classes.
mod_test.java
package net.minecraft.src;
public class mod_test extends BaseMod
{
Block test = new BlockSpreadingTest(170).setBlockName("test").setHardness(0.6F).setStepSound(Block.soundGrassFootstep);
public String getVersion()
{
return "anything";
}
public void load()
{
ModLoader.registerBlock(test);
ModLoader.addName(test, "Test grass");
}
}
BlockSpreadingTest.java
package net.minecraft.src;
import java.util.Random;
public class BlockSpreadingTest extends Block
{
protected BlockSpreadingTest(int par1)
{
super(par1, Material.grass);
this.blockIndexInTexture = 1;
this.setTickRandomly(true);
this.setCreativeTab(CreativeTabs.tabBlock);
}
public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
{
if (!par1World.isRemote)
{
if (par1World.getBlockLightValue(par2, par3 + 1, par4) < 4 && Block.lightOpacity[par1World.getBlockId(par2, par3 + 1, par4)] > 2)
{
par1World.setBlockWithNotify(par2, par3, par4, Block.dirt.blockID);
}
else if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9)
{
for (int var6 = 0; var6 < 4; ++var6)
{
int var7 = par2 + par5Random.nextInt(3) - 1;
int var8 = par3 + par5Random.nextInt(5) - 3;
int var9 = par4 + par5Random.nextInt(3) - 1;
int var10 = par1World.getBlockId(var7, var8 + 1, var9);
if (par1World.getBlockId(var7, var8, var9) == Block.dirt.blockID && par1World.getBlockLightValue(var7, var8 + 1, var9) >= 4 && Block.lightOpacity[var10] <= 2)
{
par1World.setBlockWithNotify(var7, var8, var9, this.blockID);
}
}
}
}
}
public int idDropped(int par1, Random par2Random, int par3)
{
return Block.dirt.idDropped(0, par2Random, par3);
}
}
Here we will be adding a custom particle to the game as well as a system for spawning it our particle will look like the redstone particle but it will be green instead, however there are heaps of variables to screw around with to customize it.
EntityTestFX.java
package net.minecraft.src;
import net.minecraft.client.Minecraft;
public class ParticleEffects
{
private static Minecraft mc = Minecraft.getMinecraft();
private static World theWorld = mc.theWorld;
private static RenderEngine renderEngine = mc.renderEngine;
public static EntityFX spawnParticle(String particleName, double par2, double par4, double par6, double par8, double par10, double par12)
{
if (mc != null && mc.renderViewEntity != null && mc.effectRenderer != null)
{
int var14 = mc.gameSettings.particleSetting;
if (var14 == 1 && theWorld.rand.nextInt(3) == 0)
{
var14 = 2;
}
double var15 = mc.renderViewEntity.posX - par2;
double var17 = mc.renderViewEntity.posY - par4;
double var19 = mc.renderViewEntity.posZ - par6;
EntityFX var21 = null;
double var22 = 16.0D;
if (var15 * var15 + var17 * var17 + var19 * var19 > var22 * var22)
{
return null;
}
else if (var14 > 1)
{
return null;
}
else
{
if (particleName.equals("test"))//if the name of the particle to be spawned equals test spawn our particle note the name here is the name that you use when you call spawn particle
{
var21 = new EntityTestFX(theWorld, par2, par4, par6, (float)par8, (float)par10, (float)par12);
}
mc.effectRenderer.addEffect((EntityFX)var21);
return (EntityFX)var21;
}
}
return null;
}
}
finally to spawn our particle just do this
ParticleEffects.spawnParticle("test", x, y, z, 0.0D, 0.0D, 0.0D);
where x,y,z is the position to spawn the particle at
Here we will be making a custom achievement that get activated when the player removes charcoal from the furnace
mod_test.java
package net.minecraft.src;
public class mod_test extends BaseMod
{
//Achievement id,name,item icon,coordinates on map,null,register the achievement
public static final Achievement testAchievement = new Achievement(3000, "Test", 45, 7, Item.coal, null).registerAchievement();
public void load()
{
ModLoader.addAchievementDesc(testAchievement, "Test", "Sub-Test");//name and sub-name
}
public String getVersion()
{
return "1.4.2";
}
public void takenFromFurnace(EntityPlayer entityplayer, ItemStack itemstack)
{
if(itemstack.itemID == Item.coal.shiftedIndex)
{
entityplayer.addStat(testAchievement, 1);//activates enchantment
}
}
}
Here we will add our own villager trades.
mod_test.java
package net.minecraft.src;
public class mod_test extends BaseMod
{
/*
* Creates a new trade entry where the gunpowder is the trade item, .5 is the chance of the
* trade occurring, the false tells the game the villager will be selling the item true for
* buying, and the last two arguments are the minimum and maximum amount of emeralds the item
* will cost.
*/
TradeEntry test = new TradeEntry(Item.gunpowder.itemID, 0.5f, false, 2, 4);
public String getVersion()
{
return "Anything";
}
public void load()
{
ModLoader.addTrade(1, test);//adds the trade, the 1 is the profession in this case librarian and the test is our trade.
}
}
Here we will make a block that looks like stone and falls like sand and gravel
mod_test.java
package net.minecraft.src;
public class mod_test extends BaseMod
{
public static final Block testBlock = new BlockTest(165);
public String getVersion()
{
return "anything";
}
public void load()
{
ModLoader.registerBlock(testBlock);
}
}
BlockTest.java
package net.minecraft.src;
import java.util.Random;
public class BlockTest extends BlockSand
{
public static boolean fallInstantly = false;
public BlockTest(int par1)
{
super(par1, Block.stone.blockIndexInTexture, Material.rock);
this.setCreativeTab(CreativeTabs.tabBlock);
}
}
If you liked these tutorials or if they helped you please click this button at the bottom of the post[represent]
Could you make a tutorial on how to make a tameable NPC?
Do you think you could do a tutorial on how to make a custom furnace? Thank you. I have tried and tried my self and can't seem to get it just right. Always end up with errors.
Do you think you could do some forge tutorials? Or better yet, how to (somewhat) easily convert your ModLoader mods into Forge? Following other tutorials, I've only gotten a block with no crafting recipe.... So any forge tutorials would be helpful
Thanks so much! the code i had for the tree was totally not working! the tree spawned, but when the sapling grew, the game crashed instead of giving me a tree! and bonemeal had no effect! only problem is the bonemeal actually. It works, but its glitchy. sometimes the sapling stays and a phantom tree grows (once you update the blocks of the tree it disappears). Other than that, thanks a million! P.S. Any idea how to fix the bonemeal?
Hey Popgalop or anyone. Do you know how to make a mod that contains... RECIPES ONLY
For example, I want to add more recipes for Diamonds (let's just say that, put anoher recipe/s for an exisitng item in Minecraft). If you then, please add that.
Im not sure, but in your core mod file, you could type "extends crafting manager, and then add what you want.
No actual contents on how to make a player-crafted mob, just a description of what you were going to tell us.
Anyway, this is a rather useful topic, but some of the stuff, especially the mob tutorials, are a little basic.
I was hoping there would be more on using custom models and sounds, since those are the things I tend
to have the msot trouble with ( No sounds, invisible mobs, etc.)
onItemPickup and takenFromCrafting instead of takenFromFurnace
The error is in .getServer() and it says: The method getServer() is undefined for the type Object
Please Help
Could you make a tutorial on how to make a tameable NPC?
Bleach Mod
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumCustom Entity AI spoiler will not open.
No actual contents on how to make a player-crafted mob, just a description of what you were going to tell us.
Anyway, this is a rather useful topic, but some of the stuff, especially the mob tutorials, are a little basic.
I was hoping there would be more on using custom models and sounds, since those are the things I tend
to have the msot trouble with ( No sounds, invisible mobs, etc.)
Well, not for me. Could you put the custom Entity AI stuff in a PM, or just copy-paste it into a
new spoiler? Would be much appreciated.