I will be adding some new material to this thread, mainly because I have found some things that have not been made into useful tutorials by anyone and had to do some begging, scavenging, and other things to find on my own how to do some things, that even if there were tutorials for them, they are for the most part incomplete.....
Most of any of the information I post here will now be for forge, though you can most certainly get them to work one way or another in modloader, for example the particles tut is for modloader, but mostly its pretty basic and will work in forge just as easy.
Particles
Particle modding isn't that hard as I found out, it's all in the way you setup your basic mod. This is a simple tutorial that I have created to show you how to create a mod_whatever.class and Block.class to create particles from blocks. I have searched high and low, and found that answers that come aren't always clear, tutorials are rare for this, and videos are just as rare. Anyhow, this tutorial will show you how to decorate your blocks for the beginning modder.
First lets start with the mod_whatever.class
package net.minecraft.src;
import java.util.Map;
public class mod_whatever extends BaseMod
{
public String getVersion()
{
return "1.2.5";
}
public static final Block Whatever;
static
{
whatever = new Whatever(128).setHardness(0.5F).setResistance(3F).setLightValue(0F).setBlockName("Whatever");
}
public void load()
{
whatever.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/yourtexture/whatever.png");
ModLoader.registerBlock(whatever);
ModLoader.addName(whatever, "Whatever");
ModLoader.addRecipe(new ItemStack(whatever, 1), new Object [] {" X ", " X ", " X ", Character.valueOf('X'), Block.dirt});
}
}
Now for the Block class.......
package net.minecraft.src;
import java.util.Random;
public class Whatever extends Block
{
public Whatever (int i)
{
super(i, Material.ground);
}
public int getRenderBlockPass()
{
return 0;
}
public void randomDisplayTick(World world, int i, int j, int k, Random random)
{
world.spawnParticle("smoke", i+0.5, j+1.0, k+0.5, 0.0D, 0.0D, 0.0D);
}
}
Popgalop has a wonderful tutorial on custom particles here... and if you want to add more than one particle all you have to do is add more if statements to the class like this
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);
}
if (particleName.equals("test1"))//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 EntityTestFX1(theWorld, par2, par4, par6, (float)par8, (float)par10, (float)par12);
}
if (particleName.equals("test2"))//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 EntityTestFX2(theWorld, par2, par4, par6, (float)par8, (float)par10, (float)par12);
}
If you copy the code for your custom particle from reddust or the hearts or bubbles, you can point to your custom particle, but as long as they are on individual 8x8 textures. If you want more than one custom particle and all custom particles on one sheet you should use this code in your particle FX class
All of your custom particles have to be 8x8 or they will not work....
Please.... Do Not just copy and paste this, copy it down on paper, the retype it into eclipse and you will learn it better. Particles are fun to play with and can be decorative. But without writing your own ParticleFX classes for each particle, which I don not know how to do yet, your effects are limited to their current color, and how long they last. They can be manipulated to a point, but that is about it. This tutorial works for 1.2.5 and should be okay for 1.3.x versions as well with a little manipulating. Have fun and enjoy......Microjunk
Grenades forge
I have wrote this tutorial because in search of a good tut on grenades, especially for forge, they just don't exists. At best, they are 60% complete.
Files you will need:
Things you will need....
A client proxy
an entity class
an item class
a render class
a mod class
Lets first start by saying this is done using modified code from the snowball, the following is the item from the snowball
public class ItemSnowball extends Item
{
public ItemSnowball(int par1)
{
super(par1);
this.maxStackSize = 16;
this.setCreativeTab(CreativeTabs.tabMisc);
}
/**
* Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer
*/
public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
if (!par3EntityPlayer.capabilities.isCreativeMode)
{
--par1ItemStack.stackSize;
}
par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F));
if (!par2World.isRemote)
{
par2World.spawnEntityInWorld(new EntitySnowball(par2World, par3EntityPlayer));
}
return par1ItemStack;
}
}
We take this file and turn it into this
grenade item
public class ItemGrenade extends Item
{
public ItemGrenade(int i)
{
super(i);
this.maxStackSize = 8;
this.setCreativeTab(CreativeTabs.tabMisc);
}
public ItemStack onItemRightClick(ItemStack var1, World var2, EntityPlayer var3)
{
if (!var3.capabilities.isCreativeMode)
{
--var1.stackSize;
}
var2.playSoundAtEntity(var3, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F));
if (!var2.isRemote)
{
var2.spawnEntityInWorld(new EntityGrenade(var2, var3));
}
return var1;
}
public String getTextureFile()
{
return "/microjunk/popomod/common/GrenadeItems.png";
}
}
Which is pretty much the same, except that we change the entity for our own, and call our texture file
snowball entity
public class EntitySnowball extends EntityThrowable
{
public EntitySnowball(World par1World)
{
super(par1World);
}
public EntitySnowball(World par1World, EntityLiving par2EntityLiving)
{
super(par1World, par2EntityLiving);
}
public EntitySnowball(World par1World, double par2, double par4, double par6)
{
super(par1World, par2, par4, par6);
}
/**
* Called when this EntityThrowable hits a block or entity.
*/
protected void onImpact(MovingObjectPosition par1MovingObjectPosition)
{
if (par1MovingObjectPosition.entityHit != null)
{
byte var2 = 0;
if (par1MovingObjectPosition.entityHit instanceof EntityBlaze)
{
var2 = 3;
}
par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.func_85052_h()), var2);
}
for (int var3 = 0; var3 < 8; ++var3)
{
this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
}
if (!this.worldObj.isRemote)
{
this.setDead();
}
}
}
Which we turn into this
Entity Grenade
public class EntityGrenade extends EntityThrowable
{
private EntityLiving thrower;
public EntityGrenade(World var1)
{
super(var1);
}
public EntityGrenade(World var1, EntityLiving var2)
{
super(var1, var2);
}
public EntityGrenade(World var1, double var2, double var4, double var6)
{
super(var1, var2, var4, var6);
}
/**
* Called when this EntityThrowable hits a block or entity.
*/
protected void onImpact(MovingObjectPosition var1)
{
if (var1.entityHit != null)
{
byte var2 = 0;
if (var1.entityHit instanceof EntityBlaze)
{
var2 = 3;
}
if (!var1.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.thrower), var2))
{
;
}
}
for (int var3 = 0; var3 < 8; ++var3)
{
this.worldObj.spawnParticle("none", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
}
if (!this.worldObj.isRemote)
{
this.setDead();
if (!this.worldObj.isRemote)
{
this.worldObj.createExplosion((Entity)null, this.posX, this.posY, this.posZ, 2.5F, true);
}
}
}
public String getTextureFile()
{
return "/microjunk/popomod/common/GrenadeItems.png";
}
}
But it looks again the same, with minor changes
render snowball
public class RenderSnowball extends Render
{
/**
* Have the icon index (in items.png) that will be used to render the image. Currently, eggs and snowballs uses this
* classes.
*/
private int itemIconIndex;
public RenderSnowball(int par1)
{
this.itemIconIndex = par1;
}
/**
* Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
* handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
* (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
* double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
*/
public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
{
GL11.glPushMatrix();
GL11.glTranslatef((float)par2, (float)par4, (float)par6);
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
GL11.glScalef(0.5F, 0.5F, 0.5F);
this.loadTexture("/gui/items.png");
Tessellator var10 = Tessellator.instance;
if (this.itemIconIndex == 154)
{
int var11 = PotionHelper.func_77915_a(((EntityPotion)par1Entity).getPotionDamage(), false);
float var12 = (float)(var11 >> 16 & 255) / 255.0F;
float var13 = (float)(var11 >> 8 & 255) / 255.0F;
float var14 = (float)(var11 & 255) / 255.0F;
GL11.glColor3f(var12, var13, var14);
GL11.glPushMatrix();
this.func_77026_a(var10, 141);
GL11.glPopMatrix();
GL11.glColor3f(1.0F, 1.0F, 1.0F);
}
this.func_77026_a(var10, this.itemIconIndex);
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
GL11.glPopMatrix();
}
private void func_77026_a(Tessellator par1Tessellator, int par2)
{
float var3 = (float)(par2 % 16 * 16 + 0) / 256.0F;
float var4 = (float)(par2 % 16 * 16 + 16) / 256.0F;
float var5 = (float)(par2 / 16 * 16 + 0) / 256.0F;
float var6 = (float)(par2 / 16 * 16 + 16) / 256.0F;
float var7 = 1.0F;
float var8 = 0.5F;
float var9 = 0.25F;
GL11.glRotatef(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(-this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F);
par1Tessellator.startDrawingQuads();
par1Tessellator.setNormal(0.0F, 1.0F, 0.0F);
par1Tessellator.addVertexWithUV((double)(0.0F - var8), (double)(0.0F - var9), 0.0D, (double)var3, (double)var6);
par1Tessellator.addVertexWithUV((double)(var7 - var8), (double)(0.0F - var9), 0.0D, (double)var4, (double)var6);
par1Tessellator.addVertexWithUV((double)(var7 - var8), (double)(var7 - var9), 0.0D, (double)var4, (double)var5);
par1Tessellator.addVertexWithUV((double)(0.0F - var8), (double)(var7 - var9), 0.0D, (double)var3, (double)var5);
par1Tessellator.draw();
}
}
which gets turned into this....
public class RenderGrenade extends Render
{
/**
* Have the icon index (in items.png) that will be used to render the image. Currently, eggs and snowballs uses this
* classes.
*/
private int itemIconIndex;
public RenderGrenade(int par1)
{
this.itemIconIndex = par1;
}
/**
* Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
* handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
* (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
* double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
*/
public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
{
GL11.glPushMatrix();
GL11.glTranslatef((float)par2, (float)par4, (float)par6);
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
GL11.glScalef(0.5F, 0.5F, 0.5F);
this.loadTexture("/microjunk/popomod/common/PopoItems.png");
Tessellator var10 = Tessellator.instance;
this.func_77026_a(var10, this.itemIconIndex);
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
GL11.glPopMatrix();
}
private void func_77026_a(Tessellator par1Tessellator, int par2)
{
float var3 = (float)(par2 % 16 * 16 + 0) / 256.0F;
float var4 = (float)(par2 % 16 * 16 + 16) / 256.0F;
float var5 = (float)(par2 / 16 * 16 + 0) / 256.0F;
float var6 = (float)(par2 / 16 * 16 + 16) / 256.0F;
float var7 = 1.0F;
float var8 = 0.5F;
float var9 = 0.25F;
GL11.glRotatef(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(-this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F);
par1Tessellator.startDrawingQuads();
par1Tessellator.setNormal(0.0F, 1.0F, 0.0F);
par1Tessellator.addVertexWithUV((double)(0.0F - var8), (double)(0.0F - var9), 0.0D, (double)var3, (double)var6);
par1Tessellator.addVertexWithUV((double)(var7 - var8), (double)(0.0F - var9), 0.0D, (double)var4, (double)var6);
par1Tessellator.addVertexWithUV((double)(var7 - var8), (double)(var7 - var9), 0.0D, (double)var4, (double)var5);
par1Tessellator.addVertexWithUV((double)(0.0F - var8), (double)(var7 - var9), 0.0D, (double)var3, (double)var5);
par1Tessellator.draw();
}
}
As you can see once again only small changes to the code, one thing to note though is that the potion helper portion was removed. It will error if you dont, and it is not really needed anyhow. Also note that the texture call has been changed as well so we can pull our own texture...
In the client proxy we need to add this to our register render area
RenderingRegistry.registerEntityRenderingHandler(EntityGrenade.class, new RenderGrenade(1));
this is equivalent to the add renderer to you mod class of a modloader mod. Make sure you change the 1 to what ever your location of your grenade.
Add this line of code to your mod class to register the entity in your mod class in forge....
The 550, is the ID of your grenade item, the rest you should know from registering any entity in mnecraft modding.
this should be a pretty complete tutorial, just ask if I missed something and I will try my best to fill in the blanks.
Forge Vehicle 1.4.6
This tutorial, like the others, will not be very fulfilling as far as detailed explanation. Sorry, I don't have the extreme knowledge and understanding it takes to explain it all. This one especially will be less informative than the others. I have only been able to do this with the little help and pointers I received from the forums members. That, and just playing with the numbers and deleting the few irrelevant lines of code I have been able to make a simple "Car" that drives on land. The controls are a bit sloppy because it is modified boat code. If you want a better car, I suggest trying to find and replace the control code with the code from the pig and perhaps that or this tutorial here (post #617) may help, though it is a much older tutorial. Search through the thread because there are a few updates to the tutorial and some better code. I have done this because it just does not totally work, there are quite a few problems with it, more so than I cared to fix and found doing this was a better way to make a SIMPLE vehicle.
Okay first we will need to get the relevant files we need from minecraft and they are....
You will need to change that to your entity and also your class name should be different as well. I call mine landboat for this tutorial...And this is what my ItemLandBoat looks like.
So moving right along when we look at our current code we should now have a red underline under entitylandboat (or whatever you choose to call your vehicle) asking us to create a new class, lets do so now and have a look at the entityboat class.
public class EntityBoat extends Entity
{
private boolean field_70279_a;
private double field_70276_b;
private int boatPosRotationIncrements;
private double boatX;
private double boatY;
private double boatZ;
private double boatYaw;
private double boatPitch;
@SideOnly(Side.CLIENT)
private double velocityX;
@SideOnly(Side.CLIENT)
private double velocityY;
@SideOnly(Side.CLIENT)
private double velocityZ;
public EntityBoat(World par1World)
{
super(par1World);
this.field_70279_a = true;
this.field_70276_b = 0.07D;
this.preventEntitySpawning = true;
this.setSize(1.5F, 0.6F);
this.yOffset = this.height / 2.0F;
}
/**
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
* prevent them from trampling crops
*/
protected boolean canTriggerWalking()
{
return false;
}
protected void entityInit()
{
this.dataWatcher.addObject(17, new Integer(0));
this.dataWatcher.addObject(18, new Integer(1));
this.dataWatcher.addObject(19, new Integer(0));
}
/**
* Returns a boundingBox used to collide the entity with other entities and blocks. This enables the entity to be
* pushable on contact, like boats or minecarts.
*/
public AxisAlignedBB getCollisionBox(Entity par1Entity)
{
return par1Entity.boundingBox;
}
/**
* returns the bounding box for this entity
*/
public AxisAlignedBB getBoundingBox()
{
return this.boundingBox;
}
/**
* Returns true if this entity should push and be pushed by other entities when colliding.
*/
public boolean canBePushed()
{
return true;
}
public EntityBoat(World par1World, double par2, double par4, double par6)
{
this(par1World);
this.setPosition(par2, par4 + (double)this.yOffset, par6);
this.motionX = 0.0D;
this.motionY = 0.0D;
this.motionZ = 0.0D;
this.prevPosX = par2;
this.prevPosY = par4;
this.prevPosZ = par6;
}
/**
* Returns the Y offset from the entity's position for any entity riding this one.
*/
public double getMountedYOffset()
{
return (double)this.height * 0.0D - 0.30000001192092896D;
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
{
if (this.func_85032_ar())
{
return false;
}
else if (!this.worldObj.isRemote && !this.isDead)
{
this.setForwardDirection(-this.getForwardDirection());
this.setTimeSinceHit(10);
this.setDamageTaken(this.getDamageTaken() + par2 * 10);
this.setBeenAttacked();
if (par1DamageSource.getEntity() instanceof EntityPlayer && ((EntityPlayer)par1DamageSource.getEntity()).capabilities.isCreativeMode)
{
this.setDamageTaken(100);
}
if (this.getDamageTaken() > 40)
{
if (this.riddenByEntity != null)
{
this.riddenByEntity.mountEntity(this);
}
this.dropItemWithOffset(Item.boat.shiftedIndex, 1, 0.0F);
this.setDead();
}
return true;
}
else
{
return true;
}
}
@SideOnly(Side.CLIENT)
/**
* Setups the entity to do the hurt animation. Only used by packets in multiplayer.
*/
public void performHurtAnimation()
{
this.setForwardDirection(-this.getForwardDirection());
this.setTimeSinceHit(10);
this.setDamageTaken(this.getDamageTaken() * 11);
}
/**
* Returns true if other Entities should be prevented from moving through this Entity.
*/
public boolean canBeCollidedWith()
{
return !this.isDead;
}
@SideOnly(Side.CLIENT)
/**
* Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX,
* posY, posZ, yaw, pitch
*/
public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9)
{
if (this.field_70279_a)
{
this.boatPosRotationIncrements = par9 + 5;
}
else
{
double var10 = par1 - this.posX;
double var12 = par3 - this.posY;
double var14 = par5 - this.posZ;
double var16 = var10 * var10 + var12 * var12 + var14 * var14;
if (var16 <= 1.0D)
{
return;
}
this.boatPosRotationIncrements = 3;
}
this.boatX = par1;
this.boatY = par3;
this.boatZ = par5;
this.boatYaw = (double)par7;
this.boatPitch = (double)par8;
this.motionX = this.velocityX;
this.motionY = this.velocityY;
this.motionZ = this.velocityZ;
}
@SideOnly(Side.CLIENT)
/**
* Sets the velocity to the args. Args: x, y, z
*/
public void setVelocity(double par1, double par3, double par5)
{
this.velocityX = this.motionX = par1;
this.velocityY = this.motionY = par3;
this.velocityZ = this.motionZ = par5;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
super.onUpdate();
if (this.getTimeSinceHit() > 0)
{
this.setTimeSinceHit(this.getTimeSinceHit() - 1);
}
if (this.getDamageTaken() > 0)
{
this.setDamageTaken(this.getDamageTaken() - 1);
}
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
byte var1 = 5;
double var2 = 0.0D;
for (int var4 = 0; var4 < var1; ++var4)
{
double var5 = this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) * (double)(var4 + 0) / (double)var1 - 0.125D;
double var7 = this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) * (double)(var4 + 1) / (double)var1 - 0.125D;
AxisAlignedBB var9 = AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(this.boundingBox.minX, var5, this.boundingBox.minZ, this.boundingBox.maxX, var7, this.boundingBox.maxZ);
if (this.worldObj.isAABBInMaterial(var9, Material.water))
{
var2 += 1.0D / (double)var1;
}
}
double var24 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
double var6;
double var8;
if (var24 > 0.26249999999999996D)
{
var6 = Math.cos((double)this.rotationYaw * Math.PI / 180.0D);
var8 = Math.sin((double)this.rotationYaw * Math.PI / 180.0D);
for (int var10 = 0; (double)var10 < 1.0D + var24 * 60.0D; ++var10)
{
double var11 = (double)(this.rand.nextFloat() * 2.0F - 1.0F);
double var13 = (double)(this.rand.nextInt(2) * 2 - 1) * 0.7D;
double var15;
double var17;
if (this.rand.nextBoolean())
{
var15 = this.posX - var6 * var11 * 0.8D + var8 * var13;
var17 = this.posZ - var8 * var11 * 0.8D - var6 * var13;
this.worldObj.spawnParticle("splash", var15, this.posY - 0.125D, var17, this.motionX, this.motionY, this.motionZ);
}
else
{
var15 = this.posX + var6 + var8 * var11 * 0.7D;
var17 = this.posZ + var8 - var6 * var11 * 0.7D;
this.worldObj.spawnParticle("splash", var15, this.posY - 0.125D, var17, this.motionX, this.motionY, this.motionZ);
}
}
}
double var12;
double var26;
if (this.worldObj.isRemote && this.field_70279_a)
{
if (this.boatPosRotationIncrements > 0)
{
var6 = this.posX + (this.boatX - this.posX) / (double)this.boatPosRotationIncrements;
var8 = this.posY + (this.boatY - this.posY) / (double)this.boatPosRotationIncrements;
var26 = this.posZ + (this.boatZ - this.posZ) / (double)this.boatPosRotationIncrements;
var12 = MathHelper.wrapAngleTo180_double(this.boatYaw - (double)this.rotationYaw);
this.rotationYaw = (float)((double)this.rotationYaw + var12 / (double)this.boatPosRotationIncrements);
this.rotationPitch = (float)((double)this.rotationPitch + (this.boatPitch - (double)this.rotationPitch) / (double)this.boatPosRotationIncrements);
--this.boatPosRotationIncrements;
this.setPosition(var6, var8, var26);
this.setRotation(this.rotationYaw, this.rotationPitch);
}
else
{
var6 = this.posX + this.motionX;
var8 = this.posY + this.motionY;
var26 = this.posZ + this.motionZ;
this.setPosition(var6, var8, var26);
if (this.onGround)
{
this.motionX *= 0.5D;
this.motionY *= 0.5D;
this.motionZ *= 0.5D;
}
this.motionX *= 0.9900000095367432D;
this.motionY *= 0.949999988079071D;
this.motionZ *= 0.9900000095367432D;
}
}
else
{
if (var2 < 1.0D)
{
var6 = var2 * 2.0D - 1.0D;
this.motionY += 0.03999999910593033D * var6;
}
else
{
if (this.motionY < 0.0D)
{
this.motionY /= 2.0D;
}
this.motionY += 0.007000000216066837D;
}
if (this.riddenByEntity != null)
{
this.motionX += this.riddenByEntity.motionX * this.field_70276_b;
this.motionZ += this.riddenByEntity.motionZ * this.field_70276_b;
}
var6 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
if (var6 > 0.35D)
{
var8 = 0.35D / var6;
this.motionX *= var8;
this.motionZ *= var8;
var6 = 0.35D;
}
if (var6 > var24 && this.field_70276_b < 0.35D)
{
this.field_70276_b += (0.35D - this.field_70276_B) / 35.0D;
if (this.field_70276_b > 0.35D)
{
this.field_70276_b = 0.35D;
}
}
else
{
this.field_70276_b -= (this.field_70276_b - 0.07D) / 35.0D;
if (this.field_70276_b < 0.07D)
{
this.field_70276_b = 0.07D;
}
}
if (this.onGround)
{
this.motionX *= 0.5D;
this.motionY *= 0.5D;
this.motionZ *= 0.5D;
}
this.moveEntity(this.motionX, this.motionY, this.motionZ);
if (this.isCollidedHorizontally && var24 > 0.2D)
{
if (!this.worldObj.isRemote)
{
this.setDead();
int var25;
for (var25 = 0; var25 < 3; ++var25)
{
this.dropItemWithOffset(Block.planks.blockID, 1, 0.0F);
}
for (var25 = 0; var25 < 2; ++var25)
{
this.dropItemWithOffset(Item.stick.shiftedIndex, 1, 0.0F);
}
}
}
else
{
this.motionX *= 0.9900000095367432D;
this.motionY *= 0.949999988079071D;
this.motionZ *= 0.9900000095367432D;
}
this.rotationPitch = 0.0F;
var8 = (double)this.rotationYaw;
var26 = this.prevPosX - this.posX;
var12 = this.prevPosZ - this.posZ;
if (var26 * var26 + var12 * var12 > 0.001D)
{
var8 = (double)((float)(Math.atan2(var12, var26) * 180.0D / Math.PI));
}
double var14 = MathHelper.wrapAngleTo180_double(var8 - (double)this.rotationYaw);
if (var14 > 20.0D)
{
var14 = 20.0D;
}
if (var14 < -20.0D)
{
var14 = -20.0D;
}
this.rotationYaw = (float)((double)this.rotationYaw + var14);
this.setRotation(this.rotationYaw, this.rotationPitch);
if (!this.worldObj.isRemote)
{
List var16 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D));
int var27;
if (var16 != null && !var16.isEmpty())
{
for (var27 = 0; var27 < var16.size(); ++var27)
{
Entity var18 = (Entity)var16.get(var27);
if (var18 != this.riddenByEntity && var18.canBePushed() && var18 instanceof EntityBoat)
{
var18.applyEntityCollision(this);
}
}
}
for (var27 = 0; var27 < 4; ++var27)
{
int var28 = MathHelper.floor_double(this.posX + ((double)(var27 % 2) - 0.5D) * 0.8D);
int var19 = MathHelper.floor_double(this.posZ + ((double)(var27 / 2) - 0.5D) * 0.8D);
for (int var20 = 0; var20 < 2; ++var20)
{
int var21 = MathHelper.floor_double(this.posY) + var20;
int var22 = this.worldObj.getBlockId(var28, var21, var19);
int var23 = this.worldObj.getBlockMetadata(var28, var21, var19);
if (var22 == Block.snow.blockID)
{
this.worldObj.setBlockWithNotify(var28, var21, var19, 0);
}
else if (var22 == Block.waterlily.blockID)
{
Block.waterlily.dropBlockAsItemWithChance(this.worldObj, var28, var21, var19, var23, 0.3F, 0);
this.worldObj.setBlockWithNotify(var28, var21, var19, 0);
}
}
}
if (this.riddenByEntity != null && this.riddenByEntity.isDead)
{
this.riddenByEntity = null;
}
}
}
}
public void updateRiderPosition()
{
if (this.riddenByEntity != null)
{
double var1 = Math.cos((double)this.rotationYaw * Math.PI / 180.0D) * 0.4D;
double var3 = Math.sin((double)this.rotationYaw * Math.PI / 180.0D) * 0.4D;
this.riddenByEntity.setPosition(this.posX + var1, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ + var3);
}
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) {}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) {}
/**
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
*/
public boolean interact(EntityPlayer par1EntityPlayer)
{
if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer && this.riddenByEntity != par1EntityPlayer)
{
return true;
}
else
{
if (!this.worldObj.isRemote)
{
par1EntityPlayer.mountEntity(this);
}
return true;
}
}
/**
* Sets the damage taken from the last hit.
*/
public void setDamageTaken(int par1)
{
this.dataWatcher.updateObject(19, Integer.valueOf(par1));
}
@SideOnly(Side.CLIENT)
public float getShadowSize()
{
return 0.0F;
}
/**
* Gets the damage taken from the last hit.
*/
public int getDamageTaken()
{
return this.dataWatcher.getWatchableObjectInt(19);
}
/**
* Sets the time to count down from since the last time entity was hit.
*/
public void setTimeSinceHit(int par1)
{
this.dataWatcher.updateObject(17, Integer.valueOf(par1));
}
/**
* Gets the time since the last hit.
*/
public int getTimeSinceHit()
{
return this.dataWatcher.getWatchableObjectInt(17);
}
/**
* Sets the forward direction of the entity.
*/
public void setForwardDirection(int par1)
{
this.dataWatcher.updateObject(18, Integer.valueOf(par1));
}
/**
* Gets the forward direction of the entity.
*/
public int getForwardDirection()
{
return this.dataWatcher.getWatchableObjectInt(18);
}
@SideOnly(Side.CLIENT)
public void func_70270_d(boolean par1)
{
this.field_70279_a = par1;
}
}
Now there are several changes we are going to have to make to this class to have it be drivable on land. First off we will need to get rid of anything making it a boat, and then make sure we can also use our own image for our vehicle.
Step 1. At line 237 in eclipse if you have just copied and pasted you minecraft entityboat class you will see this bit of code here.
This is step 1 to allowing the boat to beable to be spawned on the grass or any other block really.
Step 2. Since we do not plan to drive this car on water, we really do not need the code for spawning splash particles, do we. So the next bit of code to change is this. In line 253 in the entityboat class you will find this...
Just go ahead and delete those, if not the vehicle will not move. This code is for the boat should it actually spawn on the ground it will stop dead and not move at all, so get rid of it.
Step 4. Adding the code we need to make our boat into our car, or at least using our own texture.
We need to add the texture path and change the yOffset so that our vegicle doesn't sink into the ground and become useless, making it look like this...
public EntityLandBoat(World par1World)
{
super(par1World);
this.field_70279_a = true;
this.field_70276_b = 0.07D;
this.preventEntitySpawning = true;
this.texture = "/your/texturepath/here/boat.png";
(I used the boat model because after all we are using the boat as a base)
this.setSize(1.7F, 1.4F);
this.yOffset = this.height / 2.0F + 0.2F;
}
Now there is only one more thing to add to the entity class so our image is rendered, and that is to call our model base.
beneath public EntityLandBoat(World par1World) we add this
public ModelBase getModel()
{
return new ModelLandBoat();
}
Moving on to the model class, I just copied and pasted the model from the boat and renamed it to my model, it looks like this
The last and one of the most important things is the render class, without this you will not have a car at all
This is the render of the boat...
public class RenderBoat extends Render
{
/** instance of ModelBoat for rendering */
protected ModelBase modelBoat;
public RenderBoat()
{
this.shadowSize = 0.5F;
this.modelBoat = new ModelBoat();
}
/**
* The render method used in RenderBoat that renders the boat model.
*/
public void renderBoat(EntityBoat par1EntityBoat, double par2, double par4, double par6, float par8, float par9)
{
GL11.glPushMatrix();
GL11.glTranslatef((float)par2, (float)par4, (float)par6);
GL11.glRotatef(180.0F - par8, 0.0F, 1.0F, 0.0F);
float var10 = (float)par1EntityBoat.getTimeSinceHit() - par9;
float var11 = (float)par1EntityBoat.getDamageTaken() - par9;
if (var11 < 0.0F)
{
var11 = 0.0F;
}
if (var10 > 0.0F)
{
GL11.glRotatef(MathHelper.sin(var10) * var10 * var11 / 10.0F * (float)par1EntityBoat.getForwardDirection(), 1.0F, 0.0F, 0.0F);
}
this.loadTexture("/terrain.png");
float var12 = 0.75F;
GL11.glScalef(var12, var12, var12);
GL11.glScalef(1.0F / var12, 1.0F / var12, 1.0F / var12);
this.loadTexture("/item/boat.png");
GL11.glScalef(-1.0F, -1.0F, 1.0F);
this.modelBoat.render(par1EntityBoat, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
GL11.glPopMatrix();
}
/**
* Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
* handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
* (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
* double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
*/
public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
{
this.renderBoat((EntityBoat)par1Entity, par2, par4, par6, par8, par9);
}
}
Once you have completed all this, you should now have a working land boat, or SIMPLE vehicle as I have stated. The controls will again be a bit sloppy, but it will work. If you have trouble getting this to work I have included my finished code here at the bottom.....
public class RenderLandBoat extends Render
{
/** instance of ModelBoat for rendering */
protected ModelBase modelBoat;
public RenderLandBoat()
{
this.shadowSize = 0.5F;
this.modelBoat = new ModelLandBoat();
}
/**
* The render method used in RenderBoat that renders the boat model.
*/
public void renderBoat(EntityLandBoat par1EntityLandBoat, double par2, double par4, double par6, float par8, float par9)
{
this.modelBoat = par1EntityLandBoat.getModel();
GL11.glPushMatrix();
GL11.glTranslatef((float)par2, (float)par4, (float)par6);
GL11.glRotatef(180.0F - par8, 0.0F, 1.0F, 0.0F);
float var10 = (float)par1EntityLandBoat.getTimeSinceHit() - par9;
float var11 = (float)par1EntityLandBoat.getDamageTaken() - par9;
if (var11 < 0.0F)
{
var11 = 0.0F;
}
if (var10 > 0.0F)
{
GL11.glRotatef(MathHelper.sin(var10) * var10 * var11 / 10.0F * (float)par1EntityLandBoat.getForwardDirection(), 1.0F, 0.0F, 0.0F);
}
this.loadTexture("/item/boat.png");
GL11.glScalef(-1.0F, -1.0F, 1.0F);
this.modelBoat.render(par1EntityLandBoat, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
GL11.glPopMatrix();
}
/**
* Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
* handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
* (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
* double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
*/
public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
{
this.renderBoat((EntityLandBoat)par1Entity, par2, par4, par6, par8, par9);
}
}
Vehicle tutorial is now available, soon I will show how to do a simple remake of the furnace, chest, and crafting table. I will do others too, as soon as I figure out some other things that there are no tutorials for either directly or indirectly, I will be working to figure out forge ILiquid, and possibly potions too. Dont ask or try to rush me, some of these things take time and with no knowledge of these things, being that there are no tutorials to go by or information to find anywhere it may take longer. Be patient....
Just working out the bugs in crafting table, furnace will be up tomorrow, and soon a multi-biome world type. I will take requests for unique tuts, nothing already done and in vast amount on the forum already, its redundant and I wont be a part of it. I am trying to work out a few things with liquids yet in forge and hopefully a new potion.
I am moving to a new thread or possibly on a new web page and leave links here, this site is acting weird and I have too much invested in doing these to have it bark at me about space.....
Maybe could u think about making a Gun tuturial?? if you choose to email me at [email protected] or pm on planetminecraft or here.
planetminecraft user: XZOzerTY
i dont go on minecraft forums much
i will give u credit in my mod
lots of credit for the veichle tut! (my mod is not yet released but when so it is going to be very awesome)
Rollback Post to RevisionRollBack
My name is Pronounced as X-Oh-Zer-Tee, and i am offended when You spell it as ozer.
I am still figuring out the gun stuff in its entirety myself, so no plans to do a gun tut sorry. Perhaps one of the nice people who have made a gun mod can help you, it never hurts to ask...
Would you happen to know how one might apply particle Animations to a player when they walk?
Basically, I need it to check if a player meets a certain criteria (might be an item, a title, or something like that) and apply the particle around them if they meet that criteria.
Hi! I was having trouble implementing a vehicle. I had a problem where no matter what I did, my model would be the same white rectangle, so I followed this tutorial, hoping that it would work. However, I get the same thing as my other model. Can you check that your tutorial still works? (The vehicle one.)
The code is an exact copy of yours, at least from what I can tell. Thanks.
Rollback Post to RevisionRollBack
Here is my signature. If you like it, I am amazed.
Yes my tut still works. I have made four odd boats in my new mod coming soon using this formula. You should really check your entity class and render class again and compare them to the finished ones I have at the bottom of the tutorial. Also check to see that you registered your vehicle properly...
Most of any of the information I post here will now be for forge, though you can most certainly get them to work one way or another in modloader, for example the particles tut is for modloader, but mostly its pretty basic and will work in forge just as easy.
Particles
Particle modding isn't that hard as I found out, it's all in the way you setup your basic mod. This is a simple tutorial that I have created to show you how to create a mod_whatever.class and Block.class to create particles from blocks. I have searched high and low, and found that answers that come aren't always clear, tutorials are rare for this, and videos are just as rare. Anyhow, this tutorial will show you how to decorate your blocks for the beginning modder.
First lets start with the mod_whatever.class
Now for the Block class.......
Popgalop has a wonderful tutorial on custom particles here... and if you want to add more than one particle all you have to do is add more if statements to the class like this
If you copy the code for your custom particle from reddust or the hearts or bubbles, you can point to your custom particle, but as long as they are on individual 8x8 textures. If you want more than one custom particle and all custom particles on one sheet you should use this code in your particle FX class
All of your custom particles have to be 8x8 or they will not work....
Please.... Do Not just copy and paste this, copy it down on paper, the retype it into eclipse and you will learn it better. Particles are fun to play with and can be decorative. But without writing your own ParticleFX classes for each particle, which I don not know how to do yet, your effects are limited to their current color, and how long they last. They can be manipulated to a point, but that is about it. This tutorial works for 1.2.5 and should be okay for 1.3.x versions as well with a little manipulating. Have fun and enjoy......Microjunk
Grenades forge
I have wrote this tutorial because in search of a good tut on grenades, especially for forge, they just don't exists. At best, they are 60% complete.
Files you will need:
Things you will need....
A client proxy
an entity class
an item class
a render class
a mod class
Lets first start by saying this is done using modified code from the snowball, the following is the item from the snowball
We take this file and turn it into this
grenade item
Which is pretty much the same, except that we change the entity for our own, and call our texture file
snowball entity
Which we turn into this
Entity Grenade
But it looks again the same, with minor changes
render snowball
which gets turned into this....
As you can see once again only small changes to the code, one thing to note though is that the potion helper portion was removed. It will error if you dont, and it is not really needed anyhow. Also note that the texture call has been changed as well so we can pull our own texture...
In the client proxy we need to add this to our register render area
this is equivalent to the add renderer to you mod class of a modloader mod. Make sure you change the 1 to what ever your location of your grenade.
Add this line of code to your mod class to register the entity in your mod class in forge....
The 550, is the ID of your grenade item, the rest you should know from registering any entity in mnecraft modding.
this should be a pretty complete tutorial, just ask if I missed something and I will try my best to fill in the blanks.
Forge Vehicle 1.4.6
This tutorial, like the others, will not be very fulfilling as far as detailed explanation. Sorry, I don't have the extreme knowledge and understanding it takes to explain it all. This one especially will be less informative than the others. I have only been able to do this with the little help and pointers I received from the forums members. That, and just playing with the numbers and deleting the few irrelevant lines of code I have been able to make a simple "Car" that drives on land. The controls are a bit sloppy because it is modified boat code. If you want a better car, I suggest trying to find and replace the control code with the code from the pig and perhaps that or this tutorial here (post #617) may help, though it is a much older tutorial. Search through the thread because there are a few updates to the tutorial and some better code. I have done this because it just does not totally work, there are quite a few problems with it, more so than I cared to fix and found doing this was a better way to make a SIMPLE vehicle.
Okay first we will need to get the relevant files we need from minecraft and they are....
ItemBoat
EntityBoat
ModelBoat
RenderBoat
Looking at ItemBoat:
In this class you will notice on line 92, where the entity spawning comes in to action it says this
You will need to change that to your entity and also your class name should be different as well. I call mine landboat for this tutorial...And this is what my ItemLandBoat looks like.
So moving right along when we look at our current code we should now have a red underline under entitylandboat (or whatever you choose to call your vehicle) asking us to create a new class, lets do so now and have a look at the entityboat class.
Now there are several changes we are going to have to make to this class to have it be drivable on land. First off we will need to get rid of anything making it a boat, and then make sure we can also use our own image for our vehicle.
Step 1. At line 237 in eclipse if you have just copied and pasted you minecraft entityboat class you will see this bit of code here.
Change that so it now looks like this
This is step 1 to allowing the boat to beable to be spawned on the grass or any other block really.
Step 2. Since we do not plan to drive this car on water, we really do not need the code for spawning splash particles, do we. So the next bit of code to change is this. In line 253 in the entityboat class you will find this...
We can change this to look like this and we will no longer have to worry about thos funny looking particles floating around...
Step 3. At lines 304 and 368 in the entityboat class you will find this bit of code here...
Just go ahead and delete those, if not the vehicle will not move. This code is for the boat should it actually spawn on the ground it will stop dead and not move at all, so get rid of it.
Step 4. Adding the code we need to make our boat into our car, or at least using our own texture.
In the first constructor
We need to add this bit of code
Then in the next section
We need to add the texture path and change the yOffset so that our vegicle doesn't sink into the ground and become useless, making it look like this...
Now there is only one more thing to add to the entity class so our image is rendered, and that is to call our model base.
beneath public EntityLandBoat(World par1World) we add this
Moving on to the model class, I just copied and pasted the model from the boat and renamed it to my model, it looks like this
The last and one of the most important things is the render class, without this you will not have a car at all
This is the render of the boat...
At line 20 you will find this code here
Change that to this
Change line 27
to look like this
And then add this line here to line 28 in your render class
Now for rendering your texture you have to change this code here
To this here
Then of course this
Will now need to look like this
Now for the mod class and client class in you base mod you will need to add the following codes to register you land boat
client class
And in your mod class you need the following
Once you have completed all this, you should now have a working land boat, or SIMPLE vehicle as I have stated. The controls will again be a bit sloppy, but it will work. If you have trouble getting this to work I have included my finished code here at the bottom.....
Item Class
Entity Class
Model Class
And The Render Class
Have fun and enjoy your vehicle
Find out how I generate....coolAlias...world structure generation and rotation tool...
Find out how I generate....coolAlias...world structure generation and rotation tool...
Find out how I generate....coolAlias...world structure generation and rotation tool...
Find out how I generate....coolAlias...world structure generation and rotation tool...
Find out how I generate....coolAlias...world structure generation and rotation tool...
Find out how I generate....coolAlias...world structure generation and rotation tool...
Merry Christmas!
Find out how I generate....coolAlias...world structure generation and rotation tool...
Find out how I generate....coolAlias...world structure generation and rotation tool...
Find out how I generate....coolAlias...world structure generation and rotation tool...
Find out how I generate....coolAlias...world structure generation and rotation tool...
Find out how I generate....coolAlias...world structure generation and rotation tool...
Look for my furnace tut here.....
Find out how I generate....coolAlias...world structure generation and rotation tool...
planetminecraft user: XZOzerTY
i dont go on minecraft forums much
i will give u credit in my mod
lots of credit for the veichle tut! (my mod is not yet released but when so it is going to be very awesome)
Find out how I generate....coolAlias...world structure generation and rotation tool...
Basically, I need it to check if a player meets a certain criteria (might be an item, a title, or something like that) and apply the particle around them if they meet that criteria.
Thanks for any advice!
-Cere
Find out how I generate....coolAlias...world structure generation and rotation tool...
The code is an exact copy of yours, at least from what I can tell. Thanks.
Find out how I generate....coolAlias...world structure generation and rotation tool...