base mod created

This commit is contained in:
Mohammad-Ali Minaie
2018-10-08 09:07:47 -04:00
parent 0a7700c356
commit b86dedad2f
7848 changed files with 584664 additions and 1 deletions

View File

@@ -0,0 +1,268 @@
package net.minecraft.entity.passive;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.walkers.ItemStackDataLists;
import net.minecraft.world.World;
public abstract class AbstractChestHorse extends AbstractHorse
{
private static final DataParameter<Boolean> DATA_ID_CHEST = EntityDataManager.<Boolean>createKey(AbstractChestHorse.class, DataSerializers.BOOLEAN);
public AbstractChestHorse(World worldIn)
{
super(worldIn);
this.canGallop = false;
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(DATA_ID_CHEST, Boolean.valueOf(false));
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue((double)this.getModifiedMaxHealth());
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.17499999701976776D);
this.getEntityAttribute(JUMP_STRENGTH).setBaseValue(0.5D);
}
public boolean hasChest()
{
return ((Boolean)this.dataManager.get(DATA_ID_CHEST)).booleanValue();
}
public void setChested(boolean chested)
{
this.dataManager.set(DATA_ID_CHEST, Boolean.valueOf(chested));
}
protected int getInventorySize()
{
return this.hasChest() ? 17 : super.getInventorySize();
}
/**
* Returns the Y offset from the entity's position for any entity riding this one.
*/
public double getMountedYOffset()
{
return super.getMountedYOffset() - 0.25D;
}
protected SoundEvent getAngrySound()
{
super.getAngrySound();
return SoundEvents.ENTITY_DONKEY_ANGRY;
}
/**
* Called when the mob's health reaches 0.
*/
public void onDeath(DamageSource cause)
{
super.onDeath(cause);
if (this.hasChest())
{
if (!this.world.isRemote)
{
this.dropItem(Item.getItemFromBlock(Blocks.CHEST), 1);
}
this.setChested(false);
}
}
public static void registerFixesAbstractChestHorse(DataFixer fixer, Class<?> entityClass)
{
AbstractHorse.registerFixesAbstractHorse(fixer, entityClass);
fixer.registerWalker(FixTypes.ENTITY, new ItemStackDataLists(entityClass, new String[] {"Items"}));
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setBoolean("ChestedHorse", this.hasChest());
if (this.hasChest())
{
NBTTagList nbttaglist = new NBTTagList();
for (int i = 2; i < this.horseChest.getSizeInventory(); ++i)
{
ItemStack itemstack = this.horseChest.getStackInSlot(i);
if (!itemstack.isEmpty())
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
nbttagcompound.setByte("Slot", (byte)i);
itemstack.writeToNBT(nbttagcompound);
nbttaglist.appendTag(nbttagcompound);
}
}
compound.setTag("Items", nbttaglist);
}
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.setChested(compound.getBoolean("ChestedHorse"));
if (this.hasChest())
{
NBTTagList nbttaglist = compound.getTagList("Items", 10);
this.initHorseChest();
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(i);
int j = nbttagcompound.getByte("Slot") & 255;
if (j >= 2 && j < this.horseChest.getSizeInventory())
{
this.horseChest.setInventorySlotContents(j, new ItemStack(nbttagcompound));
}
}
}
this.updateHorseSlots();
}
public boolean replaceItemInInventory(int inventorySlot, ItemStack itemStackIn)
{
if (inventorySlot == 499)
{
if (this.hasChest() && itemStackIn.isEmpty())
{
this.setChested(false);
this.initHorseChest();
return true;
}
if (!this.hasChest() && itemStackIn.getItem() == Item.getItemFromBlock(Blocks.CHEST))
{
this.setChested(true);
this.initHorseChest();
return true;
}
}
return super.replaceItemInInventory(inventorySlot, itemStackIn);
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
if (itemstack.getItem() == Items.SPAWN_EGG)
{
return super.processInteract(player, hand);
}
else
{
if (!this.isChild())
{
if (this.isTame() && player.isSneaking())
{
this.openGUI(player);
return true;
}
if (this.isBeingRidden())
{
return super.processInteract(player, hand);
}
}
if (!itemstack.isEmpty())
{
boolean flag = this.handleEating(player, itemstack);
if (!flag && !this.isTame())
{
if (itemstack.interactWithEntity(player, this, hand))
{
return true;
}
this.makeMad();
return true;
}
if (!flag && !this.hasChest() && itemstack.getItem() == Item.getItemFromBlock(Blocks.CHEST))
{
this.setChested(true);
this.playChestEquipSound();
flag = true;
this.initHorseChest();
}
if (!flag && !this.isChild() && !this.isHorseSaddled() && itemstack.getItem() == Items.SADDLE)
{
this.openGUI(player);
return true;
}
if (flag)
{
if (!player.capabilities.isCreativeMode)
{
itemstack.shrink(1);
}
return true;
}
}
if (this.isChild())
{
return super.processInteract(player, hand);
}
else if (itemstack.interactWithEntity(player, this, hand))
{
return true;
}
else
{
this.mountTo(player);
return true;
}
}
}
protected void playChestEquipSound()
{
this.playSound(SoundEvents.ENTITY_DONKEY_CHEST, 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
}
public int getInventoryColumns()
{
return 5;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
package net.minecraft.entity.passive;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
public abstract class EntityAmbientCreature extends EntityLiving implements IAnimals
{
public EntityAmbientCreature(World worldIn)
{
super(worldIn);
}
public boolean canBeLeashedTo(EntityPlayer player)
{
return false;
}
}

View File

@@ -0,0 +1,282 @@
package net.minecraft.entity.passive;
import java.util.UUID;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public abstract class EntityAnimal extends EntityAgeable implements IAnimals
{
protected Block spawnableBlock = Blocks.GRASS;
private int inLove;
private UUID playerInLove;
public EntityAnimal(World worldIn)
{
super(worldIn);
}
protected void updateAITasks()
{
if (this.getGrowingAge() != 0)
{
this.inLove = 0;
}
super.updateAITasks();
}
/**
* 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();
if (this.getGrowingAge() != 0)
{
this.inLove = 0;
}
if (this.inLove > 0)
{
--this.inLove;
if (this.inLove % 10 == 0)
{
double d0 = this.rand.nextGaussian() * 0.02D;
double d1 = this.rand.nextGaussian() * 0.02D;
double d2 = this.rand.nextGaussian() * 0.02D;
this.world.spawnParticle(EnumParticleTypes.HEART, this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + 0.5D + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, d0, d1, d2);
}
}
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource source, float amount)
{
if (this.isEntityInvulnerable(source))
{
return false;
}
else
{
this.inLove = 0;
return super.attackEntityFrom(source, amount);
}
}
public float getBlockPathWeight(BlockPos pos)
{
return this.world.getBlockState(pos.down()).getBlock() == this.spawnableBlock ? 10.0F : this.world.getLightBrightness(pos) - 0.5F;
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setInteger("InLove", this.inLove);
if (this.playerInLove != null)
{
compound.setUniqueId("LoveCause", this.playerInLove);
}
}
/**
* Returns the Y Offset of this entity.
*/
public double getYOffset()
{
return 0.14D;
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.inLove = compound.getInteger("InLove");
this.playerInLove = compound.hasUniqueId("LoveCause") ? compound.getUniqueId("LoveCause") : null;
}
/**
* Checks if the entity's current position is a valid location to spawn this entity.
*/
public boolean getCanSpawnHere()
{
int i = MathHelper.floor(this.posX);
int j = MathHelper.floor(this.getEntityBoundingBox().minY);
int k = MathHelper.floor(this.posZ);
BlockPos blockpos = new BlockPos(i, j, k);
return this.world.getBlockState(blockpos.down()).getBlock() == this.spawnableBlock && this.world.getLight(blockpos) > 8 && super.getCanSpawnHere();
}
/**
* Get number of ticks, at least during which the living entity will be silent.
*/
public int getTalkInterval()
{
return 120;
}
/**
* Determines if an entity can be despawned, used on idle far away entities
*/
protected boolean canDespawn()
{
return false;
}
/**
* Get the experience points the entity currently has.
*/
protected int getExperiencePoints(EntityPlayer player)
{
return 1 + this.world.rand.nextInt(3);
}
/**
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
* the animal type)
*/
public boolean isBreedingItem(ItemStack stack)
{
return stack.getItem() == Items.WHEAT;
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
if (!itemstack.isEmpty())
{
if (this.isBreedingItem(itemstack) && this.getGrowingAge() == 0 && this.inLove <= 0)
{
this.consumeItemFromStack(player, itemstack);
this.setInLove(player);
return true;
}
if (this.isChild() && this.isBreedingItem(itemstack))
{
this.consumeItemFromStack(player, itemstack);
this.ageUp((int)((float)(-this.getGrowingAge() / 20) * 0.1F), true);
return true;
}
}
return super.processInteract(player, hand);
}
/**
* Decreases ItemStack size by one
*/
protected void consumeItemFromStack(EntityPlayer player, ItemStack stack)
{
if (!player.capabilities.isCreativeMode)
{
stack.shrink(1);
}
}
public void setInLove(@Nullable EntityPlayer player)
{
this.inLove = 600;
if (player != null)
{
this.playerInLove = player.getUniqueID();
}
this.world.setEntityState(this, (byte)18);
}
@Nullable
public EntityPlayerMP getLoveCause()
{
if (this.playerInLove == null)
{
return null;
}
else
{
EntityPlayer entityplayer = this.world.getPlayerEntityByUUID(this.playerInLove);
return entityplayer instanceof EntityPlayerMP ? (EntityPlayerMP)entityplayer : null;
}
}
/**
* Returns if the entity is currently in 'love mode'.
*/
public boolean isInLove()
{
return this.inLove > 0;
}
public void resetInLove()
{
this.inLove = 0;
}
/**
* Returns true if the mob is currently able to mate with the specified mob.
*/
public boolean canMateWith(EntityAnimal otherAnimal)
{
if (otherAnimal == this)
{
return false;
}
else if (otherAnimal.getClass() != this.getClass())
{
return false;
}
else
{
return this.isInLove() && otherAnimal.isInLove();
}
}
/**
* Handler for {@link World#setEntityState}
*/
@SideOnly(Side.CLIENT)
public void handleStatusUpdate(byte id)
{
if (id == 18)
{
for (int i = 0; i < 7; ++i)
{
double d0 = this.rand.nextGaussian() * 0.02D;
double d1 = this.rand.nextGaussian() * 0.02D;
double d2 = this.rand.nextGaussian() * 0.02D;
this.world.spawnParticle(EnumParticleTypes.HEART, this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + 0.5D + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, d0, d1, d2);
}
}
else
{
super.handleStatusUpdate(id);
}
}
}

View File

@@ -0,0 +1,305 @@
package net.minecraft.entity.passive;
import java.util.Calendar;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntityBat extends EntityAmbientCreature
{
private static final DataParameter<Byte> HANGING = EntityDataManager.<Byte>createKey(EntityBat.class, DataSerializers.BYTE);
/** Coordinates of where the bat spawned. */
private BlockPos spawnPosition;
public EntityBat(World worldIn)
{
super(worldIn);
this.setSize(0.5F, 0.9F);
this.setIsBatHanging(true);
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(HANGING, Byte.valueOf((byte)0));
}
/**
* Returns the volume for the sounds this mob makes.
*/
protected float getSoundVolume()
{
return 0.1F;
}
/**
* Gets the pitch of living sounds in living entities.
*/
protected float getSoundPitch()
{
return super.getSoundPitch() * 0.95F;
}
@Nullable
public SoundEvent getAmbientSound()
{
return this.getIsBatHanging() && this.rand.nextInt(4) != 0 ? null : SoundEvents.ENTITY_BAT_AMBIENT;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_BAT_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_BAT_DEATH;
}
/**
* Returns true if this entity should push and be pushed by other entities when colliding.
*/
public boolean canBePushed()
{
return false;
}
protected void collideWithEntity(Entity entityIn)
{
}
protected void collideWithNearbyEntities()
{
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(6.0D);
}
public boolean getIsBatHanging()
{
return (((Byte)this.dataManager.get(HANGING)).byteValue() & 1) != 0;
}
public void setIsBatHanging(boolean isHanging)
{
byte b0 = ((Byte)this.dataManager.get(HANGING)).byteValue();
if (isHanging)
{
this.dataManager.set(HANGING, Byte.valueOf((byte)(b0 | 1)));
}
else
{
this.dataManager.set(HANGING, Byte.valueOf((byte)(b0 & -2)));
}
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
super.onUpdate();
if (this.getIsBatHanging())
{
this.motionX = 0.0D;
this.motionY = 0.0D;
this.motionZ = 0.0D;
this.posY = (double)MathHelper.floor(this.posY) + 1.0D - (double)this.height;
}
else
{
this.motionY *= 0.6000000238418579D;
}
}
protected void updateAITasks()
{
super.updateAITasks();
BlockPos blockpos = new BlockPos(this);
BlockPos blockpos1 = blockpos.up();
if (this.getIsBatHanging())
{
if (this.world.getBlockState(blockpos1).isNormalCube())
{
if (this.rand.nextInt(200) == 0)
{
this.rotationYawHead = (float)this.rand.nextInt(360);
}
if (this.world.getNearestPlayerNotCreative(this, 4.0D) != null)
{
this.setIsBatHanging(false);
this.world.playEvent((EntityPlayer)null, 1025, blockpos, 0);
}
}
else
{
this.setIsBatHanging(false);
this.world.playEvent((EntityPlayer)null, 1025, blockpos, 0);
}
}
else
{
if (this.spawnPosition != null && (!this.world.isAirBlock(this.spawnPosition) || this.spawnPosition.getY() < 1))
{
this.spawnPosition = null;
}
if (this.spawnPosition == null || this.rand.nextInt(30) == 0 || this.spawnPosition.distanceSq((double)((int)this.posX), (double)((int)this.posY), (double)((int)this.posZ)) < 4.0D)
{
this.spawnPosition = new BlockPos((int)this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), (int)this.posY + this.rand.nextInt(6) - 2, (int)this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7));
}
double d0 = (double)this.spawnPosition.getX() + 0.5D - this.posX;
double d1 = (double)this.spawnPosition.getY() + 0.1D - this.posY;
double d2 = (double)this.spawnPosition.getZ() + 0.5D - this.posZ;
this.motionX += (Math.signum(d0) * 0.5D - this.motionX) * 0.10000000149011612D;
this.motionY += (Math.signum(d1) * 0.699999988079071D - this.motionY) * 0.10000000149011612D;
this.motionZ += (Math.signum(d2) * 0.5D - this.motionZ) * 0.10000000149011612D;
float f = (float)(MathHelper.atan2(this.motionZ, this.motionX) * (180D / Math.PI)) - 90.0F;
float f1 = MathHelper.wrapDegrees(f - this.rotationYaw);
this.moveForward = 0.5F;
this.rotationYaw += f1;
if (this.rand.nextInt(100) == 0 && this.world.getBlockState(blockpos1).isNormalCube())
{
this.setIsBatHanging(true);
}
}
}
/**
* 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;
}
public void fall(float distance, float damageMultiplier)
{
}
protected void updateFallState(double y, boolean onGroundIn, IBlockState state, BlockPos pos)
{
}
/**
* Return whether this entity should NOT trigger a pressure plate or a tripwire.
*/
public boolean doesEntityNotTriggerPressurePlate()
{
return true;
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource source, float amount)
{
if (this.isEntityInvulnerable(source))
{
return false;
}
else
{
if (!this.world.isRemote && this.getIsBatHanging())
{
this.setIsBatHanging(false);
}
return super.attackEntityFrom(source, amount);
}
}
public static void registerFixesBat(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntityBat.class);
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.dataManager.set(HANGING, Byte.valueOf(compound.getByte("BatFlags")));
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setByte("BatFlags", ((Byte)this.dataManager.get(HANGING)).byteValue());
}
/**
* Checks if the entity's current position is a valid location to spawn this entity.
*/
public boolean getCanSpawnHere()
{
BlockPos blockpos = new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ);
if (blockpos.getY() >= this.world.getSeaLevel())
{
return false;
}
else
{
int i = this.world.getLightFromNeighbors(blockpos);
int j = 4;
if (this.isDateAroundHalloween(this.world.getCurrentDate()))
{
j = 7;
}
else if (this.rand.nextBoolean())
{
return false;
}
return i > this.rand.nextInt(j) ? false : super.getCanSpawnHere();
}
}
private boolean isDateAroundHalloween(Calendar p_175569_1_)
{
return p_175569_1_.get(2) + 1 == 10 && p_175569_1_.get(5) >= 20 || p_175569_1_.get(2) + 1 == 11 && p_175569_1_.get(5) <= 3;
}
public float getEyeHeight()
{
return this.height / 2.0F;
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_BAT;
}
}

View File

@@ -0,0 +1,233 @@
package net.minecraft.entity.passive;
import com.google.common.collect.Sets;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIFollowParent;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAIPanic;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITempt;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.pathfinding.PathNodeType;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntityChicken extends EntityAnimal
{
private static final Set<Item> TEMPTATION_ITEMS = Sets.newHashSet(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS);
public float wingRotation;
public float destPos;
public float oFlapSpeed;
public float oFlap;
public float wingRotDelta = 1.0F;
/** The time until the next egg is spawned. */
public int timeUntilNextEgg;
public boolean chickenJockey;
public EntityChicken(World worldIn)
{
super(worldIn);
this.setSize(0.4F, 0.7F);
this.timeUntilNextEgg = this.rand.nextInt(6000) + 6000;
this.setPathPriority(PathNodeType.WATER, 0.0F);
}
protected void initEntityAI()
{
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityAIPanic(this, 1.4D));
this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
this.tasks.addTask(3, new EntityAITempt(this, 1.0D, false, TEMPTATION_ITEMS));
this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D));
this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 1.0D));
this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
this.tasks.addTask(7, new EntityAILookIdle(this));
}
public float getEyeHeight()
{
return this.height;
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(4.0D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.25D);
}
/**
* 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();
this.oFlap = this.wingRotation;
this.oFlapSpeed = this.destPos;
this.destPos = (float)((double)this.destPos + (double)(this.onGround ? -1 : 4) * 0.3D);
this.destPos = MathHelper.clamp(this.destPos, 0.0F, 1.0F);
if (!this.onGround && this.wingRotDelta < 1.0F)
{
this.wingRotDelta = 1.0F;
}
this.wingRotDelta = (float)((double)this.wingRotDelta * 0.9D);
if (!this.onGround && this.motionY < 0.0D)
{
this.motionY *= 0.6D;
}
this.wingRotation += this.wingRotDelta * 2.0F;
if (!this.world.isRemote && !this.isChild() && !this.isChickenJockey() && --this.timeUntilNextEgg <= 0)
{
this.playSound(SoundEvents.ENTITY_CHICKEN_EGG, 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
this.dropItem(Items.EGG, 1);
this.timeUntilNextEgg = this.rand.nextInt(6000) + 6000;
}
}
public void fall(float distance, float damageMultiplier)
{
}
protected SoundEvent getAmbientSound()
{
return SoundEvents.ENTITY_CHICKEN_AMBIENT;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_CHICKEN_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_CHICKEN_DEATH;
}
protected void playStepSound(BlockPos pos, Block blockIn)
{
this.playSound(SoundEvents.ENTITY_CHICKEN_STEP, 0.15F, 1.0F);
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_CHICKEN;
}
public EntityChicken createChild(EntityAgeable ageable)
{
return new EntityChicken(this.world);
}
/**
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
* the animal type)
*/
public boolean isBreedingItem(ItemStack stack)
{
return TEMPTATION_ITEMS.contains(stack.getItem());
}
/**
* Get the experience points the entity currently has.
*/
protected int getExperiencePoints(EntityPlayer player)
{
return this.isChickenJockey() ? 10 : super.getExperiencePoints(player);
}
public static void registerFixesChicken(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntityChicken.class);
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.chickenJockey = compound.getBoolean("IsChickenJockey");
if (compound.hasKey("EggLayTime"))
{
this.timeUntilNextEgg = compound.getInteger("EggLayTime");
}
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setBoolean("IsChickenJockey", this.chickenJockey);
compound.setInteger("EggLayTime", this.timeUntilNextEgg);
}
/**
* Determines if an entity can be despawned, used on idle far away entities
*/
protected boolean canDespawn()
{
return this.isChickenJockey() && !this.isBeingRidden();
}
public void updatePassenger(Entity passenger)
{
super.updatePassenger(passenger);
float f = MathHelper.sin(this.renderYawOffset * 0.017453292F);
float f1 = MathHelper.cos(this.renderYawOffset * 0.017453292F);
float f2 = 0.1F;
float f3 = 0.0F;
passenger.setPosition(this.posX + (double)(0.1F * f), this.posY + (double)(this.height * 0.5F) + passenger.getYOffset() + 0.0D, this.posZ - (double)(0.1F * f1));
if (passenger instanceof EntityLivingBase)
{
((EntityLivingBase)passenger).renderYawOffset = this.renderYawOffset;
}
}
/**
* Determines if this chicken is a jokey with a zombie riding it.
*/
public boolean isChickenJockey()
{
return this.chickenJockey;
}
/**
* Sets whether this chicken is a jockey or not.
*/
public void setChickenJockey(boolean jockey)
{
this.chickenJockey = jockey;
}
}

View File

@@ -0,0 +1,130 @@
package net.minecraft.entity.passive;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIFollowParent;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAIPanic;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITempt;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntityCow extends EntityAnimal
{
public EntityCow(World worldIn)
{
super(worldIn);
this.setSize(0.9F, 1.4F);
}
public static void registerFixesCow(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntityCow.class);
}
protected void initEntityAI()
{
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityAIPanic(this, 2.0D));
this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
this.tasks.addTask(3, new EntityAITempt(this, 1.25D, Items.WHEAT, false));
this.tasks.addTask(4, new EntityAIFollowParent(this, 1.25D));
this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 1.0D));
this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
this.tasks.addTask(7, new EntityAILookIdle(this));
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.20000000298023224D);
}
protected SoundEvent getAmbientSound()
{
return SoundEvents.ENTITY_COW_AMBIENT;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_COW_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_COW_DEATH;
}
protected void playStepSound(BlockPos pos, Block blockIn)
{
this.playSound(SoundEvents.ENTITY_COW_STEP, 0.15F, 1.0F);
}
/**
* Returns the volume for the sounds this mob makes.
*/
protected float getSoundVolume()
{
return 0.4F;
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_COW;
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
if (itemstack.getItem() == Items.BUCKET && !player.capabilities.isCreativeMode && !this.isChild())
{
player.playSound(SoundEvents.ENTITY_COW_MILK, 1.0F, 1.0F);
itemstack.shrink(1);
if (itemstack.isEmpty())
{
player.setHeldItem(hand, new ItemStack(Items.MILK_BUCKET));
}
else if (!player.inventory.addItemStackToInventory(new ItemStack(Items.MILK_BUCKET)))
{
player.dropItem(new ItemStack(Items.MILK_BUCKET), false);
}
return true;
}
else
{
return super.processInteract(player, hand);
}
}
public EntityCow createChild(EntityAgeable ageable)
{
return new EntityCow(this.world);
}
public float getEyeHeight()
{
return this.isChild() ? this.height : 1.3F;
}
}

View File

@@ -0,0 +1,74 @@
package net.minecraft.entity.passive;
import javax.annotation.Nullable;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.init.SoundEvents;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntityDonkey extends AbstractChestHorse
{
public EntityDonkey(World worldIn)
{
super(worldIn);
}
public static void registerFixesDonkey(DataFixer fixer)
{
AbstractChestHorse.registerFixesAbstractChestHorse(fixer, EntityDonkey.class);
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_DONKEY;
}
protected SoundEvent getAmbientSound()
{
super.getAmbientSound();
return SoundEvents.ENTITY_DONKEY_AMBIENT;
}
protected SoundEvent getDeathSound()
{
super.getDeathSound();
return SoundEvents.ENTITY_DONKEY_DEATH;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
super.getHurtSound(damageSourceIn);
return SoundEvents.ENTITY_DONKEY_HURT;
}
/**
* Returns true if the mob is currently able to mate with the specified mob.
*/
public boolean canMateWith(EntityAnimal otherAnimal)
{
if (otherAnimal == this)
{
return false;
}
else if (!(otherAnimal instanceof EntityDonkey) && !(otherAnimal instanceof EntityHorse))
{
return false;
}
else
{
return this.canMate() && ((AbstractHorse)otherAnimal).canMate();
}
}
public EntityAgeable createChild(EntityAgeable ageable)
{
AbstractHorse abstracthorse = (AbstractHorse)(ageable instanceof EntityHorse ? new EntityMule(this.world) : new EntityDonkey(this.world));
this.setOffspringAttributes(ageable, abstracthorse);
return abstracthorse;
}
}

View File

@@ -0,0 +1,5 @@
package net.minecraft.entity.passive;
public interface EntityFlying
{
}

View File

@@ -0,0 +1,449 @@
package net.minecraft.entity.passive;
import java.util.UUID;
import javax.annotation.Nullable;
import net.minecraft.block.SoundType;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.walkers.ItemStackData;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class EntityHorse extends AbstractHorse
{
private static final UUID ARMOR_MODIFIER_UUID = UUID.fromString("556E1665-8B10-40C8-8F9D-CF9B1667F295");
private static final DataParameter<Integer> HORSE_VARIANT = EntityDataManager.<Integer>createKey(EntityHorse.class, DataSerializers.VARINT);
private static final DataParameter<Integer> HORSE_ARMOR = EntityDataManager.<Integer>createKey(EntityHorse.class, DataSerializers.VARINT);
private static final DataParameter<ItemStack> HORSE_ARMOR_STACK = EntityDataManager.<ItemStack>createKey(EntityHorse.class, DataSerializers.ITEM_STACK);
private static final String[] HORSE_TEXTURES = new String[] {"textures/entity/horse/horse_white.png", "textures/entity/horse/horse_creamy.png", "textures/entity/horse/horse_chestnut.png", "textures/entity/horse/horse_brown.png", "textures/entity/horse/horse_black.png", "textures/entity/horse/horse_gray.png", "textures/entity/horse/horse_darkbrown.png"};
private static final String[] HORSE_TEXTURES_ABBR = new String[] {"hwh", "hcr", "hch", "hbr", "hbl", "hgr", "hdb"};
private static final String[] HORSE_MARKING_TEXTURES = new String[] {null, "textures/entity/horse/horse_markings_white.png", "textures/entity/horse/horse_markings_whitefield.png", "textures/entity/horse/horse_markings_whitedots.png", "textures/entity/horse/horse_markings_blackdots.png"};
private static final String[] HORSE_MARKING_TEXTURES_ABBR = new String[] {"", "wo_", "wmo", "wdo", "bdo"};
private String texturePrefix;
private final String[] horseTexturesArray = new String[3];
public EntityHorse(World worldIn)
{
super(worldIn);
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(HORSE_VARIANT, Integer.valueOf(0));
this.dataManager.register(HORSE_ARMOR, Integer.valueOf(HorseArmorType.NONE.getOrdinal()));
this.dataManager.register(HORSE_ARMOR_STACK, ItemStack.EMPTY);
}
public static void registerFixesHorse(DataFixer fixer)
{
AbstractHorse.registerFixesAbstractHorse(fixer, EntityHorse.class);
fixer.registerWalker(FixTypes.ENTITY, new ItemStackData(EntityHorse.class, new String[] {"ArmorItem"}));
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setInteger("Variant", this.getHorseVariant());
if (!this.horseChest.getStackInSlot(1).isEmpty())
{
compound.setTag("ArmorItem", this.horseChest.getStackInSlot(1).writeToNBT(new NBTTagCompound()));
}
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.setHorseVariant(compound.getInteger("Variant"));
if (compound.hasKey("ArmorItem", 10))
{
ItemStack itemstack = new ItemStack(compound.getCompoundTag("ArmorItem"));
if (!itemstack.isEmpty() && isArmor(itemstack))
{
this.horseChest.setInventorySlotContents(1, itemstack);
}
}
this.updateHorseSlots();
}
public void setHorseVariant(int variant)
{
this.dataManager.set(HORSE_VARIANT, Integer.valueOf(variant));
this.resetTexturePrefix();
}
public int getHorseVariant()
{
return ((Integer)this.dataManager.get(HORSE_VARIANT)).intValue();
}
private void resetTexturePrefix()
{
this.texturePrefix = null;
}
@SideOnly(Side.CLIENT)
private void setHorseTexturePaths()
{
int i = this.getHorseVariant();
int j = (i & 255) % 7;
int k = ((i & 65280) >> 8) % 5;
ItemStack armorStack = this.dataManager.get(HORSE_ARMOR_STACK);
String texture = !armorStack.isEmpty() ? armorStack.getItem().getHorseArmorTexture(this, armorStack) : HorseArmorType.getByOrdinal(this.dataManager.get(HORSE_ARMOR)).getTextureName(); //If armorStack is empty, the server is vanilla so the texture should be determined the vanilla way
this.horseTexturesArray[0] = HORSE_TEXTURES[j];
this.horseTexturesArray[1] = HORSE_MARKING_TEXTURES[k];
this.horseTexturesArray[2] = texture;
this.texturePrefix = "horse/" + HORSE_TEXTURES_ABBR[j] + HORSE_MARKING_TEXTURES_ABBR[k] + texture;
}
@SideOnly(Side.CLIENT)
public String getHorseTexture()
{
if (this.texturePrefix == null)
{
this.setHorseTexturePaths();
}
return this.texturePrefix;
}
@SideOnly(Side.CLIENT)
public String[] getVariantTexturePaths()
{
if (this.texturePrefix == null)
{
this.setHorseTexturePaths();
}
return this.horseTexturesArray;
}
/**
* Updates the items in the saddle and armor slots of the horse's inventory.
*/
protected void updateHorseSlots()
{
super.updateHorseSlots();
this.setHorseArmorStack(this.horseChest.getStackInSlot(1));
}
/**
* Set horse armor stack (for example: new ItemStack(Items.iron_horse_armor))
*/
public void setHorseArmorStack(ItemStack itemStackIn)
{
HorseArmorType horsearmortype = HorseArmorType.getByItemStack(itemStackIn);
this.dataManager.set(HORSE_ARMOR, Integer.valueOf(horsearmortype.getOrdinal()));
this.dataManager.set(HORSE_ARMOR_STACK, itemStackIn);
this.resetTexturePrefix();
if (!this.world.isRemote)
{
this.getEntityAttribute(SharedMonsterAttributes.ARMOR).removeModifier(ARMOR_MODIFIER_UUID);
int i = horsearmortype.getProtection();
if (i != 0)
{
this.getEntityAttribute(SharedMonsterAttributes.ARMOR).applyModifier((new AttributeModifier(ARMOR_MODIFIER_UUID, "Horse armor bonus", (double)i, 0)).setSaved(false));
}
}
}
public HorseArmorType getHorseArmorType()
{
HorseArmorType armor = HorseArmorType.getByItemStack(this.dataManager.get(HORSE_ARMOR_STACK)); //First check the Forge armor DataParameter
if (armor == HorseArmorType.NONE) armor = HorseArmorType.getByOrdinal(this.dataManager.get(HORSE_ARMOR)); //If the Forge armor DataParameter returns NONE, fallback to the vanilla armor DataParameter. This is necessary to prevent issues with Forge clients connected to vanilla servers.
return armor;
}
/**
* Called by InventoryBasic.onInventoryChanged() on a array that is never filled.
*/
public void onInventoryChanged(IInventory invBasic)
{
HorseArmorType horsearmortype = this.getHorseArmorType();
super.onInventoryChanged(invBasic);
HorseArmorType horsearmortype1 = this.getHorseArmorType();
if (this.ticksExisted > 20 && horsearmortype != horsearmortype1 && horsearmortype1 != HorseArmorType.NONE)
{
this.playSound(SoundEvents.ENTITY_HORSE_ARMOR, 0.5F, 1.0F);
}
}
protected void playGallopSound(SoundType p_190680_1_)
{
super.playGallopSound(p_190680_1_);
if (this.rand.nextInt(10) == 0)
{
this.playSound(SoundEvents.ENTITY_HORSE_BREATHE, p_190680_1_.getVolume() * 0.6F, p_190680_1_.getPitch());
}
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue((double)this.getModifiedMaxHealth());
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(this.getModifiedMovementSpeed());
this.getEntityAttribute(JUMP_STRENGTH).setBaseValue(this.getModifiedJumpStrength());
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
super.onUpdate();
if (this.world.isRemote && this.dataManager.isDirty())
{
this.dataManager.setClean();
this.resetTexturePrefix();
}
ItemStack armor = this.horseChest.getStackInSlot(1);
if (isArmor(armor)) armor.getItem().onHorseArmorTick(world, this, armor);
}
protected SoundEvent getAmbientSound()
{
super.getAmbientSound();
return SoundEvents.ENTITY_HORSE_AMBIENT;
}
protected SoundEvent getDeathSound()
{
super.getDeathSound();
return SoundEvents.ENTITY_HORSE_DEATH;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
super.getHurtSound(damageSourceIn);
return SoundEvents.ENTITY_HORSE_HURT;
}
protected SoundEvent getAngrySound()
{
super.getAngrySound();
return SoundEvents.ENTITY_HORSE_ANGRY;
}
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_HORSE;
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
boolean flag = !itemstack.isEmpty();
if (flag && itemstack.getItem() == Items.SPAWN_EGG)
{
return super.processInteract(player, hand);
}
else
{
if (!this.isChild())
{
if (this.isTame() && player.isSneaking())
{
this.openGUI(player);
return true;
}
if (this.isBeingRidden())
{
return super.processInteract(player, hand);
}
}
if (flag)
{
if (this.handleEating(player, itemstack))
{
if (!player.capabilities.isCreativeMode)
{
itemstack.shrink(1);
}
return true;
}
if (itemstack.interactWithEntity(player, this, hand))
{
return true;
}
if (!this.isTame())
{
this.makeMad();
return true;
}
boolean flag1 = HorseArmorType.getByItemStack(itemstack) != HorseArmorType.NONE;
boolean flag2 = !this.isChild() && !this.isHorseSaddled() && itemstack.getItem() == Items.SADDLE;
if (flag1 || flag2)
{
this.openGUI(player);
return true;
}
}
if (this.isChild())
{
return super.processInteract(player, hand);
}
else
{
this.mountTo(player);
return true;
}
}
}
/**
* Returns true if the mob is currently able to mate with the specified mob.
*/
public boolean canMateWith(EntityAnimal otherAnimal)
{
if (otherAnimal == this)
{
return false;
}
else if (!(otherAnimal instanceof EntityDonkey) && !(otherAnimal instanceof EntityHorse))
{
return false;
}
else
{
return this.canMate() && ((AbstractHorse)otherAnimal).canMate();
}
}
public EntityAgeable createChild(EntityAgeable ageable)
{
AbstractHorse abstracthorse;
if (ageable instanceof EntityDonkey)
{
abstracthorse = new EntityMule(this.world);
}
else
{
EntityHorse entityhorse = (EntityHorse)ageable;
abstracthorse = new EntityHorse(this.world);
int j = this.rand.nextInt(9);
int i;
if (j < 4)
{
i = this.getHorseVariant() & 255;
}
else if (j < 8)
{
i = entityhorse.getHorseVariant() & 255;
}
else
{
i = this.rand.nextInt(7);
}
int k = this.rand.nextInt(5);
if (k < 2)
{
i = i | this.getHorseVariant() & 65280;
}
else if (k < 4)
{
i = i | entityhorse.getHorseVariant() & 65280;
}
else
{
i = i | this.rand.nextInt(5) << 8 & 65280;
}
((EntityHorse)abstracthorse).setHorseVariant(i);
}
this.setOffspringAttributes(ageable, abstracthorse);
return abstracthorse;
}
public boolean wearsArmor()
{
return true;
}
public boolean isArmor(ItemStack stack)
{
return HorseArmorType.isHorseArmor(stack);
}
/**
* Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called
* when entity is reloaded from nbt. Mainly used for initializing attributes and inventory
*/
@Nullable
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata)
{
livingdata = super.onInitialSpawn(difficulty, livingdata);
int i;
if (livingdata instanceof EntityHorse.GroupData)
{
i = ((EntityHorse.GroupData)livingdata).variant;
}
else
{
i = this.rand.nextInt(7);
livingdata = new EntityHorse.GroupData(i);
}
this.setHorseVariant(i | this.rand.nextInt(5) << 8);
return livingdata;
}
public static class GroupData implements IEntityLivingData
{
public int variant;
public GroupData(int variantIn)
{
this.variant = variantIn;
}
}
}

View File

@@ -0,0 +1,614 @@
package net.minecraft.entity.passive;
import com.google.common.base.Predicate;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.IRangedAttackMob;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIAttackRanged;
import net.minecraft.entity.ai.EntityAIFollowParent;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAILlamaFollowCaravan;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAIPanic;
import net.minecraft.entity.ai.EntityAIRunAroundLikeCrazy;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityLlamaSpit;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class EntityLlama extends AbstractChestHorse implements IRangedAttackMob
{
private static final DataParameter<Integer> DATA_STRENGTH_ID = EntityDataManager.<Integer>createKey(EntityLlama.class, DataSerializers.VARINT);
private static final DataParameter<Integer> DATA_COLOR_ID = EntityDataManager.<Integer>createKey(EntityLlama.class, DataSerializers.VARINT);
private static final DataParameter<Integer> DATA_VARIANT_ID = EntityDataManager.<Integer>createKey(EntityLlama.class, DataSerializers.VARINT);
private boolean didSpit;
@Nullable
private EntityLlama caravanHead;
@Nullable
private EntityLlama caravanTail;
public EntityLlama(World worldIn)
{
super(worldIn);
this.setSize(0.9F, 1.87F);
}
private void setStrength(int strengthIn)
{
this.dataManager.set(DATA_STRENGTH_ID, Integer.valueOf(Math.max(1, Math.min(5, strengthIn))));
}
private void setRandomStrength()
{
int i = this.rand.nextFloat() < 0.04F ? 5 : 3;
this.setStrength(1 + this.rand.nextInt(i));
}
public int getStrength()
{
return ((Integer)this.dataManager.get(DATA_STRENGTH_ID)).intValue();
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setInteger("Variant", this.getVariant());
compound.setInteger("Strength", this.getStrength());
if (!this.horseChest.getStackInSlot(1).isEmpty())
{
compound.setTag("DecorItem", this.horseChest.getStackInSlot(1).writeToNBT(new NBTTagCompound()));
}
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
this.setStrength(compound.getInteger("Strength"));
super.readEntityFromNBT(compound);
this.setVariant(compound.getInteger("Variant"));
if (compound.hasKey("DecorItem", 10))
{
this.horseChest.setInventorySlotContents(1, new ItemStack(compound.getCompoundTag("DecorItem")));
}
this.updateHorseSlots();
}
protected void initEntityAI()
{
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityAIRunAroundLikeCrazy(this, 1.2D));
this.tasks.addTask(2, new EntityAILlamaFollowCaravan(this, 2.0999999046325684D));
this.tasks.addTask(3, new EntityAIAttackRanged(this, 1.25D, 40, 20.0F));
this.tasks.addTask(3, new EntityAIPanic(this, 1.2D));
this.tasks.addTask(4, new EntityAIMate(this, 1.0D));
this.tasks.addTask(5, new EntityAIFollowParent(this, 1.0D));
this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 0.7D));
this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
this.tasks.addTask(8, new EntityAILookIdle(this));
this.targetTasks.addTask(1, new EntityLlama.AIHurtByTarget(this));
this.targetTasks.addTask(2, new EntityLlama.AIDefendTarget(this));
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(40.0D);
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(DATA_STRENGTH_ID, Integer.valueOf(0));
this.dataManager.register(DATA_COLOR_ID, Integer.valueOf(-1));
this.dataManager.register(DATA_VARIANT_ID, Integer.valueOf(0));
}
public int getVariant()
{
return MathHelper.clamp(((Integer)this.dataManager.get(DATA_VARIANT_ID)).intValue(), 0, 3);
}
public void setVariant(int variantIn)
{
this.dataManager.set(DATA_VARIANT_ID, Integer.valueOf(variantIn));
}
protected int getInventorySize()
{
return this.hasChest() ? 2 + 3 * this.getInventoryColumns() : super.getInventorySize();
}
public void updatePassenger(Entity passenger)
{
if (this.isPassenger(passenger))
{
float f = MathHelper.cos(this.renderYawOffset * 0.017453292F);
float f1 = MathHelper.sin(this.renderYawOffset * 0.017453292F);
float f2 = 0.3F;
passenger.setPosition(this.posX + (double)(0.3F * f1), this.posY + this.getMountedYOffset() + passenger.getYOffset(), this.posZ - (double)(0.3F * f));
}
}
/**
* Returns the Y offset from the entity's position for any entity riding this one.
*/
public double getMountedYOffset()
{
return (double)this.height * 0.67D;
}
/**
* 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 false;
}
protected boolean handleEating(EntityPlayer player, ItemStack stack)
{
int i = 0;
int j = 0;
float f = 0.0F;
boolean flag = false;
Item item = stack.getItem();
if (item == Items.WHEAT)
{
i = 10;
j = 3;
f = 2.0F;
}
else if (item == Item.getItemFromBlock(Blocks.HAY_BLOCK))
{
i = 90;
j = 6;
f = 10.0F;
if (this.isTame() && this.getGrowingAge() == 0)
{
flag = true;
this.setInLove(player);
}
}
if (this.getHealth() < this.getMaxHealth() && f > 0.0F)
{
this.heal(f);
flag = true;
}
if (this.isChild() && i > 0)
{
this.world.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + 0.5D + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, 0.0D, 0.0D, 0.0D);
if (!this.world.isRemote)
{
this.addGrowth(i);
}
flag = true;
}
if (j > 0 && (flag || !this.isTame()) && this.getTemper() < this.getMaxTemper())
{
flag = true;
if (!this.world.isRemote)
{
this.increaseTemper(j);
}
}
if (flag && !this.isSilent())
{
this.world.playSound((EntityPlayer)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_LLAMA_EAT, this.getSoundCategory(), 1.0F, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F);
}
return flag;
}
/**
* Dead and sleeping entities cannot move
*/
protected boolean isMovementBlocked()
{
return this.getHealth() <= 0.0F || this.isEatingHaystack();
}
/**
* Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called
* when entity is reloaded from nbt. Mainly used for initializing attributes and inventory
*/
@Nullable
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata)
{
livingdata = super.onInitialSpawn(difficulty, livingdata);
this.setRandomStrength();
int i;
if (livingdata instanceof EntityLlama.GroupData)
{
i = ((EntityLlama.GroupData)livingdata).variant;
}
else
{
i = this.rand.nextInt(4);
livingdata = new EntityLlama.GroupData(i);
}
this.setVariant(i);
return livingdata;
}
@SideOnly(Side.CLIENT)
public boolean hasColor()
{
return this.getColor() != null;
}
protected SoundEvent getAngrySound()
{
return SoundEvents.ENTITY_LLAMA_ANGRY;
}
protected SoundEvent getAmbientSound()
{
return SoundEvents.ENTITY_LLAMA_AMBIENT;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_LLAMA_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_LLAMA_DEATH;
}
protected void playStepSound(BlockPos pos, Block blockIn)
{
this.playSound(SoundEvents.ENTITY_LLAMA_STEP, 0.15F, 1.0F);
}
protected void playChestEquipSound()
{
this.playSound(SoundEvents.ENTITY_LLAMA_CHEST, 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
}
public void makeMad()
{
SoundEvent soundevent = this.getAngrySound();
if (soundevent != null)
{
this.playSound(soundevent, this.getSoundVolume(), this.getSoundPitch());
}
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_LLAMA;
}
public int getInventoryColumns()
{
return this.getStrength();
}
public boolean wearsArmor()
{
return true;
}
public boolean isArmor(ItemStack stack)
{
return stack.getItem() == Item.getItemFromBlock(Blocks.CARPET);
}
public boolean canBeSaddled()
{
return false;
}
/**
* Called by InventoryBasic.onInventoryChanged() on a array that is never filled.
*/
public void onInventoryChanged(IInventory invBasic)
{
EnumDyeColor enumdyecolor = this.getColor();
super.onInventoryChanged(invBasic);
EnumDyeColor enumdyecolor1 = this.getColor();
if (this.ticksExisted > 20 && enumdyecolor1 != null && enumdyecolor1 != enumdyecolor)
{
this.playSound(SoundEvents.ENTITY_LLAMA_SWAG, 0.5F, 1.0F);
}
}
/**
* Updates the items in the saddle and armor slots of the horse's inventory.
*/
protected void updateHorseSlots()
{
if (!this.world.isRemote)
{
super.updateHorseSlots();
this.setColorByItem(this.horseChest.getStackInSlot(1));
}
}
private void setColor(@Nullable EnumDyeColor color)
{
this.dataManager.set(DATA_COLOR_ID, Integer.valueOf(color == null ? -1 : color.getMetadata()));
}
private void setColorByItem(ItemStack stack)
{
if (this.isArmor(stack))
{
this.setColor(EnumDyeColor.byMetadata(stack.getMetadata()));
}
else
{
this.setColor((EnumDyeColor)null);
}
}
@Nullable
public EnumDyeColor getColor()
{
int i = ((Integer)this.dataManager.get(DATA_COLOR_ID)).intValue();
return i == -1 ? null : EnumDyeColor.byMetadata(i);
}
public int getMaxTemper()
{
return 30;
}
/**
* Returns true if the mob is currently able to mate with the specified mob.
*/
public boolean canMateWith(EntityAnimal otherAnimal)
{
return otherAnimal != this && otherAnimal instanceof EntityLlama && this.canMate() && ((EntityLlama)otherAnimal).canMate();
}
public EntityLlama createChild(EntityAgeable ageable)
{
EntityLlama entityllama = new EntityLlama(this.world);
this.setOffspringAttributes(ageable, entityllama);
EntityLlama entityllama1 = (EntityLlama)ageable;
int i = this.rand.nextInt(Math.max(this.getStrength(), entityllama1.getStrength())) + 1;
if (this.rand.nextFloat() < 0.03F)
{
++i;
}
entityllama.setStrength(i);
entityllama.setVariant(this.rand.nextBoolean() ? this.getVariant() : entityllama1.getVariant());
return entityllama;
}
private void spit(EntityLivingBase target)
{
EntityLlamaSpit entityllamaspit = new EntityLlamaSpit(this.world, this);
double d0 = target.posX - this.posX;
double d1 = target.getEntityBoundingBox().minY + (double)(target.height / 3.0F) - entityllamaspit.posY;
double d2 = target.posZ - this.posZ;
float f = MathHelper.sqrt(d0 * d0 + d2 * d2) * 0.2F;
entityllamaspit.shoot(d0, d1 + (double)f, d2, 1.5F, 10.0F);
this.world.playSound((EntityPlayer)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_LLAMA_SPIT, this.getSoundCategory(), 1.0F, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F);
this.world.spawnEntity(entityllamaspit);
this.didSpit = true;
}
private void setDidSpit(boolean didSpitIn)
{
this.didSpit = didSpitIn;
}
public void fall(float distance, float damageMultiplier)
{
int i = MathHelper.ceil((distance * 0.5F - 3.0F) * damageMultiplier);
if (i > 0)
{
if (distance >= 6.0F)
{
this.attackEntityFrom(DamageSource.FALL, (float)i);
if (this.isBeingRidden())
{
for (Entity entity : this.getRecursivePassengers())
{
entity.attackEntityFrom(DamageSource.FALL, (float)i);
}
}
}
IBlockState iblockstate = this.world.getBlockState(new BlockPos(this.posX, this.posY - 0.2D - (double)this.prevRotationYaw, this.posZ));
Block block = iblockstate.getBlock();
if (iblockstate.getMaterial() != Material.AIR && !this.isSilent())
{
SoundType soundtype = block.getSoundType();
this.world.playSound((EntityPlayer)null, this.posX, this.posY, this.posZ, soundtype.getStepSound(), this.getSoundCategory(), soundtype.getVolume() * 0.5F, soundtype.getPitch() * 0.75F);
}
}
}
public void leaveCaravan()
{
if (this.caravanHead != null)
{
this.caravanHead.caravanTail = null;
}
this.caravanHead = null;
}
public void joinCaravan(EntityLlama caravanHeadIn)
{
this.caravanHead = caravanHeadIn;
this.caravanHead.caravanTail = this;
}
public boolean hasCaravanTrail()
{
return this.caravanTail != null;
}
public boolean inCaravan()
{
return this.caravanHead != null;
}
@Nullable
public EntityLlama getCaravanHead()
{
return this.caravanHead;
}
protected double followLeashSpeed()
{
return 2.0D;
}
protected void followMother()
{
if (!this.inCaravan() && this.isChild())
{
super.followMother();
}
}
public boolean canEatGrass()
{
return false;
}
/**
* Attack the specified entity using a ranged attack.
*/
public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor)
{
this.spit(target);
}
public void setSwingingArms(boolean swingingArms)
{
}
static class AIDefendTarget extends EntityAINearestAttackableTarget<EntityWolf>
{
public AIDefendTarget(EntityLlama llama)
{
super(llama, EntityWolf.class, 16, false, true, (Predicate)null);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (super.shouldExecute() && this.targetEntity != null && !((EntityWolf)this.targetEntity).isTamed())
{
return true;
}
else
{
this.taskOwner.setAttackTarget((EntityLivingBase)null);
return false;
}
}
protected double getTargetDistance()
{
return super.getTargetDistance() * 0.25D;
}
}
static class AIHurtByTarget extends EntityAIHurtByTarget
{
public AIHurtByTarget(EntityLlama llama)
{
super(llama, false);
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean shouldContinueExecuting()
{
if (this.taskOwner instanceof EntityLlama)
{
EntityLlama entityllama = (EntityLlama)this.taskOwner;
if (entityllama.didSpit)
{
entityllama.setDidSpit(false);
return false;
}
}
return super.shouldContinueExecuting();
}
}
static class GroupData implements IEntityLivingData
{
public int variant;
private GroupData(int variantIn)
{
this.variant = variantIn;
}
}
}

View File

@@ -0,0 +1,127 @@
package net.minecraft.entity.passive;
import javax.annotation.Nullable;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntityMooshroom extends EntityCow implements net.minecraftforge.common.IShearable
{
public EntityMooshroom(World worldIn)
{
super(worldIn);
this.setSize(0.9F, 1.4F);
this.spawnableBlock = Blocks.MYCELIUM;
}
public static void registerFixesMooshroom(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntityMooshroom.class);
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
if (itemstack.getItem() == Items.BOWL && this.getGrowingAge() >= 0 && !player.capabilities.isCreativeMode)
{
itemstack.shrink(1);
if (itemstack.isEmpty())
{
player.setHeldItem(hand, new ItemStack(Items.MUSHROOM_STEW));
}
else if (!player.inventory.addItemStackToInventory(new ItemStack(Items.MUSHROOM_STEW)))
{
player.dropItem(new ItemStack(Items.MUSHROOM_STEW), false);
}
return true;
}
else if (false && itemstack.getItem() == Items.SHEARS && this.getGrowingAge() >= 0) //Forge Disable, Moved to onSheared
{
this.setDead();
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, 0.0D, 0.0D, 0.0D);
if (!this.world.isRemote)
{
EntityCow entitycow = new EntityCow(this.world);
entitycow.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch);
entitycow.setHealth(this.getHealth());
entitycow.renderYawOffset = this.renderYawOffset;
if (this.hasCustomName())
{
entitycow.setCustomNameTag(this.getCustomNameTag());
}
this.world.spawnEntity(entitycow);
for (int i = 0; i < 5; ++i)
{
this.world.spawnEntity(new EntityItem(this.world, this.posX, this.posY + (double)this.height, this.posZ, new ItemStack(Blocks.RED_MUSHROOM)));
}
itemstack.damageItem(1, player);
this.playSound(SoundEvents.ENTITY_MOOSHROOM_SHEAR, 1.0F, 1.0F);
}
return true;
}
else
{
return super.processInteract(player, hand);
}
}
public EntityMooshroom createChild(EntityAgeable ageable)
{
return new EntityMooshroom(this.world);
}
@Override public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, net.minecraft.util.math.BlockPos pos){ return getGrowingAge() >= 0; }
@Override
public java.util.List<ItemStack> onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, net.minecraft.util.math.BlockPos pos, int fortune)
{
this.setDead();
((net.minecraft.world.WorldServer)this.world).spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, false, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, 1, 0.0D, 0.0D, 0.0D, 0.0D);
EntityCow entitycow = new EntityCow(this.world);
entitycow.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch);
entitycow.setHealth(this.getHealth());
entitycow.renderYawOffset = this.renderYawOffset;
if (this.hasCustomName())
{
entitycow.setCustomNameTag(this.getCustomNameTag());
}
this.world.spawnEntity(entitycow);
java.util.List<ItemStack> ret = new java.util.ArrayList<ItemStack>();
for (int i = 0; i < 5; ++i)
{
ret.add(new ItemStack(Blocks.RED_MUSHROOM));
}
this.playSound(SoundEvents.ENTITY_MOOSHROOM_SHEAR, 1.0F, 1.0F);
return ret;
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_MUSHROOM_COW;
}
}

View File

@@ -0,0 +1,52 @@
package net.minecraft.entity.passive;
import javax.annotation.Nullable;
import net.minecraft.init.SoundEvents;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntityMule extends AbstractChestHorse
{
public EntityMule(World worldIn)
{
super(worldIn);
}
public static void registerFixesMule(DataFixer fixer)
{
AbstractChestHorse.registerFixesAbstractChestHorse(fixer, EntityMule.class);
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_MULE;
}
protected SoundEvent getAmbientSound()
{
super.getAmbientSound();
return SoundEvents.ENTITY_MULE_AMBIENT;
}
protected SoundEvent getDeathSound()
{
super.getDeathSound();
return SoundEvents.ENTITY_MULE_DEATH;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
super.getHurtSound(damageSourceIn);
return SoundEvents.ENTITY_MULE_HURT;
}
protected void playChestEquipSound()
{
this.playSound(SoundEvents.ENTITY_MULE_CHEST, 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
}
}

View File

@@ -0,0 +1,413 @@
package net.minecraft.entity.passive;
import com.google.common.base.Predicate;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIAvoidEntity;
import net.minecraft.entity.ai.EntityAIFollowOwner;
import net.minecraft.entity.ai.EntityAILeapAtTarget;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAIOcelotAttack;
import net.minecraft.entity.ai.EntityAIOcelotSit;
import net.minecraft.entity.ai.EntityAISit;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITargetNonTamed;
import net.minecraft.entity.ai.EntityAITempt;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntityOcelot extends EntityTameable
{
private static final DataParameter<Integer> OCELOT_VARIANT = EntityDataManager.<Integer>createKey(EntityOcelot.class, DataSerializers.VARINT);
private EntityAIAvoidEntity<EntityPlayer> avoidEntity;
/** The tempt AI task for this mob, used to prevent taming while it is fleeing. */
private EntityAITempt aiTempt;
public EntityOcelot(World worldIn)
{
super(worldIn);
this.setSize(0.6F, 0.7F);
}
protected void initEntityAI()
{
this.aiSit = new EntityAISit(this);
this.aiTempt = new EntityAITempt(this, 0.6D, Items.FISH, true);
this.tasks.addTask(1, new EntityAISwimming(this));
this.tasks.addTask(2, this.aiSit);
this.tasks.addTask(3, this.aiTempt);
this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 5.0F));
this.tasks.addTask(6, new EntityAIOcelotSit(this, 0.8D));
this.tasks.addTask(7, new EntityAILeapAtTarget(this, 0.3F));
this.tasks.addTask(8, new EntityAIOcelotAttack(this));
this.tasks.addTask(9, new EntityAIMate(this, 0.8D));
this.tasks.addTask(10, new EntityAIWanderAvoidWater(this, 0.8D, 1.0000001E-5F));
this.tasks.addTask(11, new EntityAIWatchClosest(this, EntityPlayer.class, 10.0F));
this.targetTasks.addTask(1, new EntityAITargetNonTamed(this, EntityChicken.class, false, (Predicate)null));
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(OCELOT_VARIANT, Integer.valueOf(0));
}
public void updateAITasks()
{
if (this.getMoveHelper().isUpdating())
{
double d0 = this.getMoveHelper().getSpeed();
if (d0 == 0.6D)
{
this.setSneaking(true);
this.setSprinting(false);
}
else if (d0 == 1.33D)
{
this.setSneaking(false);
this.setSprinting(true);
}
else
{
this.setSneaking(false);
this.setSprinting(false);
}
}
else
{
this.setSneaking(false);
this.setSprinting(false);
}
}
/**
* Determines if an entity can be despawned, used on idle far away entities
*/
protected boolean canDespawn()
{
return !this.isTamed() && this.ticksExisted > 2400;
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.30000001192092896D);
}
public void fall(float distance, float damageMultiplier)
{
}
public static void registerFixesOcelot(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntityOcelot.class);
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setInteger("CatType", this.getTameSkin());
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.setTameSkin(compound.getInteger("CatType"));
}
@Nullable
protected SoundEvent getAmbientSound()
{
if (this.isTamed())
{
if (this.isInLove())
{
return SoundEvents.ENTITY_CAT_PURR;
}
else
{
return this.rand.nextInt(4) == 0 ? SoundEvents.ENTITY_CAT_PURREOW : SoundEvents.ENTITY_CAT_AMBIENT;
}
}
else
{
return null;
}
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_CAT_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_CAT_DEATH;
}
/**
* Returns the volume for the sounds this mob makes.
*/
protected float getSoundVolume()
{
return 0.4F;
}
public boolean attackEntityAsMob(Entity entityIn)
{
return entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), 3.0F);
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource source, float amount)
{
if (this.isEntityInvulnerable(source))
{
return false;
}
else
{
if (this.aiSit != null)
{
this.aiSit.setSitting(false);
}
return super.attackEntityFrom(source, amount);
}
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_OCELOT;
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
if (this.isTamed())
{
if (this.isOwner(player) && !this.world.isRemote && !this.isBreedingItem(itemstack))
{
this.aiSit.setSitting(!this.isSitting());
}
}
else if ((this.aiTempt == null || this.aiTempt.isRunning()) && itemstack.getItem() == Items.FISH && player.getDistanceSq(this) < 9.0D)
{
if (!player.capabilities.isCreativeMode)
{
itemstack.shrink(1);
}
if (!this.world.isRemote)
{
if (this.rand.nextInt(3) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, player))
{
this.setTamedBy(player);
this.setTameSkin(1 + this.world.rand.nextInt(3));
this.playTameEffect(true);
this.aiSit.setSitting(true);
this.world.setEntityState(this, (byte)7);
}
else
{
this.playTameEffect(false);
this.world.setEntityState(this, (byte)6);
}
}
return true;
}
return super.processInteract(player, hand);
}
public EntityOcelot createChild(EntityAgeable ageable)
{
EntityOcelot entityocelot = new EntityOcelot(this.world);
if (this.isTamed())
{
entityocelot.setOwnerId(this.getOwnerId());
entityocelot.setTamed(true);
entityocelot.setTameSkin(this.getTameSkin());
}
return entityocelot;
}
/**
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
* the animal type)
*/
public boolean isBreedingItem(ItemStack stack)
{
return stack.getItem() == Items.FISH;
}
/**
* Returns true if the mob is currently able to mate with the specified mob.
*/
public boolean canMateWith(EntityAnimal otherAnimal)
{
if (otherAnimal == this)
{
return false;
}
else if (!this.isTamed())
{
return false;
}
else if (!(otherAnimal instanceof EntityOcelot))
{
return false;
}
else
{
EntityOcelot entityocelot = (EntityOcelot)otherAnimal;
if (!entityocelot.isTamed())
{
return false;
}
else
{
return this.isInLove() && entityocelot.isInLove();
}
}
}
public int getTameSkin()
{
return ((Integer)this.dataManager.get(OCELOT_VARIANT)).intValue();
}
public void setTameSkin(int skinId)
{
this.dataManager.set(OCELOT_VARIANT, Integer.valueOf(skinId));
}
/**
* Checks if the entity's current position is a valid location to spawn this entity.
*/
public boolean getCanSpawnHere()
{
return this.world.rand.nextInt(3) != 0;
}
/**
* Checks that the entity is not colliding with any blocks / liquids
*/
public boolean isNotColliding()
{
if (this.world.checkNoEntityCollision(this.getEntityBoundingBox(), this) && this.world.getCollisionBoxes(this, this.getEntityBoundingBox()).isEmpty() && !this.world.containsAnyLiquid(this.getEntityBoundingBox()))
{
BlockPos blockpos = new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ);
if (blockpos.getY() < this.world.getSeaLevel())
{
return false;
}
IBlockState iblockstate = this.world.getBlockState(blockpos.down());
Block block = iblockstate.getBlock();
if (block == Blocks.GRASS || block.isLeaves(iblockstate, this.world, blockpos.down()))
{
return true;
}
}
return false;
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
if (this.hasCustomName())
{
return this.getCustomNameTag();
}
else
{
return this.isTamed() ? I18n.translateToLocal("entity.Cat.name") : super.getName();
}
}
protected void setupTamedAI()
{
if (this.avoidEntity == null)
{
this.avoidEntity = new EntityAIAvoidEntity<EntityPlayer>(this, EntityPlayer.class, 16.0F, 0.8D, 1.33D);
}
this.tasks.removeTask(this.avoidEntity);
if (!this.isTamed())
{
this.tasks.addTask(4, this.avoidEntity);
}
}
/**
* Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called
* when entity is reloaded from nbt. Mainly used for initializing attributes and inventory
*/
@Nullable
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata)
{
livingdata = super.onInitialSpawn(difficulty, livingdata);
if (this.getTameSkin() == 0 && this.world.rand.nextInt(7) == 0)
{
for (int i = 0; i < 2; ++i)
{
EntityOcelot entityocelot = new EntityOcelot(this.world);
entityocelot.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F);
entityocelot.setGrowingAge(-24000);
this.world.spawnEntity(entityocelot);
}
}
return livingdata;
}
}

View File

@@ -0,0 +1,542 @@
package net.minecraft.entity.passive;
import com.google.common.base.Predicate;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLeaves;
import net.minecraft.block.BlockLog;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIFollow;
import net.minecraft.entity.ai.EntityAIFollowOwnerFlying;
import net.minecraft.entity.ai.EntityAILandOnOwnersShoulder;
import net.minecraft.entity.ai.EntityAIPanic;
import net.minecraft.entity.ai.EntityAISit;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAIWanderAvoidWaterFlying;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.ai.EntityFlyHelper;
import net.minecraft.entity.boss.EntityDragon;
import net.minecraft.entity.boss.EntityWither;
import net.minecraft.entity.monster.EntityBlaze;
import net.minecraft.entity.monster.EntityCaveSpider;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.monster.EntityElderGuardian;
import net.minecraft.entity.monster.EntityEnderman;
import net.minecraft.entity.monster.EntityEndermite;
import net.minecraft.entity.monster.EntityEvoker;
import net.minecraft.entity.monster.EntityGhast;
import net.minecraft.entity.monster.EntityHusk;
import net.minecraft.entity.monster.EntityIllusionIllager;
import net.minecraft.entity.monster.EntityMagmaCube;
import net.minecraft.entity.monster.EntityPigZombie;
import net.minecraft.entity.monster.EntityPolarBear;
import net.minecraft.entity.monster.EntityShulker;
import net.minecraft.entity.monster.EntitySilverfish;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.entity.monster.EntitySlime;
import net.minecraft.entity.monster.EntitySpider;
import net.minecraft.entity.monster.EntityStray;
import net.minecraft.entity.monster.EntityVex;
import net.minecraft.entity.monster.EntityVindicator;
import net.minecraft.entity.monster.EntityWitch;
import net.minecraft.entity.monster.EntityWitherSkeleton;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.monster.EntityZombieVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.pathfinding.PathNavigate;
import net.minecraft.pathfinding.PathNavigateFlying;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class EntityParrot extends EntityShoulderRiding implements EntityFlying
{
private static final DataParameter<Integer> VARIANT = EntityDataManager.<Integer>createKey(EntityParrot.class, DataSerializers.VARINT);
/** Used to select entities the parrot can mimic the sound of */
private static final Predicate<EntityLiving> CAN_MIMIC = new Predicate<EntityLiving>()
{
public boolean apply(@Nullable EntityLiving p_apply_1_)
{
return p_apply_1_ != null && EntityParrot.MIMIC_SOUNDS.containsKey(p_apply_1_.getClass());
}
};
private static final Item DEADLY_ITEM = Items.COOKIE;
private static final Set<Item> TAME_ITEMS = Sets.newHashSet(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS);
private static final java.util.Map<Class<? extends Entity>, SoundEvent> MIMIC_SOUNDS = Maps.newHashMapWithExpectedSize(32);
public float flap;
public float flapSpeed;
public float oFlapSpeed;
public float oFlap;
public float flapping = 1.0F;
private boolean partyParrot;
private BlockPos jukeboxPosition;
public EntityParrot(World worldIn)
{
super(worldIn);
this.setSize(0.5F, 0.9F);
this.moveHelper = new EntityFlyHelper(this);
}
/**
* Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called
* when entity is reloaded from nbt. Mainly used for initializing attributes and inventory
*/
@Nullable
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata)
{
this.setVariant(this.rand.nextInt(5));
return super.onInitialSpawn(difficulty, livingdata);
}
protected void initEntityAI()
{
this.aiSit = new EntityAISit(this);
this.tasks.addTask(0, new EntityAIPanic(this, 1.25D));
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.tasks.addTask(2, this.aiSit);
this.tasks.addTask(2, new EntityAIFollowOwnerFlying(this, 1.0D, 5.0F, 1.0F));
this.tasks.addTask(2, new EntityAIWanderAvoidWaterFlying(this, 1.0D));
this.tasks.addTask(3, new EntityAILandOnOwnersShoulder(this));
this.tasks.addTask(3, new EntityAIFollow(this, 1.0D, 3.0F, 7.0F));
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getAttributeMap().registerAttribute(SharedMonsterAttributes.FLYING_SPEED);
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(6.0D);
this.getEntityAttribute(SharedMonsterAttributes.FLYING_SPEED).setBaseValue(0.4000000059604645D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.20000000298023224D);
}
/**
* Returns new PathNavigateGround instance
*/
protected PathNavigate createNavigator(World worldIn)
{
PathNavigateFlying pathnavigateflying = new PathNavigateFlying(this, worldIn);
pathnavigateflying.setCanOpenDoors(false);
pathnavigateflying.setCanFloat(true);
pathnavigateflying.setCanEnterDoors(true);
return pathnavigateflying;
}
public float getEyeHeight()
{
return this.height * 0.6F;
}
/**
* 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()
{
playMimicSound(this.world, this);
if (this.jukeboxPosition == null || this.jukeboxPosition.distanceSq(this.posX, this.posY, this.posZ) > 12.0D || this.world.getBlockState(this.jukeboxPosition).getBlock() != Blocks.JUKEBOX)
{
this.partyParrot = false;
this.jukeboxPosition = null;
}
super.onLivingUpdate();
this.calculateFlapping();
}
@SideOnly(Side.CLIENT)
public void setPartying(BlockPos pos, boolean p_191987_2_)
{
this.jukeboxPosition = pos;
this.partyParrot = p_191987_2_;
}
@SideOnly(Side.CLIENT)
public boolean isPartying()
{
return this.partyParrot;
}
private void calculateFlapping()
{
this.oFlap = this.flap;
this.oFlapSpeed = this.flapSpeed;
this.flapSpeed = (float)((double)this.flapSpeed + (double)(this.onGround ? -1 : 4) * 0.3D);
this.flapSpeed = MathHelper.clamp(this.flapSpeed, 0.0F, 1.0F);
if (!this.onGround && this.flapping < 1.0F)
{
this.flapping = 1.0F;
}
this.flapping = (float)((double)this.flapping * 0.9D);
if (!this.onGround && this.motionY < 0.0D)
{
this.motionY *= 0.6D;
}
this.flap += this.flapping * 2.0F;
}
private static boolean playMimicSound(World worldIn, Entity p_192006_1_)
{
if (!p_192006_1_.isSilent() && worldIn.rand.nextInt(50) == 0)
{
List<EntityLiving> list = worldIn.<EntityLiving>getEntitiesWithinAABB(EntityLiving.class, p_192006_1_.getEntityBoundingBox().grow(20.0D), CAN_MIMIC);
if (!list.isEmpty())
{
EntityLiving entityliving = list.get(worldIn.rand.nextInt(list.size()));
if (!entityliving.isSilent())
{
SoundEvent soundevent = MIMIC_SOUNDS.get(entityliving.getClass());
worldIn.playSound((EntityPlayer)null, p_192006_1_.posX, p_192006_1_.posY, p_192006_1_.posZ, soundevent, p_192006_1_.getSoundCategory(), 0.7F, getPitch(worldIn.rand));
return true;
}
}
return false;
}
else
{
return false;
}
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
if (!this.isTamed() && TAME_ITEMS.contains(itemstack.getItem()))
{
if (!player.capabilities.isCreativeMode)
{
itemstack.shrink(1);
}
if (!this.isSilent())
{
this.world.playSound((EntityPlayer)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_PARROT_EAT, this.getSoundCategory(), 1.0F, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F);
}
if (!this.world.isRemote)
{
if (this.rand.nextInt(10) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, player))
{
this.setTamedBy(player);
this.playTameEffect(true);
this.world.setEntityState(this, (byte)7);
}
else
{
this.playTameEffect(false);
this.world.setEntityState(this, (byte)6);
}
}
return true;
}
else if (itemstack.getItem() == DEADLY_ITEM)
{
if (!player.capabilities.isCreativeMode)
{
itemstack.shrink(1);
}
this.addPotionEffect(new PotionEffect(MobEffects.POISON, 900));
if (player.isCreative() || !this.getIsInvulnerable())
{
this.attackEntityFrom(DamageSource.causePlayerDamage(player), Float.MAX_VALUE);
}
return true;
}
else
{
if (!this.world.isRemote && !this.isFlying() && this.isTamed() && this.isOwner(player))
{
this.aiSit.setSitting(!this.isSitting());
}
return super.processInteract(player, hand);
}
}
/**
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
* the animal type)
*/
public boolean isBreedingItem(ItemStack stack)
{
return false;
}
/**
* Checks if the entity's current position is a valid location to spawn this entity.
*/
public boolean getCanSpawnHere()
{
int i = MathHelper.floor(this.posX);
int j = MathHelper.floor(this.getEntityBoundingBox().minY);
int k = MathHelper.floor(this.posZ);
BlockPos blockpos = new BlockPos(i, j, k);
Block block = this.world.getBlockState(blockpos.down()).getBlock();
return block instanceof BlockLeaves || block == Blocks.GRASS || block instanceof BlockLog || block == Blocks.AIR && this.world.getLight(blockpos) > 8 && super.getCanSpawnHere();
}
public void fall(float distance, float damageMultiplier)
{
}
protected void updateFallState(double y, boolean onGroundIn, IBlockState state, BlockPos pos)
{
}
/**
* Returns true if the mob is currently able to mate with the specified mob.
*/
public boolean canMateWith(EntityAnimal otherAnimal)
{
return false;
}
@Nullable
public EntityAgeable createChild(EntityAgeable ageable)
{
return null;
}
public static void playAmbientSound(World worldIn, Entity p_192005_1_)
{
if (!p_192005_1_.isSilent() && !playMimicSound(worldIn, p_192005_1_) && worldIn.rand.nextInt(200) == 0)
{
worldIn.playSound((EntityPlayer)null, p_192005_1_.posX, p_192005_1_.posY, p_192005_1_.posZ, getAmbientSound(worldIn.rand), p_192005_1_.getSoundCategory(), 1.0F, getPitch(worldIn.rand));
}
}
public boolean attackEntityAsMob(Entity entityIn)
{
return entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), 3.0F);
}
@Nullable
public SoundEvent getAmbientSound()
{
return getAmbientSound(this.rand);
}
private static SoundEvent getAmbientSound(Random random)
{
if (random.nextInt(1000) == 0)
{
List<SoundEvent> list = new ArrayList<SoundEvent>(MIMIC_SOUNDS.values());
SoundEvent ret = list.get(random.nextInt(list.size()));
return ret == null ? SoundEvents.ENTITY_PARROT_AMBIENT : ret;
}
else
{
return SoundEvents.ENTITY_PARROT_AMBIENT;
}
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_PARROT_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_PARROT_DEATH;
}
protected void playStepSound(BlockPos pos, Block blockIn)
{
this.playSound(SoundEvents.ENTITY_PARROT_STEP, 0.15F, 1.0F);
}
protected float playFlySound(float p_191954_1_)
{
this.playSound(SoundEvents.ENTITY_PARROT_FLY, 0.15F, 1.0F);
return p_191954_1_ + this.flapSpeed / 2.0F;
}
protected boolean makeFlySound()
{
return true;
}
/**
* Gets the pitch of living sounds in living entities.
*/
protected float getSoundPitch()
{
return getPitch(this.rand);
}
private static float getPitch(Random random)
{
return (random.nextFloat() - random.nextFloat()) * 0.2F + 1.0F;
}
public SoundCategory getSoundCategory()
{
return SoundCategory.NEUTRAL;
}
/**
* Returns true if this entity should push and be pushed by other entities when colliding.
*/
public boolean canBePushed()
{
return true;
}
protected void collideWithEntity(Entity entityIn)
{
if (!(entityIn instanceof EntityPlayer))
{
super.collideWithEntity(entityIn);
}
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource source, float amount)
{
if (this.isEntityInvulnerable(source))
{
return false;
}
else
{
if (this.aiSit != null)
{
this.aiSit.setSitting(false);
}
return super.attackEntityFrom(source, amount);
}
}
public int getVariant()
{
return MathHelper.clamp(((Integer)this.dataManager.get(VARIANT)).intValue(), 0, 4);
}
public void setVariant(int p_191997_1_)
{
this.dataManager.set(VARIANT, Integer.valueOf(p_191997_1_));
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(VARIANT, Integer.valueOf(0));
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setInteger("Variant", this.getVariant());
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.setVariant(compound.getInteger("Variant"));
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_PARROT;
}
public boolean isFlying()
{
return !this.onGround;
}
static
{
registerMimicSound(EntityBlaze.class, SoundEvents.E_PARROT_IM_BLAZE);
registerMimicSound(EntityCaveSpider.class, SoundEvents.E_PARROT_IM_SPIDER);
registerMimicSound(EntityCreeper.class, SoundEvents.E_PARROT_IM_CREEPER);
registerMimicSound(EntityElderGuardian.class, SoundEvents.E_PARROT_IM_ELDER_GUARDIAN);
registerMimicSound(EntityDragon.class, SoundEvents.E_PARROT_IM_ENDERDRAGON);
registerMimicSound(EntityEnderman.class, SoundEvents.E_PARROT_IM_ENDERMAN);
registerMimicSound(EntityEndermite.class, SoundEvents.E_PARROT_IM_ENDERMITE);
registerMimicSound(EntityEvoker.class, SoundEvents.E_PARROT_IM_EVOCATION_ILLAGER);
registerMimicSound(EntityGhast.class, SoundEvents.E_PARROT_IM_GHAST);
registerMimicSound(EntityHusk.class, SoundEvents.E_PARROT_IM_HUSK);
registerMimicSound(EntityIllusionIllager.class, SoundEvents.E_PARROT_IM_ILLUSION_ILLAGER);
registerMimicSound(EntityMagmaCube.class, SoundEvents.E_PARROT_IM_MAGMACUBE);
registerMimicSound(EntityPigZombie.class, SoundEvents.E_PARROT_IM_ZOMBIE_PIGMAN);
registerMimicSound(EntityPolarBear.class, SoundEvents.E_PARROT_IM_POLAR_BEAR);
registerMimicSound(EntityShulker.class, SoundEvents.E_PARROT_IM_SHULKER);
registerMimicSound(EntitySilverfish.class, SoundEvents.E_PARROT_IM_SILVERFISH);
registerMimicSound(EntitySkeleton.class, SoundEvents.E_PARROT_IM_SKELETON);
registerMimicSound(EntitySlime.class, SoundEvents.E_PARROT_IM_SLIME);
registerMimicSound(EntitySpider.class, SoundEvents.E_PARROT_IM_SPIDER);
registerMimicSound(EntityStray.class, SoundEvents.E_PARROT_IM_STRAY);
registerMimicSound(EntityVex.class, SoundEvents.E_PARROT_IM_VEX);
registerMimicSound(EntityVindicator.class, SoundEvents.E_PARROT_IM_VINDICATION_ILLAGER);
registerMimicSound(EntityWitch.class, SoundEvents.E_PARROT_IM_WITCH);
registerMimicSound(EntityWither.class, SoundEvents.E_PARROT_IM_WITHER);
registerMimicSound(EntityWitherSkeleton.class, SoundEvents.E_PARROT_IM_WITHER_SKELETON);
registerMimicSound(EntityWolf.class, SoundEvents.E_PARROT_IM_WOLF);
registerMimicSound(EntityZombie.class, SoundEvents.E_PARROT_IM_ZOMBIE);
registerMimicSound(EntityZombieVillager.class, SoundEvents.E_PARROT_IM_ZOMBIE_VILLAGER);
}
public static void registerMimicSound(Class<? extends Entity> cls, SoundEvent sound)
{
MIMIC_SOUNDS.put(cls, sound);
}
}

View File

@@ -0,0 +1,360 @@
package net.minecraft.entity.passive;
import com.google.common.collect.Sets;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIFollowParent;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAIPanic;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITempt;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraft.entity.monster.EntityPigZombie;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntityPig extends EntityAnimal
{
private static final DataParameter<Boolean> SADDLED = EntityDataManager.<Boolean>createKey(EntityPig.class, DataSerializers.BOOLEAN);
private static final DataParameter<Integer> BOOST_TIME = EntityDataManager.<Integer>createKey(EntityPig.class, DataSerializers.VARINT);
private static final Set<Item> TEMPTATION_ITEMS = Sets.newHashSet(Items.CARROT, Items.POTATO, Items.BEETROOT);
private boolean boosting;
private int boostTime;
private int totalBoostTime;
public EntityPig(World worldIn)
{
super(worldIn);
this.setSize(0.9F, 0.9F);
}
protected void initEntityAI()
{
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityAIPanic(this, 1.25D));
this.tasks.addTask(3, new EntityAIMate(this, 1.0D));
this.tasks.addTask(4, new EntityAITempt(this, 1.2D, Items.CARROT_ON_A_STICK, false));
this.tasks.addTask(4, new EntityAITempt(this, 1.2D, false, TEMPTATION_ITEMS));
this.tasks.addTask(5, new EntityAIFollowParent(this, 1.1D));
this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D));
this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
this.tasks.addTask(8, new EntityAILookIdle(this));
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.25D);
}
/**
* For vehicles, the first passenger is generally considered the controller and "drives" the vehicle. For example,
* Pigs, Horses, and Boats are generally "steered" by the controlling passenger.
*/
@Nullable
public Entity getControllingPassenger()
{
return this.getPassengers().isEmpty() ? null : (Entity)this.getPassengers().get(0);
}
/**
* 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()
{
Entity entity = this.getControllingPassenger();
if (!(entity instanceof EntityPlayer))
{
return false;
}
else
{
EntityPlayer entityplayer = (EntityPlayer)entity;
return entityplayer.getHeldItemMainhand().getItem() == Items.CARROT_ON_A_STICK || entityplayer.getHeldItemOffhand().getItem() == Items.CARROT_ON_A_STICK;
}
}
public void notifyDataManagerChange(DataParameter<?> key)
{
if (BOOST_TIME.equals(key) && this.world.isRemote)
{
this.boosting = true;
this.boostTime = 0;
this.totalBoostTime = ((Integer)this.dataManager.get(BOOST_TIME)).intValue();
}
super.notifyDataManagerChange(key);
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(SADDLED, Boolean.valueOf(false));
this.dataManager.register(BOOST_TIME, Integer.valueOf(0));
}
public static void registerFixesPig(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntityPig.class);
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setBoolean("Saddle", this.getSaddled());
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.setSaddled(compound.getBoolean("Saddle"));
}
protected SoundEvent getAmbientSound()
{
return SoundEvents.ENTITY_PIG_AMBIENT;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_PIG_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_PIG_DEATH;
}
protected void playStepSound(BlockPos pos, Block blockIn)
{
this.playSound(SoundEvents.ENTITY_PIG_STEP, 0.15F, 1.0F);
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
if (!super.processInteract(player, hand))
{
ItemStack itemstack = player.getHeldItem(hand);
if (itemstack.getItem() == Items.NAME_TAG)
{
itemstack.interactWithEntity(player, this, hand);
return true;
}
else if (this.getSaddled() && !this.isBeingRidden())
{
if (!this.world.isRemote)
{
player.startRiding(this);
}
return true;
}
else if (itemstack.getItem() == Items.SADDLE)
{
itemstack.interactWithEntity(player, this, hand);
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
/**
* Called when the mob's health reaches 0.
*/
public void onDeath(DamageSource cause)
{
super.onDeath(cause);
if (!this.world.isRemote)
{
if (this.getSaddled())
{
this.dropItem(Items.SADDLE, 1);
}
}
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_PIG;
}
/**
* Returns true if the pig is saddled.
*/
public boolean getSaddled()
{
return ((Boolean)this.dataManager.get(SADDLED)).booleanValue();
}
/**
* Set or remove the saddle of the pig.
*/
public void setSaddled(boolean saddled)
{
if (saddled)
{
this.dataManager.set(SADDLED, Boolean.valueOf(true));
}
else
{
this.dataManager.set(SADDLED, Boolean.valueOf(false));
}
}
/**
* Called when a lightning bolt hits the entity.
*/
public void onStruckByLightning(EntityLightningBolt lightningBolt)
{
if (!this.world.isRemote && !this.isDead)
{
EntityPigZombie entitypigzombie = new EntityPigZombie(this.world);
entitypigzombie.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.GOLDEN_SWORD));
entitypigzombie.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch);
entitypigzombie.setNoAI(this.isAIDisabled());
if (this.hasCustomName())
{
entitypigzombie.setCustomNameTag(this.getCustomNameTag());
entitypigzombie.setAlwaysRenderNameTag(this.getAlwaysRenderNameTag());
}
this.world.spawnEntity(entitypigzombie);
this.setDead();
}
}
public void travel(float strafe, float vertical, float forward)
{
Entity entity = this.getPassengers().isEmpty() ? null : (Entity)this.getPassengers().get(0);
if (this.isBeingRidden() && this.canBeSteered())
{
this.rotationYaw = entity.rotationYaw;
this.prevRotationYaw = this.rotationYaw;
this.rotationPitch = entity.rotationPitch * 0.5F;
this.setRotation(this.rotationYaw, this.rotationPitch);
this.renderYawOffset = this.rotationYaw;
this.rotationYawHead = this.rotationYaw;
this.stepHeight = 1.0F;
this.jumpMovementFactor = this.getAIMoveSpeed() * 0.1F;
if (this.boosting && this.boostTime++ > this.totalBoostTime)
{
this.boosting = false;
}
if (this.canPassengerSteer())
{
float f = (float)this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).getAttributeValue() * 0.225F;
if (this.boosting)
{
f += f * 1.15F * MathHelper.sin((float)this.boostTime / (float)this.totalBoostTime * (float)Math.PI);
}
this.setAIMoveSpeed(f);
super.travel(0.0F, 0.0F, 1.0F);
}
else
{
this.motionX = 0.0D;
this.motionY = 0.0D;
this.motionZ = 0.0D;
}
this.prevLimbSwingAmount = this.limbSwingAmount;
double d1 = this.posX - this.prevPosX;
double d0 = this.posZ - this.prevPosZ;
float f1 = MathHelper.sqrt(d1 * d1 + d0 * d0) * 4.0F;
if (f1 > 1.0F)
{
f1 = 1.0F;
}
this.limbSwingAmount += (f1 - this.limbSwingAmount) * 0.4F;
this.limbSwing += this.limbSwingAmount;
}
else
{
this.stepHeight = 0.5F;
this.jumpMovementFactor = 0.02F;
super.travel(strafe, vertical, forward);
}
}
public boolean boost()
{
if (this.boosting)
{
return false;
}
else
{
this.boosting = true;
this.boostTime = 0;
this.totalBoostTime = this.getRNG().nextInt(841) + 140;
this.getDataManager().set(BOOST_TIME, Integer.valueOf(this.totalBoostTime));
return true;
}
}
public EntityPig createChild(EntityAgeable ageable)
{
return new EntityPig(this.world);
}
/**
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
* the animal type)
*/
public boolean isBreedingItem(ItemStack stack)
{
return TEMPTATION_ITEMS.contains(stack.getItem());
}
}

View File

@@ -0,0 +1,771 @@
package net.minecraft.entity.passive;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockCarrot;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIAttackMelee;
import net.minecraft.entity.ai.EntityAIAvoidEntity;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAIMoveToBlock;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAIPanic;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITempt;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.ai.EntityJumpHelper;
import net.minecraft.entity.ai.EntityMoveHelper;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.pathfinding.Path;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeDesert;
import net.minecraft.world.storage.loot.LootTableList;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class EntityRabbit extends EntityAnimal
{
private static final DataParameter<Integer> RABBIT_TYPE = EntityDataManager.<Integer>createKey(EntityRabbit.class, DataSerializers.VARINT);
private int jumpTicks;
private int jumpDuration;
private boolean wasOnGround;
private int currentMoveTypeDuration;
private int carrotTicks;
public EntityRabbit(World worldIn)
{
super(worldIn);
this.setSize(0.4F, 0.5F);
this.jumpHelper = new EntityRabbit.RabbitJumpHelper(this);
this.moveHelper = new EntityRabbit.RabbitMoveHelper(this);
this.setMovementSpeed(0.0D);
}
protected void initEntityAI()
{
this.tasks.addTask(1, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityRabbit.AIPanic(this, 2.2D));
this.tasks.addTask(2, new EntityAIMate(this, 0.8D));
this.tasks.addTask(3, new EntityAITempt(this, 1.0D, Items.CARROT, false));
this.tasks.addTask(3, new EntityAITempt(this, 1.0D, Items.GOLDEN_CARROT, false));
this.tasks.addTask(3, new EntityAITempt(this, 1.0D, Item.getItemFromBlock(Blocks.YELLOW_FLOWER), false));
this.tasks.addTask(4, new EntityRabbit.AIAvoidEntity(this, EntityPlayer.class, 8.0F, 2.2D, 2.2D));
this.tasks.addTask(4, new EntityRabbit.AIAvoidEntity(this, EntityWolf.class, 10.0F, 2.2D, 2.2D));
this.tasks.addTask(4, new EntityRabbit.AIAvoidEntity(this, EntityMob.class, 4.0F, 2.2D, 2.2D));
this.tasks.addTask(5, new EntityRabbit.AIRaidFarm(this));
this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 0.6D));
this.tasks.addTask(11, new EntityAIWatchClosest(this, EntityPlayer.class, 10.0F));
}
protected float getJumpUpwardsMotion()
{
if (!this.collidedHorizontally && (!this.moveHelper.isUpdating() || this.moveHelper.getY() <= this.posY + 0.5D))
{
Path path = this.navigator.getPath();
if (path != null && path.getCurrentPathIndex() < path.getCurrentPathLength())
{
Vec3d vec3d = path.getPosition(this);
if (vec3d.y > this.posY + 0.5D)
{
return 0.5F;
}
}
return this.moveHelper.getSpeed() <= 0.6D ? 0.2F : 0.3F;
}
else
{
return 0.5F;
}
}
/**
* Causes this entity to do an upwards motion (jumping).
*/
protected void jump()
{
super.jump();
double d0 = this.moveHelper.getSpeed();
if (d0 > 0.0D)
{
double d1 = this.motionX * this.motionX + this.motionZ * this.motionZ;
if (d1 < 0.010000000000000002D)
{
this.moveRelative(0.0F, 0.0F, 1.0F, 0.1F);
}
}
if (!this.world.isRemote)
{
this.world.setEntityState(this, (byte)1);
}
}
@SideOnly(Side.CLIENT)
public float setJumpCompletion(float p_175521_1_)
{
return this.jumpDuration == 0 ? 0.0F : ((float)this.jumpTicks + p_175521_1_) / (float)this.jumpDuration;
}
public void setMovementSpeed(double newSpeed)
{
this.getNavigator().setSpeed(newSpeed);
this.moveHelper.setMoveTo(this.moveHelper.getX(), this.moveHelper.getY(), this.moveHelper.getZ(), newSpeed);
}
public void setJumping(boolean jumping)
{
super.setJumping(jumping);
if (jumping)
{
this.playSound(this.getJumpSound(), this.getSoundVolume(), ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) * 0.8F);
}
}
public void startJumping()
{
this.setJumping(true);
this.jumpDuration = 10;
this.jumpTicks = 0;
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(RABBIT_TYPE, Integer.valueOf(0));
}
public void updateAITasks()
{
if (this.currentMoveTypeDuration > 0)
{
--this.currentMoveTypeDuration;
}
if (this.carrotTicks > 0)
{
this.carrotTicks -= this.rand.nextInt(3);
if (this.carrotTicks < 0)
{
this.carrotTicks = 0;
}
}
if (this.onGround)
{
if (!this.wasOnGround)
{
this.setJumping(false);
this.checkLandingDelay();
}
if (this.getRabbitType() == 99 && this.currentMoveTypeDuration == 0)
{
EntityLivingBase entitylivingbase = this.getAttackTarget();
if (entitylivingbase != null && this.getDistanceSq(entitylivingbase) < 16.0D)
{
this.calculateRotationYaw(entitylivingbase.posX, entitylivingbase.posZ);
this.moveHelper.setMoveTo(entitylivingbase.posX, entitylivingbase.posY, entitylivingbase.posZ, this.moveHelper.getSpeed());
this.startJumping();
this.wasOnGround = true;
}
}
EntityRabbit.RabbitJumpHelper entityrabbit$rabbitjumphelper = (EntityRabbit.RabbitJumpHelper)this.jumpHelper;
if (!entityrabbit$rabbitjumphelper.getIsJumping())
{
if (this.moveHelper.isUpdating() && this.currentMoveTypeDuration == 0)
{
Path path = this.navigator.getPath();
Vec3d vec3d = new Vec3d(this.moveHelper.getX(), this.moveHelper.getY(), this.moveHelper.getZ());
if (path != null && path.getCurrentPathIndex() < path.getCurrentPathLength())
{
vec3d = path.getPosition(this);
}
this.calculateRotationYaw(vec3d.x, vec3d.z);
this.startJumping();
}
}
else if (!entityrabbit$rabbitjumphelper.canJump())
{
this.enableJumpControl();
}
}
this.wasOnGround = this.onGround;
}
/**
* Attempts to create sprinting particles if the entity is sprinting and not in water.
*/
public void spawnRunningParticles()
{
}
private void calculateRotationYaw(double x, double z)
{
this.rotationYaw = (float)(MathHelper.atan2(z - this.posZ, x - this.posX) * (180D / Math.PI)) - 90.0F;
}
private void enableJumpControl()
{
((EntityRabbit.RabbitJumpHelper)this.jumpHelper).setCanJump(true);
}
private void disableJumpControl()
{
((EntityRabbit.RabbitJumpHelper)this.jumpHelper).setCanJump(false);
}
private void updateMoveTypeDuration()
{
if (this.moveHelper.getSpeed() < 2.2D)
{
this.currentMoveTypeDuration = 10;
}
else
{
this.currentMoveTypeDuration = 1;
}
}
private void checkLandingDelay()
{
this.updateMoveTypeDuration();
this.disableJumpControl();
}
/**
* 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();
if (this.jumpTicks != this.jumpDuration)
{
++this.jumpTicks;
}
else if (this.jumpDuration != 0)
{
this.jumpTicks = 0;
this.jumpDuration = 0;
this.setJumping(false);
}
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(3.0D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.30000001192092896D);
}
public static void registerFixesRabbit(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntityRabbit.class);
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setInteger("RabbitType", this.getRabbitType());
compound.setInteger("MoreCarrotTicks", this.carrotTicks);
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.setRabbitType(compound.getInteger("RabbitType"));
this.carrotTicks = compound.getInteger("MoreCarrotTicks");
}
protected SoundEvent getJumpSound()
{
return SoundEvents.ENTITY_RABBIT_JUMP;
}
protected SoundEvent getAmbientSound()
{
return SoundEvents.ENTITY_RABBIT_AMBIENT;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_RABBIT_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_RABBIT_DEATH;
}
public boolean attackEntityAsMob(Entity entityIn)
{
if (this.getRabbitType() == 99)
{
this.playSound(SoundEvents.ENTITY_RABBIT_ATTACK, 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
return entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), 8.0F);
}
else
{
return entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), 3.0F);
}
}
public SoundCategory getSoundCategory()
{
return this.getRabbitType() == 99 ? SoundCategory.HOSTILE : SoundCategory.NEUTRAL;
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource source, float amount)
{
return this.isEntityInvulnerable(source) ? false : super.attackEntityFrom(source, amount);
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_RABBIT;
}
private boolean isRabbitBreedingItem(Item itemIn)
{
return itemIn == Items.CARROT || itemIn == Items.GOLDEN_CARROT || itemIn == Item.getItemFromBlock(Blocks.YELLOW_FLOWER);
}
public EntityRabbit createChild(EntityAgeable ageable)
{
EntityRabbit entityrabbit = new EntityRabbit(this.world);
int i = this.getRandomRabbitType();
if (this.rand.nextInt(20) != 0)
{
if (ageable instanceof EntityRabbit && this.rand.nextBoolean())
{
i = ((EntityRabbit)ageable).getRabbitType();
}
else
{
i = this.getRabbitType();
}
}
entityrabbit.setRabbitType(i);
return entityrabbit;
}
/**
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
* the animal type)
*/
public boolean isBreedingItem(ItemStack stack)
{
return this.isRabbitBreedingItem(stack.getItem());
}
public int getRabbitType()
{
return ((Integer)this.dataManager.get(RABBIT_TYPE)).intValue();
}
public void setRabbitType(int rabbitTypeId)
{
if (rabbitTypeId == 99)
{
this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(8.0D);
this.tasks.addTask(4, new EntityRabbit.AIEvilAttack(this));
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false, new Class[0]));
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, true));
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityWolf.class, true));
if (!this.hasCustomName())
{
this.setCustomNameTag(I18n.translateToLocal("entity.KillerBunny.name"));
}
}
this.dataManager.set(RABBIT_TYPE, Integer.valueOf(rabbitTypeId));
}
/**
* Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called
* when entity is reloaded from nbt. Mainly used for initializing attributes and inventory
*/
@Nullable
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata)
{
livingdata = super.onInitialSpawn(difficulty, livingdata);
int i = this.getRandomRabbitType();
boolean flag = false;
if (livingdata instanceof EntityRabbit.RabbitTypeData)
{
i = ((EntityRabbit.RabbitTypeData)livingdata).typeData;
flag = true;
}
else
{
livingdata = new EntityRabbit.RabbitTypeData(i);
}
this.setRabbitType(i);
if (flag)
{
this.setGrowingAge(-24000);
}
return livingdata;
}
private int getRandomRabbitType()
{
Biome biome = this.world.getBiome(new BlockPos(this));
int i = this.rand.nextInt(100);
if (biome.isSnowyBiome())
{
return i < 80 ? 1 : 3;
}
else if (biome instanceof BiomeDesert)
{
return 4;
}
else
{
return i < 50 ? 0 : (i < 90 ? 5 : 2);
}
}
/**
* Returns true if {@link net.minecraft.entity.passive.EntityRabbit#carrotTicks carrotTicks} has reached zero
*/
private boolean isCarrotEaten()
{
return this.carrotTicks == 0;
}
protected void createEatingParticles()
{
BlockCarrot blockcarrot = (BlockCarrot)Blocks.CARROTS;
IBlockState iblockstate = blockcarrot.withAge(blockcarrot.getMaxAge());
this.world.spawnParticle(EnumParticleTypes.BLOCK_DUST, this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + 0.5D + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, 0.0D, 0.0D, 0.0D, Block.getStateId(iblockstate));
this.carrotTicks = 40;
}
/**
* Handler for {@link World#setEntityState}
*/
@SideOnly(Side.CLIENT)
public void handleStatusUpdate(byte id)
{
if (id == 1)
{
this.createRunningParticles();
this.jumpDuration = 10;
this.jumpTicks = 0;
}
else
{
super.handleStatusUpdate(id);
}
}
static class AIAvoidEntity<T extends Entity> extends EntityAIAvoidEntity<T>
{
private final EntityRabbit rabbit;
public AIAvoidEntity(EntityRabbit rabbit, Class<T> p_i46403_2_, float p_i46403_3_, double p_i46403_4_, double p_i46403_6_)
{
super(rabbit, p_i46403_2_, p_i46403_3_, p_i46403_4_, p_i46403_6_);
this.rabbit = rabbit;
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
return this.rabbit.getRabbitType() != 99 && super.shouldExecute();
}
}
static class AIEvilAttack extends EntityAIAttackMelee
{
public AIEvilAttack(EntityRabbit rabbit)
{
super(rabbit, 1.4D, true);
}
protected double getAttackReachSqr(EntityLivingBase attackTarget)
{
return (double)(4.0F + attackTarget.width);
}
}
static class AIPanic extends EntityAIPanic
{
private final EntityRabbit rabbit;
public AIPanic(EntityRabbit rabbit, double speedIn)
{
super(rabbit, speedIn);
this.rabbit = rabbit;
}
/**
* Keep ticking a continuous task that has already been started
*/
public void updateTask()
{
super.updateTask();
this.rabbit.setMovementSpeed(this.speed);
}
}
static class AIRaidFarm extends EntityAIMoveToBlock
{
private final EntityRabbit rabbit;
private boolean wantsToRaid;
private boolean canRaid;
public AIRaidFarm(EntityRabbit rabbitIn)
{
super(rabbitIn, 0.699999988079071D, 16);
this.rabbit = rabbitIn;
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (this.runDelay <= 0)
{
if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.rabbit.world, this.rabbit))
{
return false;
}
this.canRaid = false;
this.wantsToRaid = this.rabbit.isCarrotEaten();
this.wantsToRaid = true;
}
return super.shouldExecute();
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean shouldContinueExecuting()
{
return this.canRaid && super.shouldContinueExecuting();
}
/**
* Keep ticking a continuous task that has already been started
*/
public void updateTask()
{
super.updateTask();
this.rabbit.getLookHelper().setLookPosition((double)this.destinationBlock.getX() + 0.5D, (double)(this.destinationBlock.getY() + 1), (double)this.destinationBlock.getZ() + 0.5D, 10.0F, (float)this.rabbit.getVerticalFaceSpeed());
if (this.getIsAboveDestination())
{
World world = this.rabbit.world;
BlockPos blockpos = this.destinationBlock.up();
IBlockState iblockstate = world.getBlockState(blockpos);
Block block = iblockstate.getBlock();
if (this.canRaid && block instanceof BlockCarrot)
{
Integer integer = (Integer)iblockstate.getValue(BlockCarrot.AGE);
if (integer.intValue() == 0)
{
world.setBlockState(blockpos, Blocks.AIR.getDefaultState(), 2);
world.destroyBlock(blockpos, true);
}
else
{
world.setBlockState(blockpos, iblockstate.withProperty(BlockCarrot.AGE, Integer.valueOf(integer.intValue() - 1)), 2);
world.playEvent(2001, blockpos, Block.getStateId(iblockstate));
}
this.rabbit.createEatingParticles();
}
this.canRaid = false;
this.runDelay = 10;
}
}
/**
* Return true to set given position as destination
*/
protected boolean shouldMoveTo(World worldIn, BlockPos pos)
{
Block block = worldIn.getBlockState(pos).getBlock();
if (block == Blocks.FARMLAND && this.wantsToRaid && !this.canRaid)
{
pos = pos.up();
IBlockState iblockstate = worldIn.getBlockState(pos);
block = iblockstate.getBlock();
if (block instanceof BlockCarrot && ((BlockCarrot)block).isMaxAge(iblockstate))
{
this.canRaid = true;
return true;
}
}
return false;
}
}
public class RabbitJumpHelper extends EntityJumpHelper
{
private final EntityRabbit rabbit;
private boolean canJump;
public RabbitJumpHelper(EntityRabbit rabbit)
{
super(rabbit);
this.rabbit = rabbit;
}
public boolean getIsJumping()
{
return this.isJumping;
}
public boolean canJump()
{
return this.canJump;
}
public void setCanJump(boolean canJumpIn)
{
this.canJump = canJumpIn;
}
/**
* Called to actually make the entity jump if isJumping is true.
*/
public void doJump()
{
if (this.isJumping)
{
this.rabbit.startJumping();
this.isJumping = false;
}
}
}
static class RabbitMoveHelper extends EntityMoveHelper
{
private final EntityRabbit rabbit;
private double nextJumpSpeed;
public RabbitMoveHelper(EntityRabbit rabbit)
{
super(rabbit);
this.rabbit = rabbit;
}
public void onUpdateMoveHelper()
{
if (this.rabbit.onGround && !this.rabbit.isJumping && !((EntityRabbit.RabbitJumpHelper)this.rabbit.jumpHelper).getIsJumping())
{
this.rabbit.setMovementSpeed(0.0D);
}
else if (this.isUpdating())
{
this.rabbit.setMovementSpeed(this.nextJumpSpeed);
}
super.onUpdateMoveHelper();
}
/**
* Sets the speed and location to move to
*/
public void setMoveTo(double x, double y, double z, double speedIn)
{
if (this.rabbit.isInWater())
{
speedIn = 1.5D;
}
super.setMoveTo(x, y, z, speedIn);
if (speedIn > 0.0D)
{
this.nextJumpSpeed = speedIn;
}
}
}
public static class RabbitTypeData implements IEntityLivingData
{
public int typeData;
public RabbitTypeData(int type)
{
this.typeData = type;
}
}
}

View File

@@ -0,0 +1,468 @@
package net.minecraft.entity.passive;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIEatGrass;
import net.minecraft.entity.ai.EntityAIFollowParent;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAIPanic;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITempt;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class EntitySheep extends EntityAnimal implements net.minecraftforge.common.IShearable
{
private static final DataParameter<Byte> DYE_COLOR = EntityDataManager.<Byte>createKey(EntitySheep.class, DataSerializers.BYTE);
/**
* Internal crafting inventory used to check the result of mixing dyes corresponding to the fleece color when
* breeding sheep.
*/
private final InventoryCrafting inventoryCrafting = new InventoryCrafting(new Container()
{
/**
* Determines whether supplied player can use this container
*/
public boolean canInteractWith(EntityPlayer playerIn)
{
return false;
}
}, 2, 1);
/** Map from EnumDyeColor to RGB values for passage to GlStateManager.color() */
private static final Map<EnumDyeColor, float[]> DYE_TO_RGB = Maps.newEnumMap(EnumDyeColor.class);
/**
* Used to control movement as well as wool regrowth. Set to 40 on handleHealthUpdate and counts down with each
* tick.
*/
private int sheepTimer;
private EntityAIEatGrass entityAIEatGrass;
private static float[] createSheepColor(EnumDyeColor p_192020_0_)
{
float[] afloat = p_192020_0_.getColorComponentValues();
float f = 0.75F;
return new float[] {afloat[0] * 0.75F, afloat[1] * 0.75F, afloat[2] * 0.75F};
}
@SideOnly(Side.CLIENT)
public static float[] getDyeRgb(EnumDyeColor dyeColor)
{
return DYE_TO_RGB.get(dyeColor);
}
public EntitySheep(World worldIn)
{
super(worldIn);
this.setSize(0.9F, 1.3F);
this.inventoryCrafting.setInventorySlotContents(0, new ItemStack(Items.DYE));
this.inventoryCrafting.setInventorySlotContents(1, new ItemStack(Items.DYE));
}
protected void initEntityAI()
{
this.entityAIEatGrass = new EntityAIEatGrass(this);
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityAIPanic(this, 1.25D));
this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
this.tasks.addTask(3, new EntityAITempt(this, 1.1D, Items.WHEAT, false));
this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D));
this.tasks.addTask(5, this.entityAIEatGrass);
this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D));
this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
this.tasks.addTask(8, new EntityAILookIdle(this));
}
protected void updateAITasks()
{
this.sheepTimer = this.entityAIEatGrass.getEatingGrassTimer();
super.updateAITasks();
}
/**
* 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()
{
if (this.world.isRemote)
{
this.sheepTimer = Math.max(0, this.sheepTimer - 1);
}
super.onLivingUpdate();
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(8.0D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D);
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(DYE_COLOR, Byte.valueOf((byte)0));
}
@Nullable
protected ResourceLocation getLootTable()
{
if (this.getSheared())
{
return LootTableList.ENTITIES_SHEEP;
}
else
{
switch (this.getFleeceColor())
{
case WHITE:
default:
return LootTableList.ENTITIES_SHEEP_WHITE;
case ORANGE:
return LootTableList.ENTITIES_SHEEP_ORANGE;
case MAGENTA:
return LootTableList.ENTITIES_SHEEP_MAGENTA;
case LIGHT_BLUE:
return LootTableList.ENTITIES_SHEEP_LIGHT_BLUE;
case YELLOW:
return LootTableList.ENTITIES_SHEEP_YELLOW;
case LIME:
return LootTableList.ENTITIES_SHEEP_LIME;
case PINK:
return LootTableList.ENTITIES_SHEEP_PINK;
case GRAY:
return LootTableList.ENTITIES_SHEEP_GRAY;
case SILVER:
return LootTableList.ENTITIES_SHEEP_SILVER;
case CYAN:
return LootTableList.ENTITIES_SHEEP_CYAN;
case PURPLE:
return LootTableList.ENTITIES_SHEEP_PURPLE;
case BLUE:
return LootTableList.ENTITIES_SHEEP_BLUE;
case BROWN:
return LootTableList.ENTITIES_SHEEP_BROWN;
case GREEN:
return LootTableList.ENTITIES_SHEEP_GREEN;
case RED:
return LootTableList.ENTITIES_SHEEP_RED;
case BLACK:
return LootTableList.ENTITIES_SHEEP_BLACK;
}
}
}
/**
* Handler for {@link World#setEntityState}
*/
@SideOnly(Side.CLIENT)
public void handleStatusUpdate(byte id)
{
if (id == 10)
{
this.sheepTimer = 40;
}
else
{
super.handleStatusUpdate(id);
}
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
if (false && itemstack.getItem() == Items.SHEARS && !this.getSheared() && !this.isChild()) //Forge: Moved to onSheared
{
if (!this.world.isRemote)
{
this.setSheared(true);
int i = 1 + this.rand.nextInt(3);
for (int j = 0; j < i; ++j)
{
EntityItem entityitem = this.entityDropItem(new ItemStack(Item.getItemFromBlock(Blocks.WOOL), 1, this.getFleeceColor().getMetadata()), 1.0F);
entityitem.motionY += (double)(this.rand.nextFloat() * 0.05F);
entityitem.motionX += (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F);
entityitem.motionZ += (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F);
}
}
itemstack.damageItem(1, player);
this.playSound(SoundEvents.ENTITY_SHEEP_SHEAR, 1.0F, 1.0F);
}
return super.processInteract(player, hand);
}
public static void registerFixesSheep(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntitySheep.class);
}
@SideOnly(Side.CLIENT)
public float getHeadRotationPointY(float p_70894_1_)
{
if (this.sheepTimer <= 0)
{
return 0.0F;
}
else if (this.sheepTimer >= 4 && this.sheepTimer <= 36)
{
return 1.0F;
}
else
{
return this.sheepTimer < 4 ? ((float)this.sheepTimer - p_70894_1_) / 4.0F : -((float)(this.sheepTimer - 40) - p_70894_1_) / 4.0F;
}
}
@SideOnly(Side.CLIENT)
public float getHeadRotationAngleX(float p_70890_1_)
{
if (this.sheepTimer > 4 && this.sheepTimer <= 36)
{
float f = ((float)(this.sheepTimer - 4) - p_70890_1_) / 32.0F;
return ((float)Math.PI / 5F) + ((float)Math.PI * 7F / 100F) * MathHelper.sin(f * 28.7F);
}
else
{
return this.sheepTimer > 0 ? ((float)Math.PI / 5F) : this.rotationPitch * 0.017453292F;
}
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setBoolean("Sheared", this.getSheared());
compound.setByte("Color", (byte)this.getFleeceColor().getMetadata());
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.setSheared(compound.getBoolean("Sheared"));
this.setFleeceColor(EnumDyeColor.byMetadata(compound.getByte("Color")));
}
protected SoundEvent getAmbientSound()
{
return SoundEvents.ENTITY_SHEEP_AMBIENT;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_SHEEP_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_SHEEP_DEATH;
}
protected void playStepSound(BlockPos pos, Block blockIn)
{
this.playSound(SoundEvents.ENTITY_SHEEP_STEP, 0.15F, 1.0F);
}
/**
* Gets the wool color of this sheep.
*/
public EnumDyeColor getFleeceColor()
{
return EnumDyeColor.byMetadata(((Byte)this.dataManager.get(DYE_COLOR)).byteValue() & 15);
}
/**
* Sets the wool color of this sheep
*/
public void setFleeceColor(EnumDyeColor color)
{
byte b0 = ((Byte)this.dataManager.get(DYE_COLOR)).byteValue();
this.dataManager.set(DYE_COLOR, Byte.valueOf((byte)(b0 & 240 | color.getMetadata() & 15)));
}
/**
* returns true if a sheeps wool has been sheared
*/
public boolean getSheared()
{
return (((Byte)this.dataManager.get(DYE_COLOR)).byteValue() & 16) != 0;
}
/**
* make a sheep sheared if set to true
*/
public void setSheared(boolean sheared)
{
byte b0 = ((Byte)this.dataManager.get(DYE_COLOR)).byteValue();
if (sheared)
{
this.dataManager.set(DYE_COLOR, Byte.valueOf((byte)(b0 | 16)));
}
else
{
this.dataManager.set(DYE_COLOR, Byte.valueOf((byte)(b0 & -17)));
}
}
/**
* Chooses a "vanilla" sheep color based on the provided random.
*/
public static EnumDyeColor getRandomSheepColor(Random random)
{
int i = random.nextInt(100);
if (i < 5)
{
return EnumDyeColor.BLACK;
}
else if (i < 10)
{
return EnumDyeColor.GRAY;
}
else if (i < 15)
{
return EnumDyeColor.SILVER;
}
else if (i < 18)
{
return EnumDyeColor.BROWN;
}
else
{
return random.nextInt(500) == 0 ? EnumDyeColor.PINK : EnumDyeColor.WHITE;
}
}
public EntitySheep createChild(EntityAgeable ageable)
{
EntitySheep entitysheep = (EntitySheep)ageable;
EntitySheep entitysheep1 = new EntitySheep(this.world);
entitysheep1.setFleeceColor(this.getDyeColorMixFromParents(this, entitysheep));
return entitysheep1;
}
/**
* This function applies the benefits of growing back wool and faster growing up to the acting entity. (This
* function is used in the AIEatGrass)
*/
public void eatGrassBonus()
{
this.setSheared(false);
if (this.isChild())
{
this.addGrowth(60);
}
}
/**
* Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called
* when entity is reloaded from nbt. Mainly used for initializing attributes and inventory
*/
@Nullable
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata)
{
livingdata = super.onInitialSpawn(difficulty, livingdata);
this.setFleeceColor(getRandomSheepColor(this.world.rand));
return livingdata;
}
@Override public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos){ return !this.getSheared() && !this.isChild(); }
@Override
public java.util.List<ItemStack> onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune)
{
this.setSheared(true);
int i = 1 + this.rand.nextInt(3);
java.util.List<ItemStack> ret = new java.util.ArrayList<ItemStack>();
for (int j = 0; j < i; ++j)
ret.add(new ItemStack(Item.getItemFromBlock(Blocks.WOOL), 1, this.getFleeceColor().getMetadata()));
this.playSound(SoundEvents.ENTITY_SHEEP_SHEAR, 1.0F, 1.0F);
return ret;
}
/**
* Attempts to mix both parent sheep to come up with a mixed dye color.
*/
private EnumDyeColor getDyeColorMixFromParents(EntityAnimal father, EntityAnimal mother)
{
int i = ((EntitySheep)father).getFleeceColor().getDyeDamage();
int j = ((EntitySheep)mother).getFleeceColor().getDyeDamage();
this.inventoryCrafting.getStackInSlot(0).setItemDamage(i);
this.inventoryCrafting.getStackInSlot(1).setItemDamage(j);
ItemStack itemstack = CraftingManager.findMatchingResult(this.inventoryCrafting, ((EntitySheep)father).world);
int k;
if (itemstack.getItem() == Items.DYE)
{
k = itemstack.getMetadata();
}
else
{
k = this.world.rand.nextBoolean() ? i : j;
}
return EnumDyeColor.byDyeDamage(k);
}
public float getEyeHeight()
{
return 0.95F * this.height;
}
static
{
for (EnumDyeColor enumdyecolor : EnumDyeColor.values())
{
DYE_TO_RGB.put(enumdyecolor, createSheepColor(enumdyecolor));
}
DYE_TO_RGB.put(EnumDyeColor.WHITE, new float[] {0.9019608F, 0.9019608F, 0.9019608F});
}
}

View File

@@ -0,0 +1,46 @@
package net.minecraft.entity.passive;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
public abstract class EntityShoulderRiding extends EntityTameable
{
private int rideCooldownCounter;
public EntityShoulderRiding(World p_i47410_1_)
{
super(p_i47410_1_);
}
public boolean setEntityOnShoulder(EntityPlayer p_191994_1_)
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
nbttagcompound.setString("id", this.getEntityString());
this.writeToNBT(nbttagcompound);
if (p_191994_1_.addShoulderEntity(nbttagcompound))
{
this.world.removeEntity(this);
return true;
}
else
{
return false;
}
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
++this.rideCooldownCounter;
super.onUpdate();
}
public boolean canSitOnShoulder()
{
return this.rideCooldownCounter > 100;
}
}

View File

@@ -0,0 +1,186 @@
package net.minecraft.entity.passive;
import javax.annotation.Nullable;
import net.minecraft.entity.EnumCreatureAttribute;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAISkeletonRiders;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntitySkeletonHorse extends AbstractHorse
{
private final EntityAISkeletonRiders skeletonTrapAI = new EntityAISkeletonRiders(this);
private boolean skeletonTrap;
private int skeletonTrapTime;
public EntitySkeletonHorse(World worldIn)
{
super(worldIn);
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(15.0D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.20000000298023224D);
this.getEntityAttribute(JUMP_STRENGTH).setBaseValue(this.getModifiedJumpStrength());
}
protected SoundEvent getAmbientSound()
{
super.getAmbientSound();
return SoundEvents.ENTITY_SKELETON_HORSE_AMBIENT;
}
protected SoundEvent getDeathSound()
{
super.getDeathSound();
return SoundEvents.ENTITY_SKELETON_HORSE_DEATH;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
super.getHurtSound(damageSourceIn);
return SoundEvents.ENTITY_SKELETON_HORSE_HURT;
}
/**
* Get this Entity's EnumCreatureAttribute
*/
public EnumCreatureAttribute getCreatureAttribute()
{
return EnumCreatureAttribute.UNDEAD;
}
/**
* Returns the Y offset from the entity's position for any entity riding this one.
*/
public double getMountedYOffset()
{
return super.getMountedYOffset() - 0.1875D;
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_SKELETON_HORSE;
}
/**
* 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();
if (this.isTrap() && this.skeletonTrapTime++ >= 18000)
{
this.setDead();
}
}
public static void registerFixesSkeletonHorse(DataFixer fixer)
{
AbstractHorse.registerFixesAbstractHorse(fixer, EntitySkeletonHorse.class);
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setBoolean("SkeletonTrap", this.isTrap());
compound.setInteger("SkeletonTrapTime", this.skeletonTrapTime);
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.setTrap(compound.getBoolean("SkeletonTrap"));
this.skeletonTrapTime = compound.getInteger("SkeletonTrapTime");
}
public boolean isTrap()
{
return this.skeletonTrap;
}
public void setTrap(boolean trap)
{
if (trap != this.skeletonTrap)
{
this.skeletonTrap = trap;
if (trap)
{
this.tasks.addTask(1, this.skeletonTrapAI);
}
else
{
this.tasks.removeTask(this.skeletonTrapAI);
}
}
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
boolean flag = !itemstack.isEmpty();
if (flag && itemstack.getItem() == Items.SPAWN_EGG)
{
return super.processInteract(player, hand);
}
else if (!this.isTame())
{
return false;
}
else if (this.isChild())
{
return super.processInteract(player, hand);
}
else if (player.isSneaking())
{
this.openGUI(player);
return true;
}
else if (this.isBeingRidden())
{
return super.processInteract(player, hand);
}
else
{
if (flag)
{
if (itemstack.getItem() == Items.SADDLE && !this.isHorseSaddled())
{
this.openGUI(player);
return true;
}
if (itemstack.interactWithEntity(player, this, hand))
{
return true;
}
}
this.mountTo(player);
return true;
}
}
}

View File

@@ -0,0 +1,282 @@
package net.minecraft.entity.passive;
import javax.annotation.Nullable;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.MoverType;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class EntitySquid extends EntityWaterMob
{
public float squidPitch;
public float prevSquidPitch;
public float squidYaw;
public float prevSquidYaw;
/** appears to be rotation in radians; we already have pitch & yaw, so this completes the triumvirate. */
public float squidRotation;
/** previous squidRotation in radians */
public float prevSquidRotation;
/** angle of the tentacles in radians */
public float tentacleAngle;
/** the last calculated angle of the tentacles in radians */
public float lastTentacleAngle;
private float randomMotionSpeed;
/** change in squidRotation in radians. */
private float rotationVelocity;
private float rotateSpeed;
private float randomMotionVecX;
private float randomMotionVecY;
private float randomMotionVecZ;
public EntitySquid(World worldIn)
{
super(worldIn);
this.setSize(0.8F, 0.8F);
this.rand.setSeed((long)(1 + this.getEntityId()));
this.rotationVelocity = 1.0F / (this.rand.nextFloat() + 1.0F) * 0.2F;
}
public static void registerFixesSquid(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntitySquid.class);
}
protected void initEntityAI()
{
this.tasks.addTask(0, new EntitySquid.AIMoveRandom(this));
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D);
}
public float getEyeHeight()
{
return this.height * 0.5F;
}
protected SoundEvent getAmbientSound()
{
return SoundEvents.ENTITY_SQUID_AMBIENT;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_SQUID_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_SQUID_DEATH;
}
/**
* Returns the volume for the sounds this mob makes.
*/
protected float getSoundVolume()
{
return 0.4F;
}
/**
* 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;
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_SQUID;
}
/**
* 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();
this.prevSquidPitch = this.squidPitch;
this.prevSquidYaw = this.squidYaw;
this.prevSquidRotation = this.squidRotation;
this.lastTentacleAngle = this.tentacleAngle;
this.squidRotation += this.rotationVelocity;
if ((double)this.squidRotation > (Math.PI * 2D))
{
if (this.world.isRemote)
{
this.squidRotation = ((float)Math.PI * 2F);
}
else
{
this.squidRotation = (float)((double)this.squidRotation - (Math.PI * 2D));
if (this.rand.nextInt(10) == 0)
{
this.rotationVelocity = 1.0F / (this.rand.nextFloat() + 1.0F) * 0.2F;
}
this.world.setEntityState(this, (byte)19);
}
}
if (this.inWater)
{
if (this.squidRotation < (float)Math.PI)
{
float f = this.squidRotation / (float)Math.PI;
this.tentacleAngle = MathHelper.sin(f * f * (float)Math.PI) * (float)Math.PI * 0.25F;
if ((double)f > 0.75D)
{
this.randomMotionSpeed = 1.0F;
this.rotateSpeed = 1.0F;
}
else
{
this.rotateSpeed *= 0.8F;
}
}
else
{
this.tentacleAngle = 0.0F;
this.randomMotionSpeed *= 0.9F;
this.rotateSpeed *= 0.99F;
}
if (!this.world.isRemote)
{
this.motionX = (double)(this.randomMotionVecX * this.randomMotionSpeed);
this.motionY = (double)(this.randomMotionVecY * this.randomMotionSpeed);
this.motionZ = (double)(this.randomMotionVecZ * this.randomMotionSpeed);
}
float f1 = MathHelper.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
this.renderYawOffset += (-((float)MathHelper.atan2(this.motionX, this.motionZ)) * (180F / (float)Math.PI) - this.renderYawOffset) * 0.1F;
this.rotationYaw = this.renderYawOffset;
this.squidYaw = (float)((double)this.squidYaw + Math.PI * (double)this.rotateSpeed * 1.5D);
this.squidPitch += (-((float)MathHelper.atan2((double)f1, this.motionY)) * (180F / (float)Math.PI) - this.squidPitch) * 0.1F;
}
else
{
this.tentacleAngle = MathHelper.abs(MathHelper.sin(this.squidRotation)) * (float)Math.PI * 0.25F;
if (!this.world.isRemote)
{
this.motionX = 0.0D;
this.motionZ = 0.0D;
if (this.isPotionActive(MobEffects.LEVITATION))
{
this.motionY += 0.05D * (double)(this.getActivePotionEffect(MobEffects.LEVITATION).getAmplifier() + 1) - this.motionY;
}
else if (!this.hasNoGravity())
{
this.motionY -= 0.08D;
}
this.motionY *= 0.9800000190734863D;
}
this.squidPitch = (float)((double)this.squidPitch + (double)(-90.0F - this.squidPitch) * 0.02D);
}
}
public void travel(float strafe, float vertical, float forward)
{
this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ);
}
/**
* Checks if the entity's current position is a valid location to spawn this entity.
*/
public boolean getCanSpawnHere()
{
return this.posY > 45.0D && this.posY < (double)this.world.getSeaLevel() && super.getCanSpawnHere();
}
/**
* Handler for {@link World#setEntityState}
*/
@SideOnly(Side.CLIENT)
public void handleStatusUpdate(byte id)
{
if (id == 19)
{
this.squidRotation = 0.0F;
}
else
{
super.handleStatusUpdate(id);
}
}
public void setMovementVector(float randomMotionVecXIn, float randomMotionVecYIn, float randomMotionVecZIn)
{
this.randomMotionVecX = randomMotionVecXIn;
this.randomMotionVecY = randomMotionVecYIn;
this.randomMotionVecZ = randomMotionVecZIn;
}
public boolean hasMovementVector()
{
return this.randomMotionVecX != 0.0F || this.randomMotionVecY != 0.0F || this.randomMotionVecZ != 0.0F;
}
static class AIMoveRandom extends EntityAIBase
{
private final EntitySquid squid;
public AIMoveRandom(EntitySquid p_i45859_1_)
{
this.squid = p_i45859_1_;
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
return true;
}
/**
* Keep ticking a continuous task that has already been started
*/
public void updateTask()
{
int i = this.squid.getIdleTime();
if (i > 100)
{
this.squid.setMovementVector(0.0F, 0.0F, 0.0F);
}
else if (this.squid.getRNG().nextInt(50) == 0 || !this.squid.inWater || !this.squid.hasMovementVector())
{
float f = this.squid.getRNG().nextFloat() * ((float)Math.PI * 2F);
float f1 = MathHelper.cos(f) * 0.2F;
float f2 = -0.1F + this.squid.getRNG().nextFloat() * 0.2F;
float f3 = MathHelper.sin(f) * 0.2F;
this.squid.setMovementVector(f1, f2, f3);
}
}
}
}

View File

@@ -0,0 +1,296 @@
package net.minecraft.entity.passive;
import com.google.common.base.Optional;
import java.util.UUID;
import javax.annotation.Nullable;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IEntityOwnable;
import net.minecraft.entity.ai.EntityAISit;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.scoreboard.Team;
import net.minecraft.server.management.PreYggdrasilConverter;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public abstract class EntityTameable extends EntityAnimal implements IEntityOwnable
{
protected static final DataParameter<Byte> TAMED = EntityDataManager.<Byte>createKey(EntityTameable.class, DataSerializers.BYTE);
protected static final DataParameter<Optional<UUID>> OWNER_UNIQUE_ID = EntityDataManager.<Optional<UUID>>createKey(EntityTameable.class, DataSerializers.OPTIONAL_UNIQUE_ID);
protected EntityAISit aiSit;
public EntityTameable(World worldIn)
{
super(worldIn);
this.setupTamedAI();
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(TAMED, Byte.valueOf((byte)0));
this.dataManager.register(OWNER_UNIQUE_ID, Optional.absent());
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
if (this.getOwnerId() == null)
{
compound.setString("OwnerUUID", "");
}
else
{
compound.setString("OwnerUUID", this.getOwnerId().toString());
}
compound.setBoolean("Sitting", this.isSitting());
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
String s;
if (compound.hasKey("OwnerUUID", 8))
{
s = compound.getString("OwnerUUID");
}
else
{
String s1 = compound.getString("Owner");
s = PreYggdrasilConverter.convertMobOwnerIfNeeded(this.getServer(), s1);
}
if (!s.isEmpty())
{
try
{
this.setOwnerId(UUID.fromString(s));
this.setTamed(true);
}
catch (Throwable var4)
{
this.setTamed(false);
}
}
if (this.aiSit != null)
{
this.aiSit.setSitting(compound.getBoolean("Sitting"));
}
this.setSitting(compound.getBoolean("Sitting"));
}
public boolean canBeLeashedTo(EntityPlayer player)
{
return !this.getLeashed();
}
/**
* Play the taming effect, will either be hearts or smoke depending on status
*/
protected void playTameEffect(boolean play)
{
EnumParticleTypes enumparticletypes = EnumParticleTypes.HEART;
if (!play)
{
enumparticletypes = EnumParticleTypes.SMOKE_NORMAL;
}
for (int i = 0; i < 7; ++i)
{
double d0 = this.rand.nextGaussian() * 0.02D;
double d1 = this.rand.nextGaussian() * 0.02D;
double d2 = this.rand.nextGaussian() * 0.02D;
this.world.spawnParticle(enumparticletypes, this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + 0.5D + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, d0, d1, d2);
}
}
/**
* Handler for {@link World#setEntityState}
*/
@SideOnly(Side.CLIENT)
public void handleStatusUpdate(byte id)
{
if (id == 7)
{
this.playTameEffect(true);
}
else if (id == 6)
{
this.playTameEffect(false);
}
else
{
super.handleStatusUpdate(id);
}
}
public boolean isTamed()
{
return (((Byte)this.dataManager.get(TAMED)).byteValue() & 4) != 0;
}
public void setTamed(boolean tamed)
{
byte b0 = ((Byte)this.dataManager.get(TAMED)).byteValue();
if (tamed)
{
this.dataManager.set(TAMED, Byte.valueOf((byte)(b0 | 4)));
}
else
{
this.dataManager.set(TAMED, Byte.valueOf((byte)(b0 & -5)));
}
this.setupTamedAI();
}
protected void setupTamedAI()
{
}
public boolean isSitting()
{
return (((Byte)this.dataManager.get(TAMED)).byteValue() & 1) != 0;
}
public void setSitting(boolean sitting)
{
byte b0 = ((Byte)this.dataManager.get(TAMED)).byteValue();
if (sitting)
{
this.dataManager.set(TAMED, Byte.valueOf((byte)(b0 | 1)));
}
else
{
this.dataManager.set(TAMED, Byte.valueOf((byte)(b0 & -2)));
}
}
@Nullable
public UUID getOwnerId()
{
return (UUID)((Optional)this.dataManager.get(OWNER_UNIQUE_ID)).orNull();
}
public void setOwnerId(@Nullable UUID p_184754_1_)
{
this.dataManager.set(OWNER_UNIQUE_ID, Optional.fromNullable(p_184754_1_));
}
public void setTamedBy(EntityPlayer player)
{
this.setTamed(true);
this.setOwnerId(player.getUniqueID());
if (player instanceof EntityPlayerMP)
{
CriteriaTriggers.TAME_ANIMAL.trigger((EntityPlayerMP)player, this);
}
}
@Nullable
public EntityLivingBase getOwner()
{
try
{
UUID uuid = this.getOwnerId();
return uuid == null ? null : this.world.getPlayerEntityByUUID(uuid);
}
catch (IllegalArgumentException var2)
{
return null;
}
}
public boolean isOwner(EntityLivingBase entityIn)
{
return entityIn == this.getOwner();
}
/**
* Returns the AITask responsible of the sit logic
*/
public EntityAISit getAISit()
{
return this.aiSit;
}
public boolean shouldAttackEntity(EntityLivingBase target, EntityLivingBase owner)
{
return true;
}
public Team getTeam()
{
if (this.isTamed())
{
EntityLivingBase entitylivingbase = this.getOwner();
if (entitylivingbase != null)
{
return entitylivingbase.getTeam();
}
}
return super.getTeam();
}
/**
* Returns whether this Entity is on the same team as the given Entity.
*/
public boolean isOnSameTeam(Entity entityIn)
{
if (this.isTamed())
{
EntityLivingBase entitylivingbase = this.getOwner();
if (entityIn == entitylivingbase)
{
return true;
}
if (entitylivingbase != null)
{
return entitylivingbase.isOnSameTeam(entityIn);
}
}
return super.isOnSameTeam(entityIn);
}
/**
* Called when the mob's health reaches 0.
*/
public void onDeath(DamageSource cause)
{
if (!this.world.isRemote && this.world.getGameRules().getBoolean("showDeathMessages") && this.getOwner() instanceof EntityPlayerMP)
{
this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage());
}
super.onDeath(cause);
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,89 @@
package net.minecraft.entity.passive;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
public abstract class EntityWaterMob extends EntityLiving implements IAnimals
{
public EntityWaterMob(World worldIn)
{
super(worldIn);
}
public boolean canBreatheUnderwater()
{
return true;
}
/**
* Checks if the entity's current position is a valid location to spawn this entity.
*/
public boolean getCanSpawnHere()
{
return true;
}
/**
* Checks that the entity is not colliding with any blocks / liquids
*/
public boolean isNotColliding()
{
return this.world.checkNoEntityCollision(this.getEntityBoundingBox(), this);
}
/**
* Get number of ticks, at least during which the living entity will be silent.
*/
public int getTalkInterval()
{
return 120;
}
/**
* Determines if an entity can be despawned, used on idle far away entities
*/
protected boolean canDespawn()
{
return true;
}
/**
* Get the experience points the entity currently has.
*/
protected int getExperiencePoints(EntityPlayer player)
{
return 1 + this.world.rand.nextInt(3);
}
/**
* Gets called every tick from main Entity class
*/
public void onEntityUpdate()
{
int i = this.getAir();
super.onEntityUpdate();
if (this.isEntityAlive() && !this.isInWater())
{
--i;
this.setAir(i);
if (this.getAir() == -20)
{
this.setAir(0);
this.attackEntityFrom(DamageSource.DROWN, 2.0F);
}
}
else
{
this.setAir(300);
}
}
public boolean isPushedByWater()
{
return false;
}
}

View File

@@ -0,0 +1,721 @@
package net.minecraft.entity.passive;
import com.google.common.base.Predicate;
import java.util.UUID;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIAttackMelee;
import net.minecraft.entity.ai.EntityAIAvoidEntity;
import net.minecraft.entity.ai.EntityAIBeg;
import net.minecraft.entity.ai.EntityAIFollowOwner;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAILeapAtTarget;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAIOwnerHurtByTarget;
import net.minecraft.entity.ai.EntityAIOwnerHurtTarget;
import net.minecraft.entity.ai.EntityAISit;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITargetNonTamed;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.monster.AbstractSkeleton;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.monster.EntityGhast;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class EntityWolf extends EntityTameable
{
private static final DataParameter<Float> DATA_HEALTH_ID = EntityDataManager.<Float>createKey(EntityWolf.class, DataSerializers.FLOAT);
private static final DataParameter<Boolean> BEGGING = EntityDataManager.<Boolean>createKey(EntityWolf.class, DataSerializers.BOOLEAN);
private static final DataParameter<Integer> COLLAR_COLOR = EntityDataManager.<Integer>createKey(EntityWolf.class, DataSerializers.VARINT);
/** Float used to smooth the rotation of the wolf head */
private float headRotationCourse;
private float headRotationCourseOld;
/** true is the wolf is wet else false */
private boolean isWet;
/** True if the wolf is shaking else False */
private boolean isShaking;
/** This time increases while wolf is shaking and emitting water particles. */
private float timeWolfIsShaking;
private float prevTimeWolfIsShaking;
public EntityWolf(World worldIn)
{
super(worldIn);
this.setSize(0.6F, 0.85F);
this.setTamed(false);
}
protected void initEntityAI()
{
this.aiSit = new EntityAISit(this);
this.tasks.addTask(1, new EntityAISwimming(this));
this.tasks.addTask(2, this.aiSit);
this.tasks.addTask(3, new EntityWolf.AIAvoidEntity(this, EntityLlama.class, 24.0F, 1.5D, 1.5D));
this.tasks.addTask(4, new EntityAILeapAtTarget(this, 0.4F));
this.tasks.addTask(5, new EntityAIAttackMelee(this, 1.0D, true));
this.tasks.addTask(6, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F));
this.tasks.addTask(7, new EntityAIMate(this, 1.0D));
this.tasks.addTask(8, new EntityAIWanderAvoidWater(this, 1.0D));
this.tasks.addTask(9, new EntityAIBeg(this, 8.0F));
this.tasks.addTask(10, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.tasks.addTask(10, new EntityAILookIdle(this));
this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this));
this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this));
this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true, new Class[0]));
this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntityAnimal.class, false, new Predicate<Entity>()
{
public boolean apply(@Nullable Entity p_apply_1_)
{
return p_apply_1_ instanceof EntitySheep || p_apply_1_ instanceof EntityRabbit;
}
}));
this.targetTasks.addTask(5, new EntityAINearestAttackableTarget(this, AbstractSkeleton.class, false));
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.30000001192092896D);
if (this.isTamed())
{
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D);
}
else
{
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(8.0D);
}
this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(2.0D);
}
/**
* Sets the active target the Task system uses for tracking
*/
public void setAttackTarget(@Nullable EntityLivingBase entitylivingbaseIn)
{
super.setAttackTarget(entitylivingbaseIn);
if (entitylivingbaseIn == null)
{
this.setAngry(false);
}
else if (!this.isTamed())
{
this.setAngry(true);
}
}
protected void updateAITasks()
{
this.dataManager.set(DATA_HEALTH_ID, Float.valueOf(this.getHealth()));
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(DATA_HEALTH_ID, Float.valueOf(this.getHealth()));
this.dataManager.register(BEGGING, Boolean.valueOf(false));
this.dataManager.register(COLLAR_COLOR, Integer.valueOf(EnumDyeColor.RED.getDyeDamage()));
}
protected void playStepSound(BlockPos pos, Block blockIn)
{
this.playSound(SoundEvents.ENTITY_WOLF_STEP, 0.15F, 1.0F);
}
public static void registerFixesWolf(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntityWolf.class);
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound compound)
{
super.writeEntityToNBT(compound);
compound.setBoolean("Angry", this.isAngry());
compound.setByte("CollarColor", (byte)this.getCollarColor().getDyeDamage());
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
this.setAngry(compound.getBoolean("Angry"));
if (compound.hasKey("CollarColor", 99))
{
this.setCollarColor(EnumDyeColor.byDyeDamage(compound.getByte("CollarColor")));
}
}
protected SoundEvent getAmbientSound()
{
if (this.isAngry())
{
return SoundEvents.ENTITY_WOLF_GROWL;
}
else if (this.rand.nextInt(3) == 0)
{
return this.isTamed() && ((Float)this.dataManager.get(DATA_HEALTH_ID)).floatValue() < 10.0F ? SoundEvents.ENTITY_WOLF_WHINE : SoundEvents.ENTITY_WOLF_PANT;
}
else
{
return SoundEvents.ENTITY_WOLF_AMBIENT;
}
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_WOLF_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_WOLF_DEATH;
}
/**
* Returns the volume for the sounds this mob makes.
*/
protected float getSoundVolume()
{
return 0.4F;
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_WOLF;
}
/**
* 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();
if (!this.world.isRemote && this.isWet && !this.isShaking && !this.hasPath() && this.onGround)
{
this.isShaking = true;
this.timeWolfIsShaking = 0.0F;
this.prevTimeWolfIsShaking = 0.0F;
this.world.setEntityState(this, (byte)8);
}
if (!this.world.isRemote && this.getAttackTarget() == null && this.isAngry())
{
this.setAngry(false);
}
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
super.onUpdate();
this.headRotationCourseOld = this.headRotationCourse;
if (this.isBegging())
{
this.headRotationCourse += (1.0F - this.headRotationCourse) * 0.4F;
}
else
{
this.headRotationCourse += (0.0F - this.headRotationCourse) * 0.4F;
}
if (this.isWet())
{
this.isWet = true;
this.isShaking = false;
this.timeWolfIsShaking = 0.0F;
this.prevTimeWolfIsShaking = 0.0F;
}
else if ((this.isWet || this.isShaking) && this.isShaking)
{
if (this.timeWolfIsShaking == 0.0F)
{
this.playSound(SoundEvents.ENTITY_WOLF_SHAKE, this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
}
this.prevTimeWolfIsShaking = this.timeWolfIsShaking;
this.timeWolfIsShaking += 0.05F;
if (this.prevTimeWolfIsShaking >= 2.0F)
{
this.isWet = false;
this.isShaking = false;
this.prevTimeWolfIsShaking = 0.0F;
this.timeWolfIsShaking = 0.0F;
}
if (this.timeWolfIsShaking > 0.4F)
{
float f = (float)this.getEntityBoundingBox().minY;
int i = (int)(MathHelper.sin((this.timeWolfIsShaking - 0.4F) * (float)Math.PI) * 7.0F);
for (int j = 0; j < i; ++j)
{
float f1 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;
float f2 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;
this.world.spawnParticle(EnumParticleTypes.WATER_SPLASH, this.posX + (double)f1, (double)(f + 0.8F), this.posZ + (double)f2, this.motionX, this.motionY, this.motionZ);
}
}
}
}
/**
* True if the wolf is wet
*/
@SideOnly(Side.CLIENT)
public boolean isWolfWet()
{
return this.isWet;
}
/**
* Used when calculating the amount of shading to apply while the wolf is wet.
*/
@SideOnly(Side.CLIENT)
public float getShadingWhileWet(float p_70915_1_)
{
return 0.75F + (this.prevTimeWolfIsShaking + (this.timeWolfIsShaking - this.prevTimeWolfIsShaking) * p_70915_1_) / 2.0F * 0.25F;
}
@SideOnly(Side.CLIENT)
public float getShakeAngle(float p_70923_1_, float p_70923_2_)
{
float f = (this.prevTimeWolfIsShaking + (this.timeWolfIsShaking - this.prevTimeWolfIsShaking) * p_70923_1_ + p_70923_2_) / 1.8F;
if (f < 0.0F)
{
f = 0.0F;
}
else if (f > 1.0F)
{
f = 1.0F;
}
return MathHelper.sin(f * (float)Math.PI) * MathHelper.sin(f * (float)Math.PI * 11.0F) * 0.15F * (float)Math.PI;
}
@SideOnly(Side.CLIENT)
public float getInterestedAngle(float p_70917_1_)
{
return (this.headRotationCourseOld + (this.headRotationCourse - this.headRotationCourseOld) * p_70917_1_) * 0.15F * (float)Math.PI;
}
public float getEyeHeight()
{
return this.height * 0.8F;
}
/**
* The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
* use in wolves.
*/
public int getVerticalFaceSpeed()
{
return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource source, float amount)
{
if (this.isEntityInvulnerable(source))
{
return false;
}
else
{
Entity entity = source.getTrueSource();
if (this.aiSit != null)
{
this.aiSit.setSitting(false);
}
if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
{
amount = (amount + 1.0F) / 2.0F;
}
return super.attackEntityFrom(source, amount);
}
}
public boolean attackEntityAsMob(Entity entityIn)
{
boolean flag = entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), (float)((int)this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).getAttributeValue()));
if (flag)
{
this.applyEnchantments(this, entityIn);
}
return flag;
}
public void setTamed(boolean tamed)
{
super.setTamed(tamed);
if (tamed)
{
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D);
}
else
{
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(8.0D);
}
this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(4.0D);
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
if (this.isTamed())
{
if (!itemstack.isEmpty())
{
if (itemstack.getItem() instanceof ItemFood)
{
ItemFood itemfood = (ItemFood)itemstack.getItem();
if (itemfood.isWolfsFavoriteMeat() && ((Float)this.dataManager.get(DATA_HEALTH_ID)).floatValue() < 20.0F)
{
if (!player.capabilities.isCreativeMode)
{
itemstack.shrink(1);
}
this.heal((float)itemfood.getHealAmount(itemstack));
return true;
}
}
else if (itemstack.getItem() == Items.DYE)
{
EnumDyeColor enumdyecolor = EnumDyeColor.byDyeDamage(itemstack.getMetadata());
if (enumdyecolor != this.getCollarColor())
{
this.setCollarColor(enumdyecolor);
if (!player.capabilities.isCreativeMode)
{
itemstack.shrink(1);
}
return true;
}
}
}
if (this.isOwner(player) && !this.world.isRemote && !this.isBreedingItem(itemstack))
{
this.aiSit.setSitting(!this.isSitting());
this.isJumping = false;
this.navigator.clearPath();
this.setAttackTarget((EntityLivingBase)null);
}
}
else if (itemstack.getItem() == Items.BONE && !this.isAngry())
{
if (!player.capabilities.isCreativeMode)
{
itemstack.shrink(1);
}
if (!this.world.isRemote)
{
if (this.rand.nextInt(3) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, player))
{
this.setTamedBy(player);
this.navigator.clearPath();
this.setAttackTarget((EntityLivingBase)null);
this.aiSit.setSitting(true);
this.setHealth(20.0F);
this.playTameEffect(true);
this.world.setEntityState(this, (byte)7);
}
else
{
this.playTameEffect(false);
this.world.setEntityState(this, (byte)6);
}
}
return true;
}
return super.processInteract(player, hand);
}
/**
* Handler for {@link World#setEntityState}
*/
@SideOnly(Side.CLIENT)
public void handleStatusUpdate(byte id)
{
if (id == 8)
{
this.isShaking = true;
this.timeWolfIsShaking = 0.0F;
this.prevTimeWolfIsShaking = 0.0F;
}
else
{
super.handleStatusUpdate(id);
}
}
@SideOnly(Side.CLIENT)
public float getTailRotation()
{
if (this.isAngry())
{
return 1.5393804F;
}
else
{
return this.isTamed() ? (0.55F - (this.getMaxHealth() - ((Float)this.dataManager.get(DATA_HEALTH_ID)).floatValue()) * 0.02F) * (float)Math.PI : ((float)Math.PI / 5F);
}
}
/**
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
* the animal type)
*/
public boolean isBreedingItem(ItemStack stack)
{
return stack.getItem() instanceof ItemFood && ((ItemFood)stack.getItem()).isWolfsFavoriteMeat();
}
/**
* Will return how many at most can spawn in a chunk at once.
*/
public int getMaxSpawnedInChunk()
{
return 8;
}
/**
* Determines whether this wolf is angry or not.
*/
public boolean isAngry()
{
return (((Byte)this.dataManager.get(TAMED)).byteValue() & 2) != 0;
}
/**
* Sets whether this wolf is angry or not.
*/
public void setAngry(boolean angry)
{
byte b0 = ((Byte)this.dataManager.get(TAMED)).byteValue();
if (angry)
{
this.dataManager.set(TAMED, Byte.valueOf((byte)(b0 | 2)));
}
else
{
this.dataManager.set(TAMED, Byte.valueOf((byte)(b0 & -3)));
}
}
public EnumDyeColor getCollarColor()
{
return EnumDyeColor.byDyeDamage(((Integer)this.dataManager.get(COLLAR_COLOR)).intValue() & 15);
}
public void setCollarColor(EnumDyeColor collarcolor)
{
this.dataManager.set(COLLAR_COLOR, Integer.valueOf(collarcolor.getDyeDamage()));
}
public EntityWolf createChild(EntityAgeable ageable)
{
EntityWolf entitywolf = new EntityWolf(this.world);
UUID uuid = this.getOwnerId();
if (uuid != null)
{
entitywolf.setOwnerId(uuid);
entitywolf.setTamed(true);
}
return entitywolf;
}
public void setBegging(boolean beg)
{
this.dataManager.set(BEGGING, Boolean.valueOf(beg));
}
/**
* Returns true if the mob is currently able to mate with the specified mob.
*/
public boolean canMateWith(EntityAnimal otherAnimal)
{
if (otherAnimal == this)
{
return false;
}
else if (!this.isTamed())
{
return false;
}
else if (!(otherAnimal instanceof EntityWolf))
{
return false;
}
else
{
EntityWolf entitywolf = (EntityWolf)otherAnimal;
if (!entitywolf.isTamed())
{
return false;
}
else if (entitywolf.isSitting())
{
return false;
}
else
{
return this.isInLove() && entitywolf.isInLove();
}
}
}
public boolean isBegging()
{
return ((Boolean)this.dataManager.get(BEGGING)).booleanValue();
}
public boolean shouldAttackEntity(EntityLivingBase target, EntityLivingBase owner)
{
if (!(target instanceof EntityCreeper) && !(target instanceof EntityGhast))
{
if (target instanceof EntityWolf)
{
EntityWolf entitywolf = (EntityWolf)target;
if (entitywolf.isTamed() && entitywolf.getOwner() == owner)
{
return false;
}
}
if (target instanceof EntityPlayer && owner instanceof EntityPlayer && !((EntityPlayer)owner).canAttackPlayer((EntityPlayer)target))
{
return false;
}
else
{
return !(target instanceof AbstractHorse) || !((AbstractHorse)target).isTame();
}
}
else
{
return false;
}
}
public boolean canBeLeashedTo(EntityPlayer player)
{
return !this.isAngry() && super.canBeLeashedTo(player);
}
class AIAvoidEntity<T extends Entity> extends EntityAIAvoidEntity<T>
{
private final EntityWolf wolf;
public AIAvoidEntity(EntityWolf wolfIn, Class<T> p_i47251_3_, float p_i47251_4_, double p_i47251_5_, double p_i47251_7_)
{
super(wolfIn, p_i47251_3_, p_i47251_4_, p_i47251_5_, p_i47251_7_);
this.wolf = wolfIn;
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (super.shouldExecute() && this.closestLivingEntity instanceof EntityLlama)
{
return !this.wolf.isTamed() && this.avoidLlama((EntityLlama)this.closestLivingEntity);
}
else
{
return false;
}
}
private boolean avoidLlama(EntityLlama p_190854_1_)
{
return p_190854_1_.getStrength() >= EntityWolf.this.rand.nextInt(5);
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
EntityWolf.this.setAttackTarget((EntityLivingBase)null);
super.startExecuting();
}
/**
* Keep ticking a continuous task that has already been started
*/
public void updateTask()
{
EntityWolf.this.setAttackTarget((EntityLivingBase)null);
super.updateTask();
}
}
}

View File

@@ -0,0 +1,116 @@
package net.minecraft.entity.passive;
import javax.annotation.Nullable;
import net.minecraft.entity.EnumCreatureAttribute;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntityZombieHorse extends AbstractHorse
{
public EntityZombieHorse(World worldIn)
{
super(worldIn);
}
public static void registerFixesZombieHorse(DataFixer fixer)
{
AbstractHorse.registerFixesAbstractHorse(fixer, EntityZombieHorse.class);
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(15.0D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.20000000298023224D);
this.getEntityAttribute(JUMP_STRENGTH).setBaseValue(this.getModifiedJumpStrength());
}
/**
* Get this Entity's EnumCreatureAttribute
*/
public EnumCreatureAttribute getCreatureAttribute()
{
return EnumCreatureAttribute.UNDEAD;
}
protected SoundEvent getAmbientSound()
{
super.getAmbientSound();
return SoundEvents.ENTITY_ZOMBIE_HORSE_AMBIENT;
}
protected SoundEvent getDeathSound()
{
super.getDeathSound();
return SoundEvents.ENTITY_ZOMBIE_HORSE_DEATH;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
super.getHurtSound(damageSourceIn);
return SoundEvents.ENTITY_ZOMBIE_HORSE_HURT;
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_ZOMBIE_HORSE;
}
public boolean processInteract(EntityPlayer player, EnumHand hand)
{
ItemStack itemstack = player.getHeldItem(hand);
boolean flag = !itemstack.isEmpty();
if (flag && itemstack.getItem() == Items.SPAWN_EGG)
{
return super.processInteract(player, hand);
}
else if (!this.isTame())
{
return false;
}
else if (this.isChild())
{
return super.processInteract(player, hand);
}
else if (player.isSneaking())
{
this.openGUI(player);
return true;
}
else if (this.isBeingRidden())
{
return super.processInteract(player, hand);
}
else
{
if (flag)
{
if (!this.isHorseSaddled() && itemstack.getItem() == Items.SADDLE)
{
this.openGUI(player);
return true;
}
if (itemstack.interactWithEntity(player, this, hand))
{
return true;
}
}
this.mountTo(player);
return true;
}
}
}

View File

@@ -0,0 +1,112 @@
package net.minecraft.entity.passive;
import javax.annotation.Nullable;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public enum HorseArmorType
{
NONE(0),
IRON(5, "iron", "meo"),
GOLD(7, "gold", "goo"),
DIAMOND(11, "diamond", "dio");
private final String textureName;
private final String hash;
private final int protection;
private HorseArmorType(int armorStrengthIn)
{
this.protection = armorStrengthIn;
this.textureName = null;
this.hash = "";
}
private HorseArmorType(int armorStrengthIn, String p_i46800_4_, String p_i46800_5_)
{
this.protection = armorStrengthIn;
this.textureName = "textures/entity/horse/armor/horse_armor_" + p_i46800_4_ + ".png";
this.hash = p_i46800_5_;
}
public int getOrdinal()
{
return this.ordinal();
}
@SideOnly(Side.CLIENT)
public String getHash()
{
return this.hash;
}
public int getProtection()
{
return this.protection;
}
@Nullable
@SideOnly(Side.CLIENT)
public String getTextureName()
{
return this.textureName;
}
@Deprecated /**Forge: Use getByName. Ordinals of mod-added enum constants are dependent on load order, unlike names.**/
public static HorseArmorType getByOrdinal(int ordinal)
{
return values()[ordinal];
}
public static HorseArmorType getByItemStack(ItemStack stack)
{
return stack.getItem().getHorseArmorType(stack);
}
@Deprecated //Forge: Use getByItemStack
public static HorseArmorType getByItem(Item itemIn)
{
if (itemIn == Items.IRON_HORSE_ARMOR)
{
return IRON;
}
else if (itemIn == Items.GOLDEN_HORSE_ARMOR)
{
return GOLD;
}
else
{
return itemIn == Items.DIAMOND_HORSE_ARMOR ? DIAMOND : NONE;
}
}
@Deprecated //Forge: Use ItemStack sensitive overload
public static boolean isHorseArmor(Item itemIn)
{
return getByItem(itemIn) != NONE;
}
/* ======================================== FORGE START ======================================== */
//Allows for textures located outside the vanilla horse armor folder
private HorseArmorType(String defaultTextureLocation, int armorStrengthIn)
{
this.protection = armorStrengthIn;
this.textureName = defaultTextureLocation;
this.hash = "forge";
}
public static HorseArmorType getByName(String name)
{
HorseArmorType type = HorseArmorType.valueOf(name);
return type != null ? type : NONE;
}
public static boolean isHorseArmor(ItemStack stack)
{
return getByItemStack(stack) != NONE;
}
/* ======================================== FORGE END ======================================== */
}

View File

@@ -0,0 +1,5 @@
package net.minecraft.entity.passive;
public interface IAnimals
{
}

View File

@@ -0,0 +1,7 @@
// Auto generated package-info by MCP
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package net.minecraft.entity.passive;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;