[b]Viky'sAdvancedMobTutoria[/b][b]l[/b]
[b]Hello everybody ![/b]
[b]i am here to teach you how to make advanced mob ![/b][b]like mob can Climb wall , Controllable [/b][b]mob and much more to come[/b]
[b]1.Controlable Mob[/b]
[b]do you want to make mob that controllable or do you want make car [/b][b]well here it is the it's free ! [/b][b]
[/b]package net.minecraft.src;
public class EntityCar extends EntityAnimal
{
private boolean leap;
public String myName;
public EntityCar(World par1World)
{
super(par1World);
this.texture = "/mob/Cartexture.png";
this.setSize(0.6F, 1.8F);
Name = "Jeep";
stationary = false;
}
String Name;
protected void updateEntityActionState()
{
}
public boolean isAIEnabled()
{
return true;
}
protected void updateAITasks()
{
super.updateAITasks();
}
public int getMaxHealth()
{
return 50;
}
/**
* returns true if all the conditions for steering the entity are met. For pigs, this is true if it is being ridden
* by a player and the player is holding a carrot-on-a-stick
*/
public boolean canBeSteered()
{
return true;
}
public void updateRidden()
{
if(ridingEntity.isDead)
{
ridingEntity = null;
return;
}
motionX = 0.0D;
motionZ = 0.0D;
motionY = 0.0D;
onUpdate();
//onUpdate();
if(ridingEntity == null)
{
return;
}
ridingEntity.updateRiderPosition();
}
public double getMountedYOffset()
{
return (double)height * 0.0D + 0.4D;
}
public boolean interact(EntityPlayer entityplayer)
{
if(riddenByEntity != null && (riddenByEntity instanceof EntityPlayer) && riddenByEntity != entityplayer)
{
return true;
}
if(!worldObj.isRemote)
{
entityplayer.mountEntity(this);
}
ItemStack itemstack = entityplayer.getCurrentEquippedItem();
if (itemstack != null && itemstack.itemID == mod_Carmod.Wrench.itemID)
{
if (!worldObj.isRemote)
{
EntityLiving entitytalljake = new EntityCar(worldObj);
entitytalljake.setLocationAndAngles(posX, posY, posZ, rotationYaw, rotationPitch);
worldObj.spawnEntityInWorld(entitytalljake);
setDead();
itemstack.stackSize--;
}
return true;
}
return leap;
}
/**
* Called when the mob's health reaches 0.
*/
public void onDeath(DamageSource par1DamageSource)
{
this.worldObj.createExplosion(this/*entity immune to explosion, You may set it to none*/, this.posX, this.posY, this.posZ, 5/*float, set it somewhere*/, true/* if explosion should destroy blocks*/);;
}
public void moveEntity(double d, double d1, double d2)
{
if(riddenByEntity != null)
{
stationary = true;
motionX += riddenByEntity.motionX*10; // * 0.20000000000000001D;
motionZ += riddenByEntity.motionZ*10; // * 0.20000000000000001D;
if(isCollidedHorizontally)
{
if(onGround) //else not fly
{
motionY += 0.5F;//let it try to jump over obstacle
}
}
super.moveEntity(motionX, motionY, motionZ);
}else
{
super.moveEntity(d, d1, d2);
stationary = true;
}
}
protected boolean isMovementCeased()
{
return stationary;
}
public void writeEntityToNBT(NBTTagCompound nbttagcompound)
{
super.writeEntityToNBT(nbttagcompound);
}
public void readEntityFromNBT(NBTTagCompound nbttagcompound)
{
super.readEntityFromNBT(nbttagcompound);
}
protected String getLivingSound()
{
return "none";
}
protected String getHurtSound()
{
return "none";
}
protected String getDeathSound()
{
return "none";
}
protected void playStepSound(int par1, int par2, int par3, int par4)
{
this.func_85030_a("mob.irongolem.walk", 1.0F, 1.0F);
}
private void func_85030_a(String string, float f, float g) {
// TODO Auto-generated method stub
}
public boolean stationary;
protected float getSoundVolume()
{
return 0.4F;
}
public EntityAIControlledByPlayer getAIControlledByPlayer()
{
return this.getAIControlledByPlayer();
}
public void onUpdate()
{
super.onUpdate();
if(riddenByEntity != null) //check if there is a rider
{
//currentTarget = this;
texture = "/mob/Cartexture.png"; //test to show a different texture when mounted
this.randomYawVelocity = 0; //try not to let the horse control where to look.
this.rotationYaw =riddenByEntity.rotationYaw;
}else
{
if(texture != "/mob/Cartexture.png")
{
texture = "/mob/Cartexture.png"; //reset texture afte getting off.
}
}
}
@Override
public EntityAgeable createChild(EntityAgeable entityageable) {
// TODO Auto-generated method stub
return null;
}
}[b]
[/b][b]you can modify the code whetever you want ![/b]
[b]2.Climbable mob[/b]
[b]this is really simple [/b][b]you just copy this code:[/b][b]
[/b][b]
[/b]package net.minecraft.src;
public class EntitySpider extends EntityMob
{
public EntitySpider(World par1World)
{
super(par1World);
this.texture = "/mob/spider.png";
this.setSize(1.4F, 0.9F);
this.moveSpeed = 0.8F;
}
protected void entityInit()
{
super.entityInit();
this.dataWatcher.addObject(16, new Byte((byte)0));
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
super.onUpdate();
if (!this.worldObj.isRemote)
{
this.setBesideClimbableBlock(this.isCollidedHorizontally);
}
}
public int getMaxHealth()
{
return 16;
}
/**
* Returns the Y offset from the entity's position for any entity riding this one.
*/
public double getMountedYOffset()
{
return (double)this.height * 0.75D - 0.5D;
}
/**
* Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking
* (Animals, Spiders at day, peaceful PigZombies).
*/
protected Entity findPlayerToAttack()
{
float var1 = this.getBrightness(1.0F);
if (var1 < 0.5F)
{
double var2 = 16.0D;
return this.worldObj.getClosestVulnerablePlayerToEntity(this, var2);
}
else
{
return null;
}
}
/**
* Returns the sound this mob makes while it's alive.
*/
protected String getLivingSound()
{
return "mob.spider.say";
}
/**
* Returns the sound this mob makes when it is hurt.
*/
protected String getHurtSound()
{
return "mob.spider.say";
}
/**
* Returns the sound this mob makes on death.
*/
protected String getDeathSound()
{
return "mob.spider.death";
}
/**
* Plays step sound at given x, y, z for the entity
*/
protected void playStepSound(int par1, int par2, int par3, int par4)
{
this.playSound("mob.spider.step", 0.15F, 1.0F);
}
/**
* Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack.
*/
protected void attackEntity(Entity par1Entity, float par2)
{
float var3 = this.getBrightness(1.0F);
if (var3 > 0.5F && this.rand.nextInt(100) == 0)
{
this.entityToAttack = null;
}
else
{
if (par2 > 2.0F && par2 < 6.0F && this.rand.nextInt(10) == 0)
{
if (this.onGround)
{
double var4 = par1Entity.posX - this.posX;
double var6 = par1Entity.posZ - this.posZ;
float var8 = MathHelper.sqrt_double(var4 * var4 + var6 * var6);
this.motionX = var4 / (double)var8 * 0.5D * 0.800000011920929D + this.motionX * 0.20000000298023224D;
this.motionZ = var6 / (double)var8 * 0.5D * 0.800000011920929D + this.motionZ * 0.20000000298023224D;
this.motionY = 0.4000000059604645D;
}
}
else
{
super.attackEntity(par1Entity, par2);
}
}
}
/**
* Returns the item ID for the item the mob drops on death.
*/
protected int getDropItemId()
{
return Item.silk.itemID;
}
/**
* Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param
* par2 - Level of Looting used to kill this mob.
*/
protected void dropFewItems(boolean par1, int par2)
{
super.dropFewItems(par1, par2);
if (par1 && (this.rand.nextInt(3) == 0 || this.rand.nextInt(1 + par2) > 0))
{
this.dropItem(Item.spiderEye.itemID, 1);
}
}
/**
* returns true if this entity is by a ladder, false otherwise
*/
public boolean isOnLadder()
{
return this.isBesideClimbableBlock();
}
/**
* Sets the Entity inside a web block.
*/
public void setInWeb() {}
/**
* How large the spider should be scaled.
*/
public float spiderScaleAmount()
{
return 1.0F;
}
/**
* Get this Entity's EnumCreatureAttribute
*/
public EnumCreatureAttribute getCreatureAttribute()
{
return EnumCreatureAttribute.ARTHROPOD;
}
public boolean isPotionApplicable(PotionEffect par1PotionEffect)
{
return par1PotionEffect.getPotionID() == Potion.poison.id ? false : super.isPotionApplicable(par1PotionEffect);
}
/**
* Returns true if the WatchableObject (Byte) is 0x01 otherwise returns false. The WatchableObject is updated using
* setBesideClimableBlock.
*/
public boolean isBesideClimbableBlock()
{
return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
}
/**
* Updates the WatchableObject (Byte) created in entityInit(), setting it to 0x01 if par1 is true or 0x00 if it is
* false.
*/
public void setBesideClimbableBlock(boolean par1)
{
byte var2 = this.dataWatcher.getWatchableObjectByte(16);
if (par1)
{
var2 = (byte)(var2 | 1);
}
else
{
var2 &= -2;
}
this.dataWatcher.updateObject(16, Byte.valueOf(var2));
}
/**
* Initialize this creature.
*/
public void initCreature()
{
if (this.worldObj.rand.nextInt(100) == 0)
{
EntitySkeleton var1 = new EntitySkeleton(this.worldObj);
var1.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F);
var1.initCreature();
this.worldObj.spawnEntityInWorld(var1);
var1.mountEntity(this);
}
}
}
[b]
[/b][b]
[/b]
[b]3.Mob Can Open doors and Have House[/b]
[b]alright this is fun stuff ![/b]
[b]with this line of code your mob can open doors ![/b]
[b]here's the code ![/b]
[b]
[/b]
this.tasks.addTask(3, new EntityAIMoveIndoors(this));
this.tasks.addTask(4, new EntityAIRestrictOpenDoor(this));
this.tasks.addTask(5, new EntityAIOpenDoor(this, true));
this.tasks.addTask(6, new EntityAIMoveTwardsRestriction(this, 0.3F));
[b]
[/b]
and if you want your mob move to you house just like villager did !
here's the code :
[/b]
[b]But you need this line of code ! :[/b]
[b]
[/b] private int randomTickDivider;
private boolean isMating;
private boolean isPlaying;
Village villageObj;
/** This villager's current customer. */
private EntityPlayer buyingPlayer;
/** Initialises the MerchantRecipeList.java */
private MerchantRecipeList buyingList;
private int timeUntilReset;
/** addDefaultEquipmentAndRecipies is called if this is true */
private boolean needsInitilization;
private int wealth;
/** Last player to trade with this villager, used for aggressivity. */
private String lastBuyingPlayer;
private boolean field_82190_bM;
private float field_82191_bN;
public int attackCounter = 0;
[b]
[/b]
[b]put this in your Upper Public [/b][b]Entity[/b] [b](World par1World)[/b]
[b]please send me an error text maybe i can fix that ![/b][b]Check my mod at here :[/b][b]http://www.minecraft.../#entry22771939[/b][b]Planned tutorial:[/b]
[b]1.Controllable mob[/b]
[b]2.Climbable mob[/b]
[b]3.Can destroy blocks [/b]
[b]4.Can pickup blocks[/b]
[b]5.Can Open doors [/b]
[b]so that's it everybody ! i hope this tutorial help you guys! [/b][b]Click Banner below to check my mod ![/b][b]if you guys have an error on this code:[/b]
Any way you could update this to 1.6.2 for modloader? :]
When I put this one in the mob moves and all but keeps getting pulled back to its original location. :l
Any way you could update this to 1.6.2 for modloader? :]
When I put this one in the mob moves and all but keeps getting pulled back to its original location. :l
youre problem is that you don't move it server side, only client side
Dream in code has a great and active forum with sub forums for ALL common programming languages.
There are a lot of VERY VERY experienced programmers hanging out to help out in these boards, so if you need help it's a good place to go to
[b]Hello everybody ![/b]
[b]i am here to teach you how to make advanced mob ![/b][b]like mob can Climb wall , Controllable [/b][b]mob and much more to come[/b]
[b]1.Controlable Mob[/b]
[b]do you want to make mob that controllable or do you want make car [/b][b]well here it is the it's free !
[/b]package net.minecraft.src; public class EntityCar extends EntityAnimal { private boolean leap; public String myName; public EntityCar(World par1World) { super(par1World); this.texture = "/mob/Cartexture.png"; this.setSize(0.6F, 1.8F); Name = "Jeep"; stationary = false; } String Name; protected void updateEntityActionState() { } public boolean isAIEnabled() { return true; } protected void updateAITasks() { super.updateAITasks(); } public int getMaxHealth() { return 50; } /** * returns true if all the conditions for steering the entity are met. For pigs, this is true if it is being ridden * by a player and the player is holding a carrot-on-a-stick */ public boolean canBeSteered() { return true; } public void updateRidden() { if(ridingEntity.isDead) { ridingEntity = null; return; } motionX = 0.0D; motionZ = 0.0D; motionY = 0.0D; onUpdate(); //onUpdate(); if(ridingEntity == null) { return; } ridingEntity.updateRiderPosition(); } public double getMountedYOffset() { return (double)height * 0.0D + 0.4D; } public boolean interact(EntityPlayer entityplayer) { if(riddenByEntity != null && (riddenByEntity instanceof EntityPlayer) && riddenByEntity != entityplayer) { return true; } if(!worldObj.isRemote) { entityplayer.mountEntity(this); } ItemStack itemstack = entityplayer.getCurrentEquippedItem(); if (itemstack != null && itemstack.itemID == mod_Carmod.Wrench.itemID) { if (!worldObj.isRemote) { EntityLiving entitytalljake = new EntityCar(worldObj); entitytalljake.setLocationAndAngles(posX, posY, posZ, rotationYaw, rotationPitch); worldObj.spawnEntityInWorld(entitytalljake); setDead(); itemstack.stackSize--; } return true; } return leap; } /** * Called when the mob's health reaches 0. */ public void onDeath(DamageSource par1DamageSource) { this.worldObj.createExplosion(this/*entity immune to explosion, You may set it to none*/, this.posX, this.posY, this.posZ, 5/*float, set it somewhere*/, true/* if explosion should destroy blocks*/);; } public void moveEntity(double d, double d1, double d2) { if(riddenByEntity != null) { stationary = true; motionX += riddenByEntity.motionX*10; // * 0.20000000000000001D; motionZ += riddenByEntity.motionZ*10; // * 0.20000000000000001D; if(isCollidedHorizontally) { if(onGround) //else not fly { motionY += 0.5F;//let it try to jump over obstacle } } super.moveEntity(motionX, motionY, motionZ); }else { super.moveEntity(d, d1, d2); stationary = true; } } protected boolean isMovementCeased() { return stationary; } public void writeEntityToNBT(NBTTagCompound nbttagcompound) { super.writeEntityToNBT(nbttagcompound); } public void readEntityFromNBT(NBTTagCompound nbttagcompound) { super.readEntityFromNBT(nbttagcompound); } protected String getLivingSound() { return "none"; } protected String getHurtSound() { return "none"; } protected String getDeathSound() { return "none"; } protected void playStepSound(int par1, int par2, int par3, int par4) { this.func_85030_a("mob.irongolem.walk", 1.0F, 1.0F); } private void func_85030_a(String string, float f, float g) { // TODO Auto-generated method stub } public boolean stationary; protected float getSoundVolume() { return 0.4F; } public EntityAIControlledByPlayer getAIControlledByPlayer() { return this.getAIControlledByPlayer(); } public void onUpdate() { super.onUpdate(); if(riddenByEntity != null) //check if there is a rider { //currentTarget = this; texture = "/mob/Cartexture.png"; //test to show a different texture when mounted this.randomYawVelocity = 0; //try not to let the horse control where to look. this.rotationYaw =riddenByEntity.rotationYaw; }else { if(texture != "/mob/Cartexture.png") { texture = "/mob/Cartexture.png"; //reset texture afte getting off. } } } @Override public EntityAgeable createChild(EntityAgeable entityageable) { // TODO Auto-generated method stub return null; } }[b][/b][b]you can modify the code whetever you want ![/b][b]this is really simple [/b][b]you just copy this code:[/b][b]
[/b]package net.minecraft.src; public class EntitySpider extends EntityMob { public EntitySpider(World par1World) { super(par1World); this.texture = "/mob/spider.png"; this.setSize(1.4F, 0.9F); this.moveSpeed = 0.8F; } protected void entityInit() { super.entityInit(); this.dataWatcher.addObject(16, new Byte((byte)0)); } /** * Called to update the entity's position/logic. */ public void onUpdate() { super.onUpdate(); if (!this.worldObj.isRemote) { this.setBesideClimbableBlock(this.isCollidedHorizontally); } } public int getMaxHealth() { return 16; } /** * Returns the Y offset from the entity's position for any entity riding this one. */ public double getMountedYOffset() { return (double)this.height * 0.75D - 0.5D; } /** * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking * (Animals, Spiders at day, peaceful PigZombies). */ protected Entity findPlayerToAttack() { float var1 = this.getBrightness(1.0F); if (var1 < 0.5F) { double var2 = 16.0D; return this.worldObj.getClosestVulnerablePlayerToEntity(this, var2); } else { return null; } } /** * Returns the sound this mob makes while it's alive. */ protected String getLivingSound() { return "mob.spider.say"; } /** * Returns the sound this mob makes when it is hurt. */ protected String getHurtSound() { return "mob.spider.say"; } /** * Returns the sound this mob makes on death. */ protected String getDeathSound() { return "mob.spider.death"; } /** * Plays step sound at given x, y, z for the entity */ protected void playStepSound(int par1, int par2, int par3, int par4) { this.playSound("mob.spider.step", 0.15F, 1.0F); } /** * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack. */ protected void attackEntity(Entity par1Entity, float par2) { float var3 = this.getBrightness(1.0F); if (var3 > 0.5F && this.rand.nextInt(100) == 0) { this.entityToAttack = null; } else { if (par2 > 2.0F && par2 < 6.0F && this.rand.nextInt(10) == 0) { if (this.onGround) { double var4 = par1Entity.posX - this.posX; double var6 = par1Entity.posZ - this.posZ; float var8 = MathHelper.sqrt_double(var4 * var4 + var6 * var6); this.motionX = var4 / (double)var8 * 0.5D * 0.800000011920929D + this.motionX * 0.20000000298023224D; this.motionZ = var6 / (double)var8 * 0.5D * 0.800000011920929D + this.motionZ * 0.20000000298023224D; this.motionY = 0.4000000059604645D; } } else { super.attackEntity(par1Entity, par2); } } } /** * Returns the item ID for the item the mob drops on death. */ protected int getDropItemId() { return Item.silk.itemID; } /** * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param * par2 - Level of Looting used to kill this mob. */ protected void dropFewItems(boolean par1, int par2) { super.dropFewItems(par1, par2); if (par1 && (this.rand.nextInt(3) == 0 || this.rand.nextInt(1 + par2) > 0)) { this.dropItem(Item.spiderEye.itemID, 1); } } /** * returns true if this entity is by a ladder, false otherwise */ public boolean isOnLadder() { return this.isBesideClimbableBlock(); } /** * Sets the Entity inside a web block. */ public void setInWeb() {} /** * How large the spider should be scaled. */ public float spiderScaleAmount() { return 1.0F; } /** * Get this Entity's EnumCreatureAttribute */ public EnumCreatureAttribute getCreatureAttribute() { return EnumCreatureAttribute.ARTHROPOD; } public boolean isPotionApplicable(PotionEffect par1PotionEffect) { return par1PotionEffect.getPotionID() == Potion.poison.id ? false : super.isPotionApplicable(par1PotionEffect); } /** * Returns true if the WatchableObject (Byte) is 0x01 otherwise returns false. The WatchableObject is updated using * setBesideClimableBlock. */ public boolean isBesideClimbableBlock() { return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; } /** * Updates the WatchableObject (Byte) created in entityInit(), setting it to 0x01 if par1 is true or 0x00 if it is * false. */ public void setBesideClimbableBlock(boolean par1) { byte var2 = this.dataWatcher.getWatchableObjectByte(16); if (par1) { var2 = (byte)(var2 | 1); } else { var2 &= -2; } this.dataWatcher.updateObject(16, Byte.valueOf(var2)); } /** * Initialize this creature. */ public void initCreature() { if (this.worldObj.rand.nextInt(100) == 0) { EntitySkeleton var1 = new EntitySkeleton(this.worldObj); var1.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); var1.initCreature(); this.worldObj.spawnEntityInWorld(var1); var1.mountEntity(this); } } } [b][/b][b][b]3.Mob Can Open doors and Have House[/b]
[b]alright this is fun stuff ![/b]
[b]with this line of code your mob can open doors ![/b]
[b]here's the code ![/b]
[b][/b]
and if you want your mob move to you house just like villager did !
here's the code :
/** * main AI tick function, replaces updateEntityActionState */ protected void updateAITick() { if (--this.randomTickDivider <= 0) { this.worldObj.villageCollectionObj.addVillagerPosition(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); this.randomTickDivider = 70 + this.rand.nextInt(50); this.villageObj = this.worldObj.villageCollectionObj.findNearestVillage(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 32);[/b] [b] if (this.villageObj == null) { this.detachHome(); } else { ChunkCoordinates var1 = this.villageObj.getCenter(); this.setHomeArea(var1.posX, var1.posY, var1.posZ, (int)((float)this.villageObj.getVillageRadius() * 0.6F));[/b] [b] if (this.field_82190_bM) { this.field_82190_bM = false; this.villageObj.func_82683_b(5); } } } } [b][/b][b]But you need this line of code ! :[/b]
[b][/b]
[b]put this in your Upper Public [/b][b]Entity[/b] [b](World par1World)[/b]
[b]1.
Controllable mob[/b][b]2.
Climbable mob[/b][b]3.Can destroy blocks [/b]
[b]4.Can pickup blocks[/b]
[b]5.Can Open doors [/b]
[b]so that's it everybody ! i hope this tutorial help you guys! [/b][b]Click Banner below to check my mod ![/b][b]if you guys have an error on this code:[/b][b]delete that ![/b][b]and this ![/b][b][/b]
everyone !
no prob
well...this tutorial are not for how to make mob, this tutorial for making mobs better .if you want how to make mobs click this :
for Modloader :
http://www.minecraftforum.net/topic/1552222-152-151-147-132-creating-mods-modloaderforge-scmowns-src-video/
for Forge :
http://www.minecraftforum.net/topic/1431137-152-forge-smp-modding-tutorials-updated-21-5-2013-now-also-on-android/
these guys are pro in code,i am just a normal coder
i'll try mob animations because it's quite complicated, i learn mob animations from here (for forge) -> http://www.minecraftforum.net/topic/1850860-15xspmp-animationapi-animate-your-entities-v100/
When I put this one in the mob moves and all but keeps getting pulled back to its original location. :l
youre problem is that you don't move it server side, only client side
And how would i go about that?
One of the problems with mod loader is that you have the sides separated still, but yeh server should handle entities.
Do i need to install something else to do the server side stuff or is just modloader all i need?
Yeah I was getting that feeling, here this is for you:
http://www.minecraftforum.net/topic/1892328-need-a-highly-detailed-152-guide/
Good luck
Thanks!
As these boards aren't for Java or general programming help I'd like to give you a for me valuable resource:
http://www.dreamincode.net/forums/forum/32-java/
Dream in code has a great and active forum with sub forums for ALL common programming languages.
There are a lot of VERY VERY experienced programmers hanging out to help out in these boards, so if you need help it's a good place to go to
Have fun on the road ahead mate!
How about jumping mob + animations,rotations while jump.