UPDATED 8/23/2011 - 9:50pm EST
Ok, people have been asking me about this, so I am going to post my (not finished yet, but working) code for my tameable mobs. These super class (when you want this functionality, have your entity class extend this one) will allow you to tame mobs, rename them (you will have to do your own render code for like my last post if you want the names to show), mount them, and have them follow you around (as long as you don't get too far). I'm going to try and past only the code that is finished. I still need to do the save stuff, so the stats and such stay with (tame, owned) mobs, as well as the hostile code, and hopefully the pack animal code. That means that this thread will change several times. I will post what is working, and what is in the works. That said,
inLanoche's Tamable Entity class V0.7
Please read the whole post. Features:
- tamable when given favourite item. mood boost can be defined, as well as mood needed to tame. Most other features require taming (but this can be overrided) COMPLETE
- Once tamed, GUI interface when interacting with the mob. COMPLETE
- Can name/rename through GUI. COMPLETE
- Toggle for mountable. Can also depend on having an item in hand. Item is not consumed, may change to item is in iventory, istead of having to be equiped. COMPLETE
- Toggle follow/don't follow behaviour through GUI. Mob must be within range, and can see you, or will stop following. COMPLETE
- Various levels of hostility, from doesn't attack, to attacks only players, to attacks anything that moves. Might also work in that it attacks one specific mob type only (hunting). INCOMPLETE
- Make it attack monster type mobs when tamed, can set the attack strength. INCOMPLETE
- Can set it's carry capacity, and through GUI can get to it's inventory menu. COMPLETE - Thanks to killNature!
- Flying or not flying - Might drop this, as it seems quite easy to add this in the sub class. I could just add a sub to this for flying and release that as well, with customizable wing flapping.
- Usable age. Can be used to scale the model, as well as allow for beging ridable after a certain age. COMPLETE
- Saving/Loading of Tamed mobs and their stats INCOMPLETE WIP
- Patroling an area (4 waypoints) COMPLETE - Thanks to McDog3!
Thems the features,for now. Here is a taste of the (not complete yet) code. I've tried to comment so that you can make your own changes in your sub class, and do what you want.
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) braces deadcode
/*JWorld_TamableEntiy class
* 19 Aug 2011
* http://www.minecraftforum.net/topic/529327-modloader-adding-custom-mobs-and-more/
*
* NEEDED support java files:
* JWorldGUICreatureInteract.java, JWorld_TamableRender.java, KeyBinding in your main mod_ java file.
*/
package net.minecraft.src;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import net.minecraft.client.Minecraft;
// Referenced classes of package net.minecraft.src:
// EntityAnimal, World, Item, NBTTagCompound
public class JWorld_TamableEntity extends EntityAnimal
{
//fields that are needed for all tameable mobs. Tie in to tameable menus
public String entityType; //used for the menus and other checks
public int hostile; //if the mob will attack other mobs or not. -1 not hostile, 0 attacks player only, 1 attacks any other mob
public String ownerName; //String name for the owner, if it is the player
public int mountable; //flag to see if you can mount this mob. -2 means never, 0 means need item, 1 means yes.
public int favItem; //What they like (to tame them) set the to -1 for no possible taming
public int favBoost; //how much it boosts the mood
public int mood; //how happy it is. When mood exceeds tamemood, the mob is tamed
public int tamemood; //how much mood needed to tame it
public int MountItem; //What is needed to mount them
public String myName; //if it's tamed you can name it
public boolean fly; //flag for if this mob can fly
public boolean leap; //used for flying mount control
public int myAge; //age of the mob, only really tracked in tamed mobs
public int maxAge; //age when full size
public float maxSpeed; //as fast as it goes normally
public int attackStrength; //how much damage this inflicts when it attacks. Can be scaled by age
public int maxStrength; //basic str. value
private World worldObj;
public float sizeX;
public float sizeY;
public boolean hasHead;
public static String behaveList[] = {"None", "Follow", "Defend", "Hunt", "HuntPlayer"}; //behaviors that can be set
public int myBehavior = 0;
public JWorld_TamableEntity(World world)
{
super(world);
sizeX = 1F; //set and do not change!
sizeY = 1F; //set and do not change!
texture = "/mob/char.png"; //texture needs to be set in sub class
setSize(sizeX, sizeY); //USE sizeX and sizeY to initialize this!
health = 10; //keep defaults
maxSpeed = 1.5F; //basic unmodified speed
moveSpeed = maxSpeed;
worldObj = world; //get the world object
//***set vars for tamable mobs***
entityType = ""; //set in sub class, bread name of creature
hostile = -1; //will it attack the player/other mobs or not.
ownerName = ""; //needed for finding player by owner
mountable = -2; //default to not possible
favItem = -1; //leave it negative, meaning not possible to tame. Based on Item.shiftedIndex
favBoost = 1; //default boost of 1 to mood.
mood = 0; //negative is angry, positive is happy. 10 will tame?
tamemood = 10; //how much needed to tame it
MountItem = -1; //-1 means no item needed if mountable. Based on Item.shiftedIndex
myName = ""; //Leave it un-named to not render name tag.
fly = false; //can it fly or not
leap = false; //for flying mounts
myAge = 1; //can be used for scaling and other age related code
maxAge = 10; //age when fully grown (can be older)
attackStrength = 2; //base attack strength, can be modified by age
inventory = new JWorld_TamableInventory(this);
}
//START:Age and scaling code-------------------------------------------------
public float getAgeScale()
{
//this will return a scale value that can be passed to the render java file to set a scale by age
//this should also be applied to setSize to fix bounding box. Not used by default
//Set the age scale yourself! These are my defaults
int age = getAge();
float scaler = 1F;
scaler = (float)age/(float)maxAge;
if(scaler <= 0.5) //set minimum scale factor
{
return 0.5F;
}
if(scaler <= 0.9) //medium size scale factor
{
return 0.75F;
}
return 1.25F; //if not then full size
}
public void updateAge()
{
//should be run every time the age is updated to fix speed, bounding box, etc.
float aScale = getAgeScale(); //how much to scale based on myAge vs maxAge
setSize(sizeX*aScale,sizeY*aScale); //the only way the size should change, do not adjust sizeX and sizeY after constructor
moveSpeed = maxSpeed*aScale; //scale movement to size
attackStrength = (int)(maxStrength * aScale);
if(attackStrength < 1) attackStrength = 1; //cannot be less that 1
}
//END:Age and scaling code-----------------------------------------------------
protected boolean canDespawn()
{
if(ownerName != "") //means it's owned
{
return true; //means should stay in the game
}
return true; //else... see ya!
}
//START:Inventory code-----------------------------------------------------------
public JWorld_TamableInventory inventory; //inventory object for tamable pack animals
public void openInventory(EntityPlayer theplayer)
{
ModLoader.OpenGUI(theplayer, new JWorld_TamableInvGui(theplayer, this));
}
public void onDeath(Entity entity) //when mob dies
{
inventory.dropAllItems(); // when dead drop all inventory! **
super.onDeath(entity);
}
//END:Inventory code-----------------------------------------------------------
//START: Update code. Put stuff here that needs to be constantly checked-----------------
public void onLivingUpdate()
{
//Halting movement if ridden
if(riddenByEntity != null) //ridden overrides all
{
//halt attempts to move or look around, reset behavior
setBehavior(0);
moveStrafing = 0;
moveForward = 0;
randomYawVelocity = 0;
defaultPitch = 0;
this.rotationYaw = this.prevRotationYaw; // keep head straight
this.rotationPitch = 0; // keep head straight
if(riddenByEntity.rotationYaw < (riddenByEntity.prevRotationYaw - 45) || riddenByEntity.rotationYaw > (riddenByEntity.prevRotationYaw + 45))
{
rotationYaw = riddenByEntity.rotationYaw;
}
//mod_JWorld.mountYaw = this.rotationYaw; //inLanoche's test code
}else//end of riding code
{
//mod_JWorld.mountYaw = 0; //inLanoche's test code
//manage what each behavior level does
if(getBehavior() == 1) Following();
if(getBehavior() == 2) DefendHere();
//standard movement stuff below
if(newPosRotationIncrements > 0)
{
double d = posX + (newPosX - posX) / (double)newPosRotationIncrements;
double d1 = posY + (newPosY - posY) / (double)newPosRotationIncrements;
double d2 = posZ + (newPosZ - posZ) / (double)newPosRotationIncrements;
double d3;
for(d3 = newRotationYaw - (double)rotationYaw; d3 < -180D; d3 += 360D) { }
for(; d3 >= 180D; d3 -= 360D) { }
rotationYaw += d3 / (double)newPosRotationIncrements;
rotationPitch += (newRotationPitch - (double)rotationPitch) / (double)newPosRotationIncrements;
newPosRotationIncrements--;
setPosition(d, d1, d2);
setRotation(rotationYaw, rotationPitch);
List list1 = worldObj.getCollidingBoundingBoxes(this, boundingBox.contract(0.03125D, 0.0D, 0.03125D));
if(list1.size() > 0)
{
double d4 = 0.0D;
for(int j = 0; j < list1.size(); j++)
{
AxisAlignedBB axisalignedbb = (AxisAlignedBB)list1.get(j);
if(axisalignedbb.maxY > d4)
{
d4 = axisalignedbb.maxY;
}
}
d1 += d4 - boundingBox.minY;
setPosition(d, d1, d2);
}
}
if(isMovementBlocked())
{
isJumping = false;
moveStrafing = 0.0F;
moveForward = 0.0F;
randomYawVelocity = 0.0F;
} else
if(!isMultiplayerEntity)
{
updateEntityActionState();
}
boolean flag = isInWater();
boolean flag1 = handleLavaMovement();
if(isJumping)
{
if(flag)
{
motionY += 0.039999999105930328D;
} else
if(flag1)
{
motionY += 0.039999999105930328D;
} else
if(onGround)
{
jump();
}
}
moveStrafing *= 0.98F;
moveForward *= 0.98F;
randomYawVelocity *= 0.9F;
}
//This below should stay the same
moveEntityWithHeading(moveStrafing, moveForward);
List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D));
if(list != null && list.size() > 0)
{
for(int i = 0; i < list.size(); i++)
{
Entity entity = (Entity)list.get(i);
if(entity.canBePushed())
{
entity.applyEntityCollision(this);
}
}
}
}
//END: Update code. Put stuff here that needs to be constantly checked-----------------
//START: Manage movement code------------------------------------------------------
protected boolean canTriggerWalking()
{
return false;
}
public void moveEntity(double d, double d1, double d2)
{
if(riddenByEntity != null)
{
isJumping = false; //seems to want to jump around by itself
rotationYaw = riddenByEntity.rotationYaw; //set rotation as you move.
if(leap)
{//have it fly up a bit
motionX += riddenByEntity.motionX*moveSpeed; //Should find a way to set this to normal mob speed
motionZ += riddenByEntity.motionZ*moveSpeed; //ditto
motionY += 1F;
leap = false;
}else
{//regular run on the ground movement
motionX += riddenByEntity.motionX*moveSpeed; //ditto
motionZ += riddenByEntity.motionZ*moveSpeed; //ditto
if(onGround)
{
motionY = 0; //for some reason it likes to hop
}
}
if(isCollidedHorizontally)
{
if(fly) //if it can fly
{
motionY += 0.15F; //allows it to drift up if you are hitting an obstacle in front of you
}else
{
if(onGround) //else not fly
{
jump(); //let it try to jump over obstacle
}
}
}
super.moveEntity(motionX, motionY, motionZ);
}else
{
super.moveEntity(d, d1, d2);
}
}
// from super super class Entity
public void updateRidden()
{
if(ridingEntity.isDead)//if rider is dead, drop it
{
ridingEntity = null;
return;
}
motionX = 0.0D; //set all movement to 0. Let player control it.
motionY = 0.0D;
motionZ = 0.0D;
onUpdate();
if(ridingEntity == null)
{
return;
}
ridingEntity.updateRiderPosition();
//cut a lot from the Entity.updateRidden
//test code:
}
//END: Manage movement code------------------------------------------------------
//START: Player interaction with mob-------------------------------------------
public boolean interact(EntityPlayer entityplayer)
{
ItemStack itemstack = entityplayer.inventory.getCurrentItem(); //see what the interacting player is holding
if(MountItem >= 0 && mountable != -2) //you need an item to mount
{
mountable = 0; //reset mountable in case an item is needed to mount. No cheating!
}
//if you have nothing, and it's not yours, nothing will happen
if(itemstack == null && !ownerName.equalsIgnoreCase(entityplayer.username))
{
return false;
}
//if riding, dismount, no matter what is in hand
if(riddenByEntity != null && riddenByEntity == entityplayer)
{
mountThis(entityplayer);
return true;
}
if(mountable == 0) //if you need an item to mount,
{
for(int j = 0; j < entityplayer.inventory.mainInventory.length; j++)
{
if(entityplayer.inventory.mainInventory[j] != null && entityplayer.inventory.mainInventory[j].itemID == MountItem)
{
mountable = 1;
break;
}
}
}
//if you have nothing, but own this mob, bring up the menu
if((itemstack == null) && ownerName.equalsIgnoreCase(entityplayer.username))
{
//one liner with ModLoader to open GUIs
ModLoader.OpenGUI(entityplayer, new JWorld_TamableGUIMenu(this, entityplayer));
}
//To tame it, you have to give it something it likes, and it can't be already owned, unless by you
if(itemstack != null && itemstack.itemID == favItem && (ownerName == "" || ownerName.equalsIgnoreCase(entityplayer.username)))
{
itemstack.stackSize--; //you give the item
if(itemstack.stackSize <= 0)
{
entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null);
}
setMood(getMood() + favBoost); //boost its mood
if(getMood() >= tamemood) //check if you tamed it
{
setOwner(entityplayer.username);//need this for finding the player in the world
//should call naming GUI at this point
Minecraft mc = ModLoader.getMinecraftInstance();
ParticleFX("heart");
mc.displayGuiScreen(new JWorld_TamableGUIMenu(this, entityplayer)); //Should the GUI pop up the right now?
//maybe use just a naming GUI here...
return true;
}else
{
ParticleFX("note"); //it's happy it got something good
}
return true;
}
return false;
}
//END: Player interaction with mob-------------------------------------------
//START: Call to mount--------------------------------------------------------
public void mountThis(EntityPlayer entityplayer) //use this for mounting from GUI or direct mount
{
if (riddenByEntity == null || riddenByEntity == entityplayer)
{
rotationYaw = entityplayer.rotationYaw;
entityplayer.mountEntity(this); //climb on/get off
}
}
//END: Call to mount--------------------------------------------------------
//START: Behavior management code-----------------------------------------------------
private void Following()
{
float fRange = 18; //outside of follow range
EntityPlayer entityplayer = worldObj.getPlayerEntityByName(ownerName); //has to be done this way, no other method I know
if(entityplayer != null)
{
fRange = getDistanceToEntity(entityplayer);
if(fRange > 5F && fRange < 18F)
{
PathEntity pathentity = worldObj.getPathToEntity(this, entityplayer, 16F);
setPathToEntity(pathentity);
}else
{
setPathToEntity(null); //have it stop following if too close or out of range.
}
}
if(fRange > 18)
{
setPathToEntity(null); //Forget following, no path set.
setBehavior(0); //stop following when too far away
}
}
//track where the patrol path is for defending
private int defendX;
private int defendY;
private int defendZ;
public int nextPoint = 0;
private void DefendHere()
{
int deltaX = 0;
int deltaZ = 0;
if(nextPoint == 0) //waypoint not set yet
{
defendX = (int)posX;
defendY = (int)posY;
defendZ = (int)posZ;
nextPoint = 1;
//world.entityJoinedWorld(new EntityArrow(world, entityplayer));
}
switch(nextPoint)
{//should patrol a 16x16 square around the point where you asked it to defend
case 1: deltaX =-9; deltaZ = 9; break; //top left
case 2: deltaX = 9; deltaZ = 9; break; //top right
case 3: deltaX = 9; deltaZ =-9; break; //bottom right
case 4: deltaX =-9; deltaZ =-9; break; //bottom left
}
PathEntity patrolPath = worldObj.getEntityPathToXYZ(this,defendX+deltaX,defendY,defendZ+deltaZ,18F);
setPathToEntity(patrolPath);
if(Math.abs(posX -(deltaX + defendX)) <= 1 && Math.abs(posZ -(deltaZ + defendZ)) <= 1) nextPoint ++;
if(nextPoint > 4) nextPoint = 1;
}
//END: Behavior management code-----------------------------------------------------
//START: File handling code-------------------------------------------------------
//these need to be used to save tamed/owned creatures - in progress...
protected void entityInit()
{
super.entityInit();
//dataWatcher.addObject(16, Byte.valueOf((byte)0));
dataWatcher.addObject(17, ""); //held for the owner's name
dataWatcher.addObject(18, new Integer(health)); //store current health?
dataWatcher.addObject(19, new Integer(mood)); //store mood - marks if it is tame
dataWatcher.addObject(20, new Integer(myAge));
dataWatcher.addObject(21, new Integer(myBehavior));
}
//Guess should be following this?
public String getOwner()
{
return dataWatcher.getWatchableObjectString(17);
}
public void setOwner(String s)
{
dataWatcher.updateObject(17, s);
ownerName = s;
}
public int getMood()
{
return dataWatcher.getWatchableObjectInt(19);
}
public void setMood(int newmood)
{
dataWatcher.updateObject(19, Integer.valueOf(newmood));
}
public int getAge()
{
return dataWatcher.getWatchableObjectInt(20);
}
public void setAge(int newage)
{
dataWatcher.updateObject(20, Integer.valueOf(newage));
}
public int getBehavior()
{
return dataWatcher.getWatchableObjectInt(21);
}
public void setBehavior(int i)
{
myBehavior = i;
dataWatcher.updateObject(21, Integer.valueOf(myBehavior));
}
public void writeEntityToNBT(NBTTagCompound nbttagcompound)
{
super.writeEntityToNBT(nbttagcompound);
if(getOwner() == "")
{
nbttagcompound.setString("Owner", "");
} else
{
nbttagcompound.setString("Owner", getOwner());
nbttagcompound.setTag("Inventory", inventory.writeToNBT(new NBTTagList())); // it writes the inventory to file
nbttagcompound.setInteger("Mood", getMood());
nbttagcompound.setInteger("Age", getAge());
if(!this.isDead)
{
nbttagcompound.setInteger("myX", (int)posX);
nbttagcompound.setInteger("myY", (int)posY);
nbttagcompound.setInteger("myZ", (int)posZ);
}
}
}
public void readEntityFromNBT(NBTTagCompound nbttagcompound)
{
super.readEntityFromNBT(nbttagcompound);
String s = nbttagcompound.getString("Owner");
if(s.length() > 0)
{
setOwner(s);
//EntityPlayer theplayer = worldObj.getPlayerEntityByName(s);
//owner = theplayer.entityId; //set the id owner
NBTTagList nbttaglist = nbttagcompound.getTagList("Inventory"); // must read inventory
inventory.readFromNBT(nbttaglist);
setMood(nbttagcompound.getInteger("Mood"));
setAge(nbttagcompound.getInteger("Age"));
updateAge();
posX = (double)nbttagcompound.getInteger("myX");
posY = (double)nbttagcompound.getInteger("myY");
posZ = (double)nbttagcompound.getInteger("myZ");
}
}
//inLanoche's attempts at save code with DataSaver class
protected void saveEntity()
{
}
protected void loadEntity()
{
}
//END: File handling code------------------------------------------------------
//START: Audio sounds----------------------------------------------------------
protected String getLivingSound()
{
return "mob.chicken";
}
protected String getHurtSound()
{
return "mob.chickenhurt";
}
protected String getDeathSound()
{
return "mob.chickenhurt";
}
//END: Audio sounds----------------------------------------------------------
protected int getDropItemId()
{
return 0; //set what this drops when it dies
}
//Used for Particle effect when tamed or other particles.
public static ArrayList particleList = new ArrayList();
void ParticleFX(String fx)
{
//these are found in RenderGlobal.java
particleList.add("heart");
particleList.add("smoke");
particleList.add("splash");
particleList.add("note");
particleList.add("flame");
particleList.add("bubble");
String s = fx;
if(particleList.indexOf(fx) < 0)
{
return; //passed an improper particle type and do nothing
}
for(int i = 0; i < 7; i++)
{
double d = rand.nextGaussian() * 0.02D;
double d1 = rand.nextGaussian() * 0.02D;
double d2 = rand.nextGaussian() * 0.02D;
worldObj.spawnParticle(s, (posX + (double)(rand.nextFloat() * width * 2.0F)) - (double)width, posY + 0.5D + (double)(rand.nextFloat() * height), (posZ + (double)(rand.nextFloat() * width * 2.0F)) - (double)width, d, d1, d2);
}
}
}
UPDATED 8/30/2011 - 3:45pm EST
Some class names have changed!
Data saving is almost there. This is a major overhaul of the code, though for the most part should not affect classes that extend this. I have made changes to ALL the support files as well. ***Special thanks to McDog3 helping with the now working Patrol code!
I know that this is really old and all, but I updated parts of it, and fixed some things. I made an entity file, but one problem im having is that my mob will not move, it'll just stand still, and i don't know why. If you can help me send me a pm please, thanks :smile.gif:.
I've got a problem, and I just can't match up what to do in MY Model.java file versus the tutorial's. As in, When my creature spawns in game, the forearms aren't connected to the biceps as they are in the techne file. Would you like me to post my code, so that you can possibly see what I've done? (I'm hoping that this thread is still active in that you see this post!)
I am having trouble resizing my mob! I am able to resize the hitbox on the mob but am not able to get the texture to fit him!
Entity.class
package net.minecraft.src;
import java.util.Random;
public class EntityGummybear extends EntityMob
{{
super.setSize(0.2f, 0.2f);}
public EntityGummybear(World par1World)
{
super(par1World);
super.setSize(0.2f, 0.2f);
texture = "/Gummybear.png";
moveSpeed = 0.23F;
attackStrength = 4;
getNavigator().setBreakDoors(true);
tasks.addTask(0, new EntityAISwimming(this));
tasks.addTask(1, new EntityAIBreakDoor(this));
tasks.addTask(2, new EntityAIAttackOnCollide(this, net.minecraft.src.EntityPlayer.class, moveSpeed, false));
tasks.addTask(3, new EntityAIAttackOnCollide(this, net.minecraft.src.EntityVillager.class, moveSpeed, true));
tasks.addTask(4, new EntityAIMoveTwardsRestriction(this, moveSpeed));
tasks.addTask(5, new EntityAIMoveThroughVillage(this, moveSpeed, false));
tasks.addTask(6, new EntityAIWander(this, moveSpeed));
tasks.addTask(7, new EntityAIWatchClosest(this, net.minecraft.src.EntityPlayer.class, 8F));
tasks.addTask(7, new EntityAILookIdle(this));
targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, net.minecraft.src.EntityPlayer.class, 16F, 0, true));
targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, net.minecraft.src.EntityVillager.class, 16F, 0, false));
}
public int getMaxHealth()
{
return 100;
}
/**
* Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
*/
public int getTotalArmorValue()
{
return 0;
}
/**
* Returns true if the newer Entity AI code should be run
*/
protected boolean isAIEnabled()
{
return false;
}
/**
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
* use this to react to sunlight and start to burn.
*/
public void onLivingUpdate()
{
super.onLivingUpdate();
}
/**
* Returns the sound this mob makes while it's alive.
*/
protected String getLivingSound()
{
return "mob.zombie";
}
/**
* Returns the sound this mob makes when it is hurt.
*/
protected String getHurtSound()
{
return "mob.zombiehurt";
}
/**
* Returns the sound this mob makes on death.
*/
protected String getDeathSound()
{
return "mob.zombiedeath";
}
/**
* Returns the item ID for the item the mob drops on death.
*/
protected int getDropItemId()
{
return Item.rottenFlesh.shiftedIndex;
}
/**
* Get this Entity's EnumCreatureAttribute
*/
public EnumCreatureAttribute getCreatureAttribute()
{
return EnumCreatureAttribute.UNDEAD;
}
protected void dropRareDrop(int par1)
{
switch (rand.nextInt(4))
{
case 0:
dropItem(Item.swordSteel.shiftedIndex, 1);
break;
case 1:
dropItem(Item.helmetSteel.shiftedIndex, 1);
break;
case 2:
dropItem(Item.ingotIron.shiftedIndex, 1);
break;
case 3:
dropItem(Item.shovelSteel.shiftedIndex, 1);
break;
}
}
}
Im using the controllable vehicles tutorial for 1.3.2. I can make the mob turn, but not go forwards or backward. Sorry for bumping.
Check my tut for vehicles, its a boat to car modification, perhaps you can add your code to that and make a smoother ride of it, but it basically shows you how to use the boat on land....
so as u can see its a ufo but i need to know how to mount a player in the middle, make fly and be controlled, and make it shoot something
Check Pig mounting code/the mounting tutorial in this thread (may not work since it is outdated).
Check ghast code for flying, as for being controllable check this thread again.
Check Skeleton code for how it fires arrows.
I know that this is really old and all, but I updated parts of it, and fixed some things. I made an entity file, but one problem im having is that my mob will not move, it'll just stand still, and i don't know why. If you can help me send me a pm please, thanks :smile.gif:.
Thanks!
Entity.class
Render.class
Model.java
BTW all .class files are actually .java in eclipse!
The gummybear is supposed to be smaller than a regular zombie! The hitbox is smaller but the actual texture is not... here is a screenshot!
Maybe you should look at the title: ModLoader [1.7.3]
Check my tut for vehicles, its a boat to car modification, perhaps you can add your code to that and make a smoother ride of it, but it basically shows you how to use the boat on land....
Find out how I generate....coolAlias...world structure generation and rotation tool...