Files
Mohammad-Ali Minaie b86dedad2f base mod created
2018-10-08 09:07:47 -04:00

3761 lines
118 KiB
Java

package net.minecraft.entity;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nullable;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFence;
import net.minecraft.block.BlockFenceGate;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.BlockWall;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.EnumPushReaction;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.state.pattern.BlockPattern;
import net.minecraft.command.CommandResultStats;
import net.minecraft.command.ICommandSender;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.crash.ICrashReportDetail;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentProtection;
import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraft.entity.item.EntityBoat;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
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.nbt.NBTTagDouble;
import net.minecraft.nbt.NBTTagFloat;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.scoreboard.ScorePlayerTeam;
import net.minecraft.scoreboard.Team;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.Mirror;
import net.minecraft.util.ReportedException;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.IDataFixer;
import net.minecraft.util.datafix.IDataWalker;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec2f;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.event.HoverEvent;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.world.Explosion;
import net.minecraft.world.Teleporter;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public abstract class Entity implements ICommandSender, net.minecraftforge.common.capabilities.ICapabilitySerializable<NBTTagCompound>
{
private static final Logger LOGGER = LogManager.getLogger();
private static final List<ItemStack> EMPTY_EQUIPMENT = Collections.<ItemStack>emptyList();
private static final AxisAlignedBB ZERO_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
private static double renderDistanceWeight = 1.0D;
private static int nextEntityID;
private int entityId;
/**
* Blocks entities from spawning when they do their AABB check to make sure the spot is clear of entities that can
* prevent spawning.
*/
public boolean preventEntitySpawning;
/** List of entities that are riding this entity */
private final List<Entity> riddenByEntities;
protected int rideCooldown;
private Entity ridingEntity;
public boolean forceSpawn;
/** Reference to the World object. */
public World world;
public double prevPosX;
public double prevPosY;
public double prevPosZ;
/** X position of this entity, located at the center of its bounding box. */
public double posX;
/** Y position of this entity, located at the bottom of its bounding box (its feet) */
public double posY;
/** Z position of this entity, located at the center of its bounding box. */
public double posZ;
/** Entity motion X */
public double motionX;
/** Entity motion Y */
public double motionY;
/** Entity motion Z */
public double motionZ;
/** Entity rotation Yaw */
public float rotationYaw;
/** Entity rotation Pitch */
public float rotationPitch;
public float prevRotationYaw;
public float prevRotationPitch;
/** Axis aligned bounding box. */
private AxisAlignedBB boundingBox;
public boolean onGround;
/** True if after a move this entity has collided with something on X- or Z-axis */
public boolean collidedHorizontally;
/** True if after a move this entity has collided with something on Y-axis */
public boolean collidedVertically;
/** True if after a move this entity has collided with something either vertically or horizontally */
public boolean collided;
/** If true, an {@link SPacketEntityVelocity} will be sent updating this entity's velocity. */
public boolean velocityChanged;
protected boolean isInWeb;
private boolean isOutsideBorder;
/** gets set by setEntityDead, so this must be the flag whether an Entity is dead (inactive may be better term) */
public boolean isDead;
/** How wide this entity is considered to be */
public float width;
/** How high this entity is considered to be */
public float height;
/** The previous ticks distance walked multiplied by 0.6 */
public float prevDistanceWalkedModified;
/** The distance walked multiplied by 0.6 */
public float distanceWalkedModified;
public float distanceWalkedOnStepModified;
public float fallDistance;
/** The distance that has to be exceeded in order to triger a new step sound and an onEntityWalking event on a block */
private int nextStepDistance;
private float nextFlap;
/** The entity's X coordinate at the previous tick, used to calculate position during rendering routines */
public double lastTickPosX;
/** The entity's Y coordinate at the previous tick, used to calculate position during rendering routines */
public double lastTickPosY;
/** The entity's Z coordinate at the previous tick, used to calculate position during rendering routines */
public double lastTickPosZ;
/**
* How high this entity can step up when running into a block to try to get over it (currently make note the entity
* will always step up this amount and not just the amount needed)
*/
public float stepHeight;
/** Whether this entity won't clip with collision or not (make note it won't disable gravity) */
public boolean noClip;
/** Reduces the velocity applied by entity collisions by the specified percent. */
public float entityCollisionReduction;
protected Random rand;
/** How many ticks has this entity had ran since being alive */
public int ticksExisted;
private int fire;
/** Whether this entity is currently inside of water (if it handles water movement that is) */
protected boolean inWater;
/** Remaining time an entity will be "immune" to further damage after being hurt. */
public int hurtResistantTime;
protected boolean firstUpdate;
protected boolean isImmuneToFire;
protected EntityDataManager dataManager;
protected static final DataParameter<Byte> FLAGS = EntityDataManager.<Byte>createKey(Entity.class, DataSerializers.BYTE);
private static final DataParameter<Integer> AIR = EntityDataManager.<Integer>createKey(Entity.class, DataSerializers.VARINT);
private static final DataParameter<String> CUSTOM_NAME = EntityDataManager.<String>createKey(Entity.class, DataSerializers.STRING);
private static final DataParameter<Boolean> CUSTOM_NAME_VISIBLE = EntityDataManager.<Boolean>createKey(Entity.class, DataSerializers.BOOLEAN);
private static final DataParameter<Boolean> SILENT = EntityDataManager.<Boolean>createKey(Entity.class, DataSerializers.BOOLEAN);
private static final DataParameter<Boolean> NO_GRAVITY = EntityDataManager.<Boolean>createKey(Entity.class, DataSerializers.BOOLEAN);
/** Has this entity been added to the chunk its within */
public boolean addedToChunk;
public int chunkCoordX;
public int chunkCoordY;
public int chunkCoordZ;
@SideOnly(Side.CLIENT)
public long serverPosX;
@SideOnly(Side.CLIENT)
public long serverPosY;
@SideOnly(Side.CLIENT)
public long serverPosZ;
/**
* Render entity even if it is outside the camera frustum. Only true in EntityFish for now. Used in RenderGlobal:
* render if ignoreFrustumCheck or in frustum.
*/
public boolean ignoreFrustumCheck;
public boolean isAirBorne;
public int timeUntilPortal;
/** Whether the entity is inside a Portal */
protected boolean inPortal;
protected int portalCounter;
/** Which dimension the player is in (-1 = the Nether, 0 = normal world) */
public int dimension;
/** The position of the last portal the entity was in */
protected BlockPos lastPortalPos;
/** A horizontal vector related to the position of the last portal the entity was in */
protected Vec3d lastPortalVec;
/** A direction related to the position of the last portal the entity was in */
protected EnumFacing teleportDirection;
private boolean invulnerable;
protected UUID entityUniqueID;
protected String cachedUniqueIdString;
/** The command result statistics for this Entity. */
private final CommandResultStats cmdResultStats;
protected boolean glowing;
private final Set<String> tags;
private boolean isPositionDirty;
private final double[] pistonDeltas;
private long pistonDeltasGameTime;
/**
* Setting this to true will prevent the world from calling {@link #onUpdate()} for this entity.
*/
public boolean updateBlocked;
public Entity(World worldIn)
{
this.entityId = nextEntityID++;
this.riddenByEntities = Lists.<Entity>newArrayList();
this.boundingBox = ZERO_AABB;
this.width = 0.6F;
this.height = 1.8F;
this.nextStepDistance = 1;
this.nextFlap = 1.0F;
this.rand = new Random();
this.fire = -this.getFireImmuneTicks();
this.firstUpdate = true;
this.entityUniqueID = MathHelper.getRandomUUID(this.rand);
this.cachedUniqueIdString = this.entityUniqueID.toString();
this.cmdResultStats = new CommandResultStats();
this.tags = Sets.<String>newHashSet();
this.pistonDeltas = new double[] {0.0D, 0.0D, 0.0D};
this.world = worldIn;
this.setPosition(0.0D, 0.0D, 0.0D);
if (worldIn != null)
{
this.dimension = worldIn.provider.getDimension();
}
this.dataManager = new EntityDataManager(this);
this.dataManager.register(FLAGS, Byte.valueOf((byte)0));
this.dataManager.register(AIR, Integer.valueOf(300));
this.dataManager.register(CUSTOM_NAME_VISIBLE, Boolean.valueOf(false));
this.dataManager.register(CUSTOM_NAME, "");
this.dataManager.register(SILENT, Boolean.valueOf(false));
this.dataManager.register(NO_GRAVITY, Boolean.valueOf(false));
this.entityInit();
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityEvent.EntityConstructing(this));
capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this);
}
/** Forge: Used to store custom data for each entity. */
private NBTTagCompound customEntityData;
public boolean captureDrops = false;
public java.util.ArrayList<EntityItem> capturedDrops = new java.util.ArrayList<EntityItem>();
private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities;
public int getEntityId()
{
return this.entityId;
}
public void setEntityId(int id)
{
this.entityId = id;
}
public Set<String> getTags()
{
return this.tags;
}
public boolean addTag(String tag)
{
if (this.tags.size() >= 1024)
{
return false;
}
else
{
this.tags.add(tag);
return true;
}
}
public boolean removeTag(String tag)
{
return this.tags.remove(tag);
}
/**
* Called by the /kill command.
*/
public void onKillCommand()
{
this.setDead();
}
protected abstract void entityInit();
public EntityDataManager getDataManager()
{
return this.dataManager;
}
public boolean equals(Object p_equals_1_)
{
if (p_equals_1_ instanceof Entity)
{
return ((Entity)p_equals_1_).entityId == this.entityId;
}
else
{
return false;
}
}
public int hashCode()
{
return this.entityId;
}
/**
* Keeps moving the entity up so it isn't colliding with blocks and other requirements for this entity to be spawned
* (only actually used on players though its also on Entity)
*/
@SideOnly(Side.CLIENT)
protected void preparePlayerToSpawn()
{
if (this.world != null)
{
while (this.posY > 0.0D && this.posY < 256.0D)
{
this.setPosition(this.posX, this.posY, this.posZ);
if (this.world.getCollisionBoxes(this, this.getEntityBoundingBox()).isEmpty())
{
break;
}
++this.posY;
}
this.motionX = 0.0D;
this.motionY = 0.0D;
this.motionZ = 0.0D;
this.rotationPitch = 0.0F;
}
}
/**
* Will get destroyed next tick.
*/
public void setDead()
{
this.isDead = true;
}
/**
* Sets whether this entity should drop its items when setDead() is called. This applies to container minecarts.
*/
public void setDropItemsWhenDead(boolean dropWhenDead)
{
}
/**
* Sets the width and height of the entity.
*/
protected void setSize(float width, float height)
{
if (width != this.width || height != this.height)
{
float f = this.width;
this.width = width;
this.height = height;
if (this.width < f)
{
double d0 = (double)width / 2.0D;
this.setEntityBoundingBox(new AxisAlignedBB(this.posX - d0, this.posY, this.posZ - d0, this.posX + d0, this.posY + (double)this.height, this.posZ + d0));
return;
}
AxisAlignedBB axisalignedbb = this.getEntityBoundingBox();
this.setEntityBoundingBox(new AxisAlignedBB(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ, axisalignedbb.minX + (double)this.width, axisalignedbb.minY + (double)this.height, axisalignedbb.minZ + (double)this.width));
if (this.width > f && !this.firstUpdate && !this.world.isRemote)
{
this.move(MoverType.SELF, (double)(f - this.width), 0.0D, (double)(f - this.width));
}
}
}
/**
* Sets the rotation of the entity.
*/
protected void setRotation(float yaw, float pitch)
{
this.rotationYaw = yaw % 360.0F;
this.rotationPitch = pitch % 360.0F;
}
/**
* Sets the x,y,z of the entity from the given parameters. Also seems to set up a bounding box.
*/
public void setPosition(double x, double y, double z)
{
this.posX = x;
this.posY = y;
this.posZ = z;
float f = this.width / 2.0F;
float f1 = this.height;
this.setEntityBoundingBox(new AxisAlignedBB(x - (double)f, y, z - (double)f, x + (double)f, y + (double)f1, z + (double)f));
}
/**
* Adds 15% to the entity's yaw and subtracts 15% from the pitch. Clamps pitch from -90 to 90. Both arguments in
* degrees.
*/
@SideOnly(Side.CLIENT)
public void turn(float yaw, float pitch)
{
float f = this.rotationPitch;
float f1 = this.rotationYaw;
this.rotationYaw = (float)((double)this.rotationYaw + (double)yaw * 0.15D);
this.rotationPitch = (float)((double)this.rotationPitch - (double)pitch * 0.15D);
this.rotationPitch = MathHelper.clamp(this.rotationPitch, -90.0F, 90.0F);
this.prevRotationPitch += this.rotationPitch - f;
this.prevRotationYaw += this.rotationYaw - f1;
if (this.ridingEntity != null)
{
this.ridingEntity.applyOrientationToEntity(this);
}
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
if (!this.world.isRemote)
{
this.setFlag(6, this.isGlowing());
}
this.onEntityUpdate();
}
/**
* Gets called every tick from main Entity class
*/
public void onEntityUpdate()
{
this.world.profiler.startSection("entityBaseTick");
if (this.isRiding() && this.getRidingEntity().isDead)
{
this.dismountRidingEntity();
}
if (this.rideCooldown > 0)
{
--this.rideCooldown;
}
this.prevDistanceWalkedModified = this.distanceWalkedModified;
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
this.prevRotationPitch = this.rotationPitch;
this.prevRotationYaw = this.rotationYaw;
if (!this.world.isRemote && this.world instanceof WorldServer)
{
this.world.profiler.startSection("portal");
if (this.inPortal)
{
MinecraftServer minecraftserver = this.world.getMinecraftServer();
if (minecraftserver.getAllowNether())
{
if (!this.isRiding())
{
int i = this.getMaxInPortalTime();
if (this.portalCounter++ >= i)
{
this.portalCounter = i;
this.timeUntilPortal = this.getPortalCooldown();
int j;
if (this.world.provider.getDimensionType().getId() == -1)
{
j = 0;
}
else
{
j = -1;
}
this.changeDimension(j);
}
}
this.inPortal = false;
}
}
else
{
if (this.portalCounter > 0)
{
this.portalCounter -= 4;
}
if (this.portalCounter < 0)
{
this.portalCounter = 0;
}
}
this.decrementTimeUntilPortal();
this.world.profiler.endSection();
}
this.spawnRunningParticles();
this.handleWaterMovement();
if (this.world.isRemote)
{
this.extinguish();
}
else if (this.fire > 0)
{
if (this.isImmuneToFire)
{
this.fire -= 4;
if (this.fire < 0)
{
this.extinguish();
}
}
else
{
if (this.fire % 20 == 0)
{
this.attackEntityFrom(DamageSource.ON_FIRE, 1.0F);
}
--this.fire;
}
}
if (this.isInLava())
{
this.setOnFireFromLava();
this.fallDistance *= 0.5F;
}
if (this.posY < -64.0D)
{
this.outOfWorld();
}
if (!this.world.isRemote)
{
this.setFlag(0, this.fire > 0);
}
this.firstUpdate = false;
this.world.profiler.endSection();
}
/**
* Decrements the counter for the remaining time until the entity may use a portal again.
*/
protected void decrementTimeUntilPortal()
{
if (this.timeUntilPortal > 0)
{
--this.timeUntilPortal;
}
}
/**
* Return the amount of time this entity should stay in a portal before being transported.
*/
public int getMaxInPortalTime()
{
return 1;
}
/**
* Called whenever the entity is walking inside of lava.
*/
protected void setOnFireFromLava()
{
if (!this.isImmuneToFire)
{
this.attackEntityFrom(DamageSource.LAVA, 4.0F);
this.setFire(15);
}
}
/**
* Sets entity to burn for x amount of seconds, cannot lower amount of existing fire.
*/
public void setFire(int seconds)
{
int i = seconds * 20;
if (this instanceof EntityLivingBase)
{
i = EnchantmentProtection.getFireTimeForEntity((EntityLivingBase)this, i);
}
if (this.fire < i)
{
this.fire = i;
}
}
/**
* Removes fire from entity.
*/
public void extinguish()
{
this.fire = 0;
}
/**
* sets the dead flag. Used when you fall off the bottom of the world.
*/
protected void outOfWorld()
{
this.setDead();
}
/**
* Checks if the offset position from the entity's current position is inside of a liquid.
*/
public boolean isOffsetPositionInLiquid(double x, double y, double z)
{
AxisAlignedBB axisalignedbb = this.getEntityBoundingBox().offset(x, y, z);
return this.isLiquidPresentInAABB(axisalignedbb);
}
/**
* Determines if a liquid is present within the specified AxisAlignedBB.
*/
private boolean isLiquidPresentInAABB(AxisAlignedBB bb)
{
return this.world.getCollisionBoxes(this, bb).isEmpty() && !this.world.containsAnyLiquid(bb);
}
/**
* Tries to move the entity towards the specified location.
*/
public void move(MoverType type, double x, double y, double z)
{
if (this.noClip)
{
this.setEntityBoundingBox(this.getEntityBoundingBox().offset(x, y, z));
this.resetPositionToBB();
}
else
{
if (type == MoverType.PISTON)
{
long i = this.world.getTotalWorldTime();
if (i != this.pistonDeltasGameTime)
{
Arrays.fill(this.pistonDeltas, 0.0D);
this.pistonDeltasGameTime = i;
}
if (x != 0.0D)
{
int j = EnumFacing.Axis.X.ordinal();
double d0 = MathHelper.clamp(x + this.pistonDeltas[j], -0.51D, 0.51D);
x = d0 - this.pistonDeltas[j];
this.pistonDeltas[j] = d0;
if (Math.abs(x) <= 9.999999747378752E-6D)
{
return;
}
}
else if (y != 0.0D)
{
int l4 = EnumFacing.Axis.Y.ordinal();
double d12 = MathHelper.clamp(y + this.pistonDeltas[l4], -0.51D, 0.51D);
y = d12 - this.pistonDeltas[l4];
this.pistonDeltas[l4] = d12;
if (Math.abs(y) <= 9.999999747378752E-6D)
{
return;
}
}
else
{
if (z == 0.0D)
{
return;
}
int i5 = EnumFacing.Axis.Z.ordinal();
double d13 = MathHelper.clamp(z + this.pistonDeltas[i5], -0.51D, 0.51D);
z = d13 - this.pistonDeltas[i5];
this.pistonDeltas[i5] = d13;
if (Math.abs(z) <= 9.999999747378752E-6D)
{
return;
}
}
}
this.world.profiler.startSection("move");
double d10 = this.posX;
double d11 = this.posY;
double d1 = this.posZ;
if (this.isInWeb)
{
this.isInWeb = false;
x *= 0.25D;
y *= 0.05000000074505806D;
z *= 0.25D;
this.motionX = 0.0D;
this.motionY = 0.0D;
this.motionZ = 0.0D;
}
double d2 = x;
double d3 = y;
double d4 = z;
if ((type == MoverType.SELF || type == MoverType.PLAYER) && this.onGround && this.isSneaking() && this instanceof EntityPlayer)
{
for (double d5 = 0.05D; x != 0.0D && this.world.getCollisionBoxes(this, this.getEntityBoundingBox().offset(x, (double)(-this.stepHeight), 0.0D)).isEmpty(); d2 = x)
{
if (x < 0.05D && x >= -0.05D)
{
x = 0.0D;
}
else if (x > 0.0D)
{
x -= 0.05D;
}
else
{
x += 0.05D;
}
}
for (; z != 0.0D && this.world.getCollisionBoxes(this, this.getEntityBoundingBox().offset(0.0D, (double)(-this.stepHeight), z)).isEmpty(); d4 = z)
{
if (z < 0.05D && z >= -0.05D)
{
z = 0.0D;
}
else if (z > 0.0D)
{
z -= 0.05D;
}
else
{
z += 0.05D;
}
}
for (; x != 0.0D && z != 0.0D && this.world.getCollisionBoxes(this, this.getEntityBoundingBox().offset(x, (double)(-this.stepHeight), z)).isEmpty(); d4 = z)
{
if (x < 0.05D && x >= -0.05D)
{
x = 0.0D;
}
else if (x > 0.0D)
{
x -= 0.05D;
}
else
{
x += 0.05D;
}
d2 = x;
if (z < 0.05D && z >= -0.05D)
{
z = 0.0D;
}
else if (z > 0.0D)
{
z -= 0.05D;
}
else
{
z += 0.05D;
}
}
}
List<AxisAlignedBB> list1 = this.world.getCollisionBoxes(this, this.getEntityBoundingBox().expand(x, y, z));
AxisAlignedBB axisalignedbb = this.getEntityBoundingBox();
if (y != 0.0D)
{
int k = 0;
for (int l = list1.size(); k < l; ++k)
{
y = ((AxisAlignedBB)list1.get(k)).calculateYOffset(this.getEntityBoundingBox(), y);
}
this.setEntityBoundingBox(this.getEntityBoundingBox().offset(0.0D, y, 0.0D));
}
if (x != 0.0D)
{
int j5 = 0;
for (int l5 = list1.size(); j5 < l5; ++j5)
{
x = ((AxisAlignedBB)list1.get(j5)).calculateXOffset(this.getEntityBoundingBox(), x);
}
if (x != 0.0D)
{
this.setEntityBoundingBox(this.getEntityBoundingBox().offset(x, 0.0D, 0.0D));
}
}
if (z != 0.0D)
{
int k5 = 0;
for (int i6 = list1.size(); k5 < i6; ++k5)
{
z = ((AxisAlignedBB)list1.get(k5)).calculateZOffset(this.getEntityBoundingBox(), z);
}
if (z != 0.0D)
{
this.setEntityBoundingBox(this.getEntityBoundingBox().offset(0.0D, 0.0D, z));
}
}
boolean flag = this.onGround || d3 != y && d3 < 0.0D;
if (this.stepHeight > 0.0F && flag && (d2 != x || d4 != z))
{
double d14 = x;
double d6 = y;
double d7 = z;
AxisAlignedBB axisalignedbb1 = this.getEntityBoundingBox();
this.setEntityBoundingBox(axisalignedbb);
y = (double)this.stepHeight;
List<AxisAlignedBB> list = this.world.getCollisionBoxes(this, this.getEntityBoundingBox().expand(d2, y, d4));
AxisAlignedBB axisalignedbb2 = this.getEntityBoundingBox();
AxisAlignedBB axisalignedbb3 = axisalignedbb2.expand(d2, 0.0D, d4);
double d8 = y;
int j1 = 0;
for (int k1 = list.size(); j1 < k1; ++j1)
{
d8 = ((AxisAlignedBB)list.get(j1)).calculateYOffset(axisalignedbb3, d8);
}
axisalignedbb2 = axisalignedbb2.offset(0.0D, d8, 0.0D);
double d18 = d2;
int l1 = 0;
for (int i2 = list.size(); l1 < i2; ++l1)
{
d18 = ((AxisAlignedBB)list.get(l1)).calculateXOffset(axisalignedbb2, d18);
}
axisalignedbb2 = axisalignedbb2.offset(d18, 0.0D, 0.0D);
double d19 = d4;
int j2 = 0;
for (int k2 = list.size(); j2 < k2; ++j2)
{
d19 = ((AxisAlignedBB)list.get(j2)).calculateZOffset(axisalignedbb2, d19);
}
axisalignedbb2 = axisalignedbb2.offset(0.0D, 0.0D, d19);
AxisAlignedBB axisalignedbb4 = this.getEntityBoundingBox();
double d20 = y;
int l2 = 0;
for (int i3 = list.size(); l2 < i3; ++l2)
{
d20 = ((AxisAlignedBB)list.get(l2)).calculateYOffset(axisalignedbb4, d20);
}
axisalignedbb4 = axisalignedbb4.offset(0.0D, d20, 0.0D);
double d21 = d2;
int j3 = 0;
for (int k3 = list.size(); j3 < k3; ++j3)
{
d21 = ((AxisAlignedBB)list.get(j3)).calculateXOffset(axisalignedbb4, d21);
}
axisalignedbb4 = axisalignedbb4.offset(d21, 0.0D, 0.0D);
double d22 = d4;
int l3 = 0;
for (int i4 = list.size(); l3 < i4; ++l3)
{
d22 = ((AxisAlignedBB)list.get(l3)).calculateZOffset(axisalignedbb4, d22);
}
axisalignedbb4 = axisalignedbb4.offset(0.0D, 0.0D, d22);
double d23 = d18 * d18 + d19 * d19;
double d9 = d21 * d21 + d22 * d22;
if (d23 > d9)
{
x = d18;
z = d19;
y = -d8;
this.setEntityBoundingBox(axisalignedbb2);
}
else
{
x = d21;
z = d22;
y = -d20;
this.setEntityBoundingBox(axisalignedbb4);
}
int j4 = 0;
for (int k4 = list.size(); j4 < k4; ++j4)
{
y = ((AxisAlignedBB)list.get(j4)).calculateYOffset(this.getEntityBoundingBox(), y);
}
this.setEntityBoundingBox(this.getEntityBoundingBox().offset(0.0D, y, 0.0D));
if (d14 * d14 + d7 * d7 >= x * x + z * z)
{
x = d14;
y = d6;
z = d7;
this.setEntityBoundingBox(axisalignedbb1);
}
}
this.world.profiler.endSection();
this.world.profiler.startSection("rest");
this.resetPositionToBB();
this.collidedHorizontally = d2 != x || d4 != z;
this.collidedVertically = d3 != y;
this.onGround = this.collidedVertically && d3 < 0.0D;
this.collided = this.collidedHorizontally || this.collidedVertically;
int j6 = MathHelper.floor(this.posX);
int i1 = MathHelper.floor(this.posY - 0.20000000298023224D);
int k6 = MathHelper.floor(this.posZ);
BlockPos blockpos = new BlockPos(j6, i1, k6);
IBlockState iblockstate = this.world.getBlockState(blockpos);
if (iblockstate.getMaterial() == Material.AIR)
{
BlockPos blockpos1 = blockpos.down();
IBlockState iblockstate1 = this.world.getBlockState(blockpos1);
Block block1 = iblockstate1.getBlock();
if (block1 instanceof BlockFence || block1 instanceof BlockWall || block1 instanceof BlockFenceGate)
{
iblockstate = iblockstate1;
blockpos = blockpos1;
}
}
this.updateFallState(y, this.onGround, iblockstate, blockpos);
if (d2 != x)
{
this.motionX = 0.0D;
}
if (d4 != z)
{
this.motionZ = 0.0D;
}
Block block = iblockstate.getBlock();
if (d3 != y)
{
block.onLanded(this.world, this);
}
if (this.canTriggerWalking() && (!this.onGround || !this.isSneaking() || !(this instanceof EntityPlayer)) && !this.isRiding())
{
double d15 = this.posX - d10;
double d16 = this.posY - d11;
double d17 = this.posZ - d1;
if (block != Blocks.LADDER)
{
d16 = 0.0D;
}
if (block != null && this.onGround)
{
block.onEntityWalk(this.world, blockpos, this);
}
this.distanceWalkedModified = (float)((double)this.distanceWalkedModified + (double)MathHelper.sqrt(d15 * d15 + d17 * d17) * 0.6D);
this.distanceWalkedOnStepModified = (float)((double)this.distanceWalkedOnStepModified + (double)MathHelper.sqrt(d15 * d15 + d16 * d16 + d17 * d17) * 0.6D);
if (this.distanceWalkedOnStepModified > (float)this.nextStepDistance && iblockstate.getMaterial() != Material.AIR)
{
this.nextStepDistance = (int)this.distanceWalkedOnStepModified + 1;
if (this.isInWater())
{
Entity entity = this.isBeingRidden() && this.getControllingPassenger() != null ? this.getControllingPassenger() : this;
float f = entity == this ? 0.35F : 0.4F;
float f1 = MathHelper.sqrt(entity.motionX * entity.motionX * 0.20000000298023224D + entity.motionY * entity.motionY + entity.motionZ * entity.motionZ * 0.20000000298023224D) * f;
if (f1 > 1.0F)
{
f1 = 1.0F;
}
this.playSound(this.getSwimSound(), f1, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
}
else
{
this.playStepSound(blockpos, block);
}
}
else if (this.distanceWalkedOnStepModified > this.nextFlap && this.makeFlySound() && iblockstate.getMaterial() == Material.AIR)
{
this.nextFlap = this.playFlySound(this.distanceWalkedOnStepModified);
}
}
try
{
this.doBlockCollisions();
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Checking entity block collision");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity being checked for collision");
this.addEntityCrashInfo(crashreportcategory);
throw new ReportedException(crashreport);
}
boolean flag1 = this.isWet();
if (this.world.isFlammableWithin(this.getEntityBoundingBox().shrink(0.001D)))
{
this.dealFireDamage(1);
if (!flag1)
{
++this.fire;
if (this.fire == 0)
{
this.setFire(8);
}
}
}
else if (this.fire <= 0)
{
this.fire = -this.getFireImmuneTicks();
}
if (flag1 && this.isBurning())
{
this.playSound(SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, 0.7F, 1.6F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
this.fire = -this.getFireImmuneTicks();
}
this.world.profiler.endSection();
}
}
/**
* Resets the entity's position to the center (planar) and bottom (vertical) points of its bounding box.
*/
public void resetPositionToBB()
{
AxisAlignedBB axisalignedbb = this.getEntityBoundingBox();
this.posX = (axisalignedbb.minX + axisalignedbb.maxX) / 2.0D;
this.posY = axisalignedbb.minY;
this.posZ = (axisalignedbb.minZ + axisalignedbb.maxZ) / 2.0D;
}
protected SoundEvent getSwimSound()
{
return SoundEvents.ENTITY_GENERIC_SWIM;
}
protected SoundEvent getSplashSound()
{
return SoundEvents.ENTITY_GENERIC_SPLASH;
}
protected void doBlockCollisions()
{
AxisAlignedBB axisalignedbb = this.getEntityBoundingBox();
BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(axisalignedbb.minX + 0.001D, axisalignedbb.minY + 0.001D, axisalignedbb.minZ + 0.001D);
BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos1 = BlockPos.PooledMutableBlockPos.retain(axisalignedbb.maxX - 0.001D, axisalignedbb.maxY - 0.001D, axisalignedbb.maxZ - 0.001D);
BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos2 = BlockPos.PooledMutableBlockPos.retain();
if (this.world.isAreaLoaded(blockpos$pooledmutableblockpos, blockpos$pooledmutableblockpos1))
{
for (int i = blockpos$pooledmutableblockpos.getX(); i <= blockpos$pooledmutableblockpos1.getX(); ++i)
{
for (int j = blockpos$pooledmutableblockpos.getY(); j <= blockpos$pooledmutableblockpos1.getY(); ++j)
{
for (int k = blockpos$pooledmutableblockpos.getZ(); k <= blockpos$pooledmutableblockpos1.getZ(); ++k)
{
blockpos$pooledmutableblockpos2.setPos(i, j, k);
IBlockState iblockstate = this.world.getBlockState(blockpos$pooledmutableblockpos2);
try
{
iblockstate.getBlock().onEntityCollidedWithBlock(this.world, blockpos$pooledmutableblockpos2, iblockstate, this);
this.onInsideBlock(iblockstate);
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Colliding entity with block");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Block being collided with");
CrashReportCategory.addBlockInfo(crashreportcategory, blockpos$pooledmutableblockpos2, iblockstate);
throw new ReportedException(crashreport);
}
}
}
}
}
blockpos$pooledmutableblockpos.release();
blockpos$pooledmutableblockpos1.release();
blockpos$pooledmutableblockpos2.release();
}
protected void onInsideBlock(IBlockState p_191955_1_)
{
}
protected void playStepSound(BlockPos pos, Block blockIn)
{
SoundType soundtype = blockIn.getSoundType(world.getBlockState(pos), world, pos, this);
if (this.world.getBlockState(pos.up()).getBlock() == Blocks.SNOW_LAYER)
{
soundtype = Blocks.SNOW_LAYER.getSoundType();
this.playSound(soundtype.getStepSound(), soundtype.getVolume() * 0.15F, soundtype.getPitch());
}
else if (!blockIn.getDefaultState().getMaterial().isLiquid())
{
this.playSound(soundtype.getStepSound(), soundtype.getVolume() * 0.15F, soundtype.getPitch());
}
}
protected float playFlySound(float p_191954_1_)
{
return 0.0F;
}
protected boolean makeFlySound()
{
return false;
}
public void playSound(SoundEvent soundIn, float volume, float pitch)
{
if (!this.isSilent())
{
this.world.playSound((EntityPlayer)null, this.posX, this.posY, this.posZ, soundIn, this.getSoundCategory(), volume, pitch);
}
}
/**
* @return True if this entity will not play sounds
*/
public boolean isSilent()
{
return ((Boolean)this.dataManager.get(SILENT)).booleanValue();
}
/**
* When set to true the entity will not play sounds.
*/
public void setSilent(boolean isSilent)
{
this.dataManager.set(SILENT, Boolean.valueOf(isSilent));
}
public boolean hasNoGravity()
{
return ((Boolean)this.dataManager.get(NO_GRAVITY)).booleanValue();
}
public void setNoGravity(boolean noGravity)
{
this.dataManager.set(NO_GRAVITY, Boolean.valueOf(noGravity));
}
/**
* 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 true;
}
protected void updateFallState(double y, boolean onGroundIn, IBlockState state, BlockPos pos)
{
if (onGroundIn)
{
if (this.fallDistance > 0.0F)
{
state.getBlock().onFallenUpon(this.world, pos, this, this.fallDistance);
}
this.fallDistance = 0.0F;
}
else if (y < 0.0D)
{
this.fallDistance = (float)((double)this.fallDistance - y);
}
}
/**
* Returns the <b>solid</b> collision bounding box for this entity. Used to make (e.g.) boats solid. Return null if
* this entity is not solid.
*
* For general purposes, use {@link #width} and {@link #height}.
*
* @see getEntityBoundingBox
*/
@Nullable
public AxisAlignedBB getCollisionBoundingBox()
{
return null;
}
/**
* Will deal the specified amount of fire damage to the entity if the entity isn't immune to fire damage.
*/
protected void dealFireDamage(int amount)
{
if (!this.isImmuneToFire)
{
this.attackEntityFrom(DamageSource.IN_FIRE, (float)amount);
}
}
public final boolean isImmuneToFire()
{
return this.isImmuneToFire;
}
public void fall(float distance, float damageMultiplier)
{
if (this.isBeingRidden())
{
for (Entity entity : this.getPassengers())
{
entity.fall(distance, damageMultiplier);
}
}
}
/**
* Checks if this entity is either in water or on an open air block in rain (used in wolves).
*/
public boolean isWet()
{
if (this.inWater)
{
return true;
}
else
{
BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(this.posX, this.posY, this.posZ);
if (!this.world.isRainingAt(blockpos$pooledmutableblockpos) && !this.world.isRainingAt(blockpos$pooledmutableblockpos.setPos(this.posX, this.posY + (double)this.height, this.posZ)))
{
blockpos$pooledmutableblockpos.release();
return false;
}
else
{
blockpos$pooledmutableblockpos.release();
return true;
}
}
}
/**
* Checks if this entity is inside water (if inWater field is true as a result of handleWaterMovement() returning
* true)
*/
public boolean isInWater()
{
return this.inWater;
}
public boolean isOverWater()
{
return this.world.handleMaterialAcceleration(this.getEntityBoundingBox().grow(0.0D, -20.0D, 0.0D).shrink(0.001D), Material.WATER, this);
}
/**
* Returns if this entity is in water and will end up adding the waters velocity to the entity
*/
public boolean handleWaterMovement()
{
if (this.getRidingEntity() instanceof EntityBoat)
{
this.inWater = false;
}
else if (this.world.handleMaterialAcceleration(this.getEntityBoundingBox().grow(0.0D, -0.4000000059604645D, 0.0D).shrink(0.001D), Material.WATER, this))
{
if (!this.inWater && !this.firstUpdate)
{
this.doWaterSplashEffect();
}
this.fallDistance = 0.0F;
this.inWater = true;
this.extinguish();
}
else
{
this.inWater = false;
}
return this.inWater;
}
/**
* Plays the {@link #getSplashSound() splash sound}, and the {@link ParticleType#WATER_BUBBLE} and {@link
* ParticleType#WATER_SPLASH} particles.
*/
protected void doWaterSplashEffect()
{
Entity entity = this.isBeingRidden() && this.getControllingPassenger() != null ? this.getControllingPassenger() : this;
float f = entity == this ? 0.2F : 0.9F;
float f1 = MathHelper.sqrt(entity.motionX * entity.motionX * 0.20000000298023224D + entity.motionY * entity.motionY + entity.motionZ * entity.motionZ * 0.20000000298023224D) * f;
if (f1 > 1.0F)
{
f1 = 1.0F;
}
this.playSound(this.getSplashSound(), f1, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
float f2 = (float)MathHelper.floor(this.getEntityBoundingBox().minY);
for (int i = 0; (float)i < 1.0F + this.width * 20.0F; ++i)
{
float f3 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width;
float f4 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width;
this.world.spawnParticle(EnumParticleTypes.WATER_BUBBLE, this.posX + (double)f3, (double)(f2 + 1.0F), this.posZ + (double)f4, this.motionX, this.motionY - (double)(this.rand.nextFloat() * 0.2F), this.motionZ);
}
for (int j = 0; (float)j < 1.0F + this.width * 20.0F; ++j)
{
float f5 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width;
float f6 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width;
this.world.spawnParticle(EnumParticleTypes.WATER_SPLASH, this.posX + (double)f5, (double)(f2 + 1.0F), this.posZ + (double)f6, this.motionX, this.motionY, this.motionZ);
}
}
/**
* Attempts to create sprinting particles if the entity is sprinting and not in water.
*/
public void spawnRunningParticles()
{
if (this.isSprinting() && !this.isInWater())
{
this.createRunningParticles();
}
}
protected void createRunningParticles()
{
int i = MathHelper.floor(this.posX);
int j = MathHelper.floor(this.posY - 0.20000000298023224D);
int k = MathHelper.floor(this.posZ);
BlockPos blockpos = new BlockPos(i, j, k);
IBlockState iblockstate = this.world.getBlockState(blockpos);
if(!iblockstate.getBlock().addRunningEffects(iblockstate, world, blockpos, this))
if (iblockstate.getRenderType() != EnumBlockRenderType.INVISIBLE)
{
this.world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, this.posX + ((double)this.rand.nextFloat() - 0.5D) * (double)this.width, this.getEntityBoundingBox().minY + 0.1D, this.posZ + ((double)this.rand.nextFloat() - 0.5D) * (double)this.width, -this.motionX * 4.0D, 1.5D, -this.motionZ * 4.0D, Block.getStateId(iblockstate));
}
}
/**
* Checks if the current block the entity is within of the specified material type
*/
public boolean isInsideOfMaterial(Material materialIn)
{
if (this.getRidingEntity() instanceof EntityBoat)
{
return false;
}
else
{
double d0 = this.posY + (double)this.getEyeHeight();
BlockPos blockpos = new BlockPos(this.posX, d0, this.posZ);
IBlockState iblockstate = this.world.getBlockState(blockpos);
Boolean result = iblockstate.getBlock().isEntityInsideMaterial(this.world, blockpos, iblockstate, this, d0, materialIn, true);
if (result != null) return result;
if (iblockstate.getMaterial() == materialIn)
{
return net.minecraftforge.common.ForgeHooks.isInsideOfMaterial(materialIn, this, blockpos);
}
else
{
return false;
}
}
}
public boolean isInLava()
{
return this.world.isMaterialInBB(this.getEntityBoundingBox().grow(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.LAVA);
}
public void moveRelative(float strafe, float up, float forward, float friction)
{
float f = strafe * strafe + up * up + forward * forward;
if (f >= 1.0E-4F)
{
f = MathHelper.sqrt(f);
if (f < 1.0F)
{
f = 1.0F;
}
f = friction / f;
strafe = strafe * f;
up = up * f;
forward = forward * f;
float f1 = MathHelper.sin(this.rotationYaw * 0.017453292F);
float f2 = MathHelper.cos(this.rotationYaw * 0.017453292F);
this.motionX += (double)(strafe * f2 - forward * f1);
this.motionY += (double)up;
this.motionZ += (double)(forward * f2 + strafe * f1);
}
}
@SideOnly(Side.CLIENT)
public int getBrightnessForRender()
{
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(MathHelper.floor(this.posX), 0, MathHelper.floor(this.posZ));
if (this.world.isBlockLoaded(blockpos$mutableblockpos))
{
blockpos$mutableblockpos.setY(MathHelper.floor(this.posY + (double)this.getEyeHeight()));
return this.world.getCombinedLight(blockpos$mutableblockpos, 0);
}
else
{
return 0;
}
}
/**
* Gets how bright this entity is.
*/
public float getBrightness()
{
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(MathHelper.floor(this.posX), 0, MathHelper.floor(this.posZ));
if (this.world.isBlockLoaded(blockpos$mutableblockpos))
{
blockpos$mutableblockpos.setY(MathHelper.floor(this.posY + (double)this.getEyeHeight()));
return this.world.getLightBrightness(blockpos$mutableblockpos);
}
else
{
return 0.0F;
}
}
/**
* Sets the reference to the World object.
*/
public void setWorld(World worldIn)
{
this.world = worldIn;
}
/**
* Sets position and rotation, clamping and wrapping params to valid values. Used by network code.
*/
public void setPositionAndRotation(double x, double y, double z, float yaw, float pitch)
{
this.posX = MathHelper.clamp(x, -3.0E7D, 3.0E7D);
this.posY = y;
this.posZ = MathHelper.clamp(z, -3.0E7D, 3.0E7D);
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
pitch = MathHelper.clamp(pitch, -90.0F, 90.0F);
this.rotationYaw = yaw;
this.rotationPitch = pitch;
this.prevRotationYaw = this.rotationYaw;
this.prevRotationPitch = this.rotationPitch;
double d0 = (double)(this.prevRotationYaw - yaw);
if (d0 < -180.0D)
{
this.prevRotationYaw += 360.0F;
}
if (d0 >= 180.0D)
{
this.prevRotationYaw -= 360.0F;
}
this.setPosition(this.posX, this.posY, this.posZ);
this.setRotation(yaw, pitch);
}
public void moveToBlockPosAndAngles(BlockPos pos, float rotationYawIn, float rotationPitchIn)
{
this.setLocationAndAngles((double)pos.getX() + 0.5D, (double)pos.getY(), (double)pos.getZ() + 0.5D, rotationYawIn, rotationPitchIn);
}
/**
* Sets the location and Yaw/Pitch of an entity in the world
*/
public void setLocationAndAngles(double x, double y, double z, float yaw, float pitch)
{
this.posX = x;
this.posY = y;
this.posZ = z;
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
this.lastTickPosX = this.posX;
this.lastTickPosY = this.posY;
this.lastTickPosZ = this.posZ;
this.rotationYaw = yaw;
this.rotationPitch = pitch;
this.setPosition(this.posX, this.posY, this.posZ);
}
/**
* Returns the distance to the entity.
*/
public float getDistance(Entity entityIn)
{
float f = (float)(this.posX - entityIn.posX);
float f1 = (float)(this.posY - entityIn.posY);
float f2 = (float)(this.posZ - entityIn.posZ);
return MathHelper.sqrt(f * f + f1 * f1 + f2 * f2);
}
/**
* Gets the squared distance to the position.
*/
public double getDistanceSq(double x, double y, double z)
{
double d0 = this.posX - x;
double d1 = this.posY - y;
double d2 = this.posZ - z;
return d0 * d0 + d1 * d1 + d2 * d2;
}
public double getDistanceSq(BlockPos pos)
{
return pos.distanceSq(this.posX, this.posY, this.posZ);
}
public double getDistanceSqToCenter(BlockPos pos)
{
return pos.distanceSqToCenter(this.posX, this.posY, this.posZ);
}
/**
* Gets the distance to the position.
*/
public double getDistance(double x, double y, double z)
{
double d0 = this.posX - x;
double d1 = this.posY - y;
double d2 = this.posZ - z;
return (double)MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
}
/**
* Returns the squared distance to the entity.
*/
public double getDistanceSq(Entity entityIn)
{
double d0 = this.posX - entityIn.posX;
double d1 = this.posY - entityIn.posY;
double d2 = this.posZ - entityIn.posZ;
return d0 * d0 + d1 * d1 + d2 * d2;
}
/**
* Called by a player entity when they collide with an entity
*/
public void onCollideWithPlayer(EntityPlayer entityIn)
{
}
/**
* Applies a velocity to the entities, to push them away from eachother.
*/
public void applyEntityCollision(Entity entityIn)
{
if (!this.isRidingSameEntity(entityIn))
{
if (!entityIn.noClip && !this.noClip)
{
double d0 = entityIn.posX - this.posX;
double d1 = entityIn.posZ - this.posZ;
double d2 = MathHelper.absMax(d0, d1);
if (d2 >= 0.009999999776482582D)
{
d2 = (double)MathHelper.sqrt(d2);
d0 = d0 / d2;
d1 = d1 / d2;
double d3 = 1.0D / d2;
if (d3 > 1.0D)
{
d3 = 1.0D;
}
d0 = d0 * d3;
d1 = d1 * d3;
d0 = d0 * 0.05000000074505806D;
d1 = d1 * 0.05000000074505806D;
d0 = d0 * (double)(1.0F - this.entityCollisionReduction);
d1 = d1 * (double)(1.0F - this.entityCollisionReduction);
if (!this.isBeingRidden())
{
this.addVelocity(-d0, 0.0D, -d1);
}
if (!entityIn.isBeingRidden())
{
entityIn.addVelocity(d0, 0.0D, d1);
}
}
}
}
}
/**
* Adds to the current velocity of the entity, and sets {@link #isAirBorne} to true.
*/
public void addVelocity(double x, double y, double z)
{
this.motionX += x;
this.motionY += y;
this.motionZ += z;
this.isAirBorne = true;
}
/**
* Marks this entity's velocity as changed, so that it can be re-synced with the client later
*/
protected void markVelocityChanged()
{
this.velocityChanged = true;
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource source, float amount)
{
if (this.isEntityInvulnerable(source))
{
return false;
}
else
{
this.markVelocityChanged();
return false;
}
}
/**
* interpolated look vector
*/
public Vec3d getLook(float partialTicks)
{
if (partialTicks == 1.0F)
{
return this.getVectorForRotation(this.rotationPitch, this.rotationYaw);
}
else
{
float f = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * partialTicks;
float f1 = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * partialTicks;
return this.getVectorForRotation(f, f1);
}
}
/**
* Creates a Vec3 using the pitch and yaw of the entities rotation.
*/
protected final Vec3d getVectorForRotation(float pitch, float yaw)
{
float f = MathHelper.cos(-yaw * 0.017453292F - (float)Math.PI);
float f1 = MathHelper.sin(-yaw * 0.017453292F - (float)Math.PI);
float f2 = -MathHelper.cos(-pitch * 0.017453292F);
float f3 = MathHelper.sin(-pitch * 0.017453292F);
return new Vec3d((double)(f1 * f2), (double)f3, (double)(f * f2));
}
public Vec3d getPositionEyes(float partialTicks)
{
if (partialTicks == 1.0F)
{
return new Vec3d(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ);
}
else
{
double d0 = this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks;
double d1 = this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks + (double)this.getEyeHeight();
double d2 = this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks;
return new Vec3d(d0, d1, d2);
}
}
@Nullable
@SideOnly(Side.CLIENT)
public RayTraceResult rayTrace(double blockReachDistance, float partialTicks)
{
Vec3d vec3d = this.getPositionEyes(partialTicks);
Vec3d vec3d1 = this.getLook(partialTicks);
Vec3d vec3d2 = vec3d.addVector(vec3d1.x * blockReachDistance, vec3d1.y * blockReachDistance, vec3d1.z * blockReachDistance);
return this.world.rayTraceBlocks(vec3d, vec3d2, false, false, true);
}
/**
* Returns true if other Entities should be prevented from moving through this Entity.
*/
public boolean canBeCollidedWith()
{
return false;
}
/**
* Returns true if this entity should push and be pushed by other entities when colliding.
*/
public boolean canBePushed()
{
return false;
}
public void awardKillScore(Entity p_191956_1_, int p_191956_2_, DamageSource p_191956_3_)
{
if (p_191956_1_ instanceof EntityPlayerMP)
{
CriteriaTriggers.ENTITY_KILLED_PLAYER.trigger((EntityPlayerMP)p_191956_1_, this, p_191956_3_);
}
}
@SideOnly(Side.CLIENT)
public boolean isInRangeToRender3d(double x, double y, double z)
{
double d0 = this.posX - x;
double d1 = this.posY - y;
double d2 = this.posZ - z;
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
return this.isInRangeToRenderDist(d3);
}
/**
* Checks if the entity is in range to render.
*/
@SideOnly(Side.CLIENT)
public boolean isInRangeToRenderDist(double distance)
{
double d0 = this.getEntityBoundingBox().getAverageEdgeLength();
if (Double.isNaN(d0))
{
d0 = 1.0D;
}
d0 = d0 * 64.0D * renderDistanceWeight;
return distance < d0 * d0;
}
/**
* Attempts to write this Entity to the given NBTTagCompound. Returns false if the entity is dead or its string
* representation is null. In this event, the given NBTTagCompound is not modified.
*
* Similar to writeToNBTOptional, but does not check whether this Entity is a passenger of another.
*/
public boolean writeToNBTAtomically(NBTTagCompound compound)
{
String s = this.getEntityString();
if (!this.isDead && s != null)
{
compound.setString("id", s);
this.writeToNBT(compound);
return true;
}
else
{
return false;
}
}
/**
* Either write this entity to the NBT tag given and return true, or return false without doing anything. If this
* returns false the entity is not saved on disk. Riding entities return false here as they are saved with their
* mount.
*/
public boolean writeToNBTOptional(NBTTagCompound compound)
{
String s = this.getEntityString();
if (!this.isDead && s != null && !this.isRiding())
{
compound.setString("id", s);
this.writeToNBT(compound);
return true;
}
else
{
return false;
}
}
public static void registerFixes(DataFixer fixer)
{
fixer.registerWalker(FixTypes.ENTITY, new IDataWalker()
{
public NBTTagCompound process(IDataFixer fixer, NBTTagCompound compound, int versionIn)
{
if (compound.hasKey("Passengers", 9))
{
NBTTagList nbttaglist = compound.getTagList("Passengers", 10);
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
nbttaglist.set(i, fixer.process(FixTypes.ENTITY, nbttaglist.getCompoundTagAt(i), versionIn));
}
}
return compound;
}
});
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
try
{
compound.setTag("Pos", this.newDoubleNBTList(this.posX, this.posY, this.posZ));
compound.setTag("Motion", this.newDoubleNBTList(this.motionX, this.motionY, this.motionZ));
compound.setTag("Rotation", this.newFloatNBTList(this.rotationYaw, this.rotationPitch));
compound.setFloat("FallDistance", this.fallDistance);
compound.setShort("Fire", (short)this.fire);
compound.setShort("Air", (short)this.getAir());
compound.setBoolean("OnGround", this.onGround);
compound.setInteger("Dimension", this.dimension);
compound.setBoolean("Invulnerable", this.invulnerable);
compound.setInteger("PortalCooldown", this.timeUntilPortal);
compound.setUniqueId("UUID", this.getUniqueID());
if (this.hasCustomName())
{
compound.setString("CustomName", this.getCustomNameTag());
}
if (this.getAlwaysRenderNameTag())
{
compound.setBoolean("CustomNameVisible", this.getAlwaysRenderNameTag());
}
this.cmdResultStats.writeStatsToNBT(compound);
if (this.isSilent())
{
compound.setBoolean("Silent", this.isSilent());
}
if (this.hasNoGravity())
{
compound.setBoolean("NoGravity", this.hasNoGravity());
}
if (this.glowing)
{
compound.setBoolean("Glowing", this.glowing);
}
compound.setBoolean("UpdateBlocked", updateBlocked);
if (!this.tags.isEmpty())
{
NBTTagList nbttaglist = new NBTTagList();
for (String s : this.tags)
{
nbttaglist.appendTag(new NBTTagString(s));
}
compound.setTag("Tags", nbttaglist);
}
if (customEntityData != null) compound.setTag("ForgeData", customEntityData);
if (this.capabilities != null) compound.setTag("ForgeCaps", this.capabilities.serializeNBT());
this.writeEntityToNBT(compound);
if (this.isBeingRidden())
{
NBTTagList nbttaglist1 = new NBTTagList();
for (Entity entity : this.getPassengers())
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
if (entity.writeToNBTAtomically(nbttagcompound))
{
nbttaglist1.appendTag(nbttagcompound);
}
}
if (!nbttaglist1.hasNoTags())
{
compound.setTag("Passengers", nbttaglist1);
}
}
return compound;
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Saving entity NBT");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity being saved");
this.addEntityCrashInfo(crashreportcategory);
throw new ReportedException(crashreport);
}
}
/**
* Reads the entity from NBT (calls an abstract helper method to read specialized data)
*/
public void readFromNBT(NBTTagCompound compound)
{
try
{
NBTTagList nbttaglist = compound.getTagList("Pos", 6);
NBTTagList nbttaglist2 = compound.getTagList("Motion", 6);
NBTTagList nbttaglist3 = compound.getTagList("Rotation", 5);
this.motionX = nbttaglist2.getDoubleAt(0);
this.motionY = nbttaglist2.getDoubleAt(1);
this.motionZ = nbttaglist2.getDoubleAt(2);
if (Math.abs(this.motionX) > 10.0D)
{
this.motionX = 0.0D;
}
if (Math.abs(this.motionY) > 10.0D)
{
this.motionY = 0.0D;
}
if (Math.abs(this.motionZ) > 10.0D)
{
this.motionZ = 0.0D;
}
this.posX = nbttaglist.getDoubleAt(0);
this.posY = nbttaglist.getDoubleAt(1);
this.posZ = nbttaglist.getDoubleAt(2);
this.lastTickPosX = this.posX;
this.lastTickPosY = this.posY;
this.lastTickPosZ = this.posZ;
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
this.rotationYaw = nbttaglist3.getFloatAt(0);
this.rotationPitch = nbttaglist3.getFloatAt(1);
this.prevRotationYaw = this.rotationYaw;
this.prevRotationPitch = this.rotationPitch;
this.setRotationYawHead(this.rotationYaw);
this.setRenderYawOffset(this.rotationYaw);
this.fallDistance = compound.getFloat("FallDistance");
this.fire = compound.getShort("Fire");
this.setAir(compound.getShort("Air"));
this.onGround = compound.getBoolean("OnGround");
if (compound.hasKey("Dimension"))
{
this.dimension = compound.getInteger("Dimension");
}
this.invulnerable = compound.getBoolean("Invulnerable");
this.timeUntilPortal = compound.getInteger("PortalCooldown");
if (compound.hasUniqueId("UUID"))
{
this.entityUniqueID = compound.getUniqueId("UUID");
this.cachedUniqueIdString = this.entityUniqueID.toString();
}
this.setPosition(this.posX, this.posY, this.posZ);
this.setRotation(this.rotationYaw, this.rotationPitch);
if (compound.hasKey("CustomName", 8))
{
this.setCustomNameTag(compound.getString("CustomName"));
}
this.setAlwaysRenderNameTag(compound.getBoolean("CustomNameVisible"));
this.cmdResultStats.readStatsFromNBT(compound);
this.setSilent(compound.getBoolean("Silent"));
this.setNoGravity(compound.getBoolean("NoGravity"));
this.setGlowing(compound.getBoolean("Glowing"));
updateBlocked = compound.getBoolean("UpdateBlocked");
if (compound.hasKey("ForgeData")) customEntityData = compound.getCompoundTag("ForgeData");
if (this.capabilities != null && compound.hasKey("ForgeCaps")) this.capabilities.deserializeNBT(compound.getCompoundTag("ForgeCaps"));
if (compound.hasKey("Tags", 9))
{
this.tags.clear();
NBTTagList nbttaglist1 = compound.getTagList("Tags", 8);
int i = Math.min(nbttaglist1.tagCount(), 1024);
for (int j = 0; j < i; ++j)
{
this.tags.add(nbttaglist1.getStringTagAt(j));
}
}
this.readEntityFromNBT(compound);
if (this.shouldSetPosAfterLoading())
{
this.setPosition(this.posX, this.posY, this.posZ);
}
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Loading entity NBT");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity being loaded");
this.addEntityCrashInfo(crashreportcategory);
throw new ReportedException(crashreport);
}
}
protected boolean shouldSetPosAfterLoading()
{
return true;
}
/**
* Returns the string that identifies this Entity's class
*/
@Nullable
protected final String getEntityString()
{
ResourceLocation resourcelocation = EntityList.getKey(this);
return resourcelocation == null ? null : resourcelocation.toString();
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
protected abstract void readEntityFromNBT(NBTTagCompound compound);
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
protected abstract void writeEntityToNBT(NBTTagCompound compound);
/**
* creates a NBT list from the array of doubles passed to this function
*/
protected NBTTagList newDoubleNBTList(double... numbers)
{
NBTTagList nbttaglist = new NBTTagList();
for (double d0 : numbers)
{
nbttaglist.appendTag(new NBTTagDouble(d0));
}
return nbttaglist;
}
/**
* Returns a new NBTTagList filled with the specified floats
*/
protected NBTTagList newFloatNBTList(float... numbers)
{
NBTTagList nbttaglist = new NBTTagList();
for (float f : numbers)
{
nbttaglist.appendTag(new NBTTagFloat(f));
}
return nbttaglist;
}
@Nullable
public EntityItem dropItem(Item itemIn, int size)
{
return this.dropItemWithOffset(itemIn, size, 0.0F);
}
@Nullable
public EntityItem dropItemWithOffset(Item itemIn, int size, float offsetY)
{
return this.entityDropItem(new ItemStack(itemIn, size, 0), offsetY);
}
/**
* Drops an item at the position of the entity.
*/
@Nullable
public EntityItem entityDropItem(ItemStack stack, float offsetY)
{
if (stack.isEmpty())
{
return null;
}
else
{
EntityItem entityitem = new EntityItem(this.world, this.posX, this.posY + (double)offsetY, this.posZ, stack);
entityitem.setDefaultPickupDelay();
if (captureDrops)
this.capturedDrops.add(entityitem);
else
this.world.spawnEntity(entityitem);
return entityitem;
}
}
/**
* Checks whether target entity is alive.
*/
public boolean isEntityAlive()
{
return !this.isDead;
}
/**
* Checks if this entity is inside of an opaque block
*/
public boolean isEntityInsideOpaqueBlock()
{
if (this.noClip)
{
return false;
}
else
{
BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain();
for (int i = 0; i < 8; ++i)
{
int j = MathHelper.floor(this.posY + (double)(((float)((i >> 0) % 2) - 0.5F) * 0.1F) + (double)this.getEyeHeight());
int k = MathHelper.floor(this.posX + (double)(((float)((i >> 1) % 2) - 0.5F) * this.width * 0.8F));
int l = MathHelper.floor(this.posZ + (double)(((float)((i >> 2) % 2) - 0.5F) * this.width * 0.8F));
if (blockpos$pooledmutableblockpos.getX() != k || blockpos$pooledmutableblockpos.getY() != j || blockpos$pooledmutableblockpos.getZ() != l)
{
blockpos$pooledmutableblockpos.setPos(k, j, l);
if (this.world.getBlockState(blockpos$pooledmutableblockpos).causesSuffocation())
{
blockpos$pooledmutableblockpos.release();
return true;
}
}
}
blockpos$pooledmutableblockpos.release();
return false;
}
}
public boolean processInitialInteract(EntityPlayer player, EnumHand hand)
{
return false;
}
/**
* Returns a boundingBox used to collide the entity with other entities and blocks. This enables the entity to be
* pushable on contact, like boats or minecarts.
*/
@Nullable
public AxisAlignedBB getCollisionBox(Entity entityIn)
{
return null;
}
/**
* Handles updating while riding another entity
*/
public void updateRidden()
{
Entity entity = this.getRidingEntity();
if (this.isRiding() && entity.isDead)
{
this.dismountRidingEntity();
}
else
{
this.motionX = 0.0D;
this.motionY = 0.0D;
this.motionZ = 0.0D;
if(!updateBlocked)
this.onUpdate();
if (this.isRiding())
{
entity.updatePassenger(this);
}
}
}
public void updatePassenger(Entity passenger)
{
if (this.isPassenger(passenger))
{
passenger.setPosition(this.posX, this.posY + this.getMountedYOffset() + passenger.getYOffset(), this.posZ);
}
}
/**
* Applies this entity's orientation (pitch/yaw) to another entity. Used to update passenger orientation.
*/
@SideOnly(Side.CLIENT)
public void applyOrientationToEntity(Entity entityToUpdate)
{
}
/**
* Returns the Y Offset of this entity.
*/
public double getYOffset()
{
return 0.0D;
}
/**
* Returns the Y offset from the entity's position for any entity riding this one.
*/
public double getMountedYOffset()
{
return (double)this.height * 0.75D;
}
public boolean startRiding(Entity entityIn)
{
return this.startRiding(entityIn, false);
}
public boolean startRiding(Entity entityIn, boolean force)
{
for (Entity entity = entityIn; entity.ridingEntity != null; entity = entity.ridingEntity)
{
if (entity.ridingEntity == this)
{
return false;
}
}
if (!net.minecraftforge.event.ForgeEventFactory.canMountEntity(this, entityIn, true)) return false;
if (force || this.canBeRidden(entityIn) && entityIn.canFitPassenger(this))
{
if (this.isRiding())
{
this.dismountRidingEntity();
}
this.ridingEntity = entityIn;
this.ridingEntity.addPassenger(this);
return true;
}
else
{
return false;
}
}
protected boolean canBeRidden(Entity entityIn)
{
return this.rideCooldown <= 0;
}
/**
* Dismounts all entities riding this entity from this entity.
*/
public void removePassengers()
{
for (int i = this.riddenByEntities.size() - 1; i >= 0; --i)
{
((Entity)this.riddenByEntities.get(i)).dismountRidingEntity();
}
}
/**
* Dismounts this entity from the entity it is riding.
*/
public void dismountRidingEntity()
{
if (this.ridingEntity != null)
{
Entity entity = this.ridingEntity;
if (!net.minecraftforge.event.ForgeEventFactory.canMountEntity(this, entity, false)) return;
this.ridingEntity = null;
entity.removePassenger(this);
}
}
protected void addPassenger(Entity passenger)
{
if (passenger.getRidingEntity() != this)
{
throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)");
}
else
{
if (!this.world.isRemote && passenger instanceof EntityPlayer && !(this.getControllingPassenger() instanceof EntityPlayer))
{
this.riddenByEntities.add(0, passenger);
}
else
{
this.riddenByEntities.add(passenger);
}
}
}
protected void removePassenger(Entity passenger)
{
if (passenger.getRidingEntity() == this)
{
throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
}
else
{
this.riddenByEntities.remove(passenger);
passenger.rideCooldown = 60;
}
}
protected boolean canFitPassenger(Entity passenger)
{
return this.getPassengers().size() < 1;
}
/**
* Set the position and rotation values directly without any clamping.
*/
@SideOnly(Side.CLIENT)
public void setPositionAndRotationDirect(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean teleport)
{
this.setPosition(x, y, z);
this.setRotation(yaw, pitch);
}
public float getCollisionBorderSize()
{
return 0.0F;
}
/**
* returns a (normalized) vector of where this entity is looking
*/
public Vec3d getLookVec()
{
return this.getVectorForRotation(this.rotationPitch, this.rotationYaw);
}
/**
* returns the Entity's pitch and yaw as a Vec2f
*/
@SideOnly(Side.CLIENT)
public Vec2f getPitchYaw()
{
return new Vec2f(this.rotationPitch, this.rotationYaw);
}
@SideOnly(Side.CLIENT)
public Vec3d getForward()
{
return Vec3d.fromPitchYawVector(this.getPitchYaw());
}
/**
* Marks the entity as being inside a portal, activating teleportation logic in onEntityUpdate() in the following
* tick(s).
*/
public void setPortal(BlockPos pos)
{
if (this.timeUntilPortal > 0)
{
this.timeUntilPortal = this.getPortalCooldown();
}
else
{
if (!this.world.isRemote && !pos.equals(this.lastPortalPos))
{
this.lastPortalPos = new BlockPos(pos);
BlockPattern.PatternHelper blockpattern$patternhelper = Blocks.PORTAL.createPatternHelper(this.world, this.lastPortalPos);
double d0 = blockpattern$patternhelper.getForwards().getAxis() == EnumFacing.Axis.X ? (double)blockpattern$patternhelper.getFrontTopLeft().getZ() : (double)blockpattern$patternhelper.getFrontTopLeft().getX();
double d1 = blockpattern$patternhelper.getForwards().getAxis() == EnumFacing.Axis.X ? this.posZ : this.posX;
d1 = Math.abs(MathHelper.pct(d1 - (double)(blockpattern$patternhelper.getForwards().rotateY().getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE ? 1 : 0), d0, d0 - (double)blockpattern$patternhelper.getWidth()));
double d2 = MathHelper.pct(this.posY - 1.0D, (double)blockpattern$patternhelper.getFrontTopLeft().getY(), (double)(blockpattern$patternhelper.getFrontTopLeft().getY() - blockpattern$patternhelper.getHeight()));
this.lastPortalVec = new Vec3d(d1, d2, 0.0D);
this.teleportDirection = blockpattern$patternhelper.getForwards();
}
this.inPortal = true;
}
}
/**
* Return the amount of cooldown before this entity can use a portal again.
*/
public int getPortalCooldown()
{
return 300;
}
/**
* Updates the entity motion clientside, called by packets from the server
*/
@SideOnly(Side.CLIENT)
public void setVelocity(double x, double y, double z)
{
this.motionX = x;
this.motionY = y;
this.motionZ = z;
}
/**
* Handler for {@link World#setEntityState}
*/
@SideOnly(Side.CLIENT)
public void handleStatusUpdate(byte id)
{
}
/**
* Setups the entity to do the hurt animation. Only used by packets in multiplayer.
*/
@SideOnly(Side.CLIENT)
public void performHurtAnimation()
{
}
public Iterable<ItemStack> getHeldEquipment()
{
return EMPTY_EQUIPMENT;
}
public Iterable<ItemStack> getArmorInventoryList()
{
return EMPTY_EQUIPMENT;
}
public Iterable<ItemStack> getEquipmentAndArmor()
{
return Iterables.<ItemStack>concat(this.getHeldEquipment(), this.getArmorInventoryList());
}
public void setItemStackToSlot(EntityEquipmentSlot slotIn, ItemStack stack)
{
}
/**
* Returns true if the entity is on fire. Used by render to add the fire effect on rendering.
*/
public boolean isBurning()
{
boolean flag = this.world != null && this.world.isRemote;
return !this.isImmuneToFire && (this.fire > 0 || flag && this.getFlag(0));
}
public boolean isRiding()
{
return this.getRidingEntity() != null;
}
/**
* If at least 1 entity is riding this one
*/
public boolean isBeingRidden()
{
return !this.getPassengers().isEmpty();
}
/**
* Returns if this entity is sneaking.
*/
public boolean isSneaking()
{
return this.getFlag(1);
}
/**
* Sets the sneaking flag.
*/
public void setSneaking(boolean sneaking)
{
this.setFlag(1, sneaking);
}
/**
* Get if the Entity is sprinting.
*/
public boolean isSprinting()
{
return this.getFlag(3);
}
/**
* Set sprinting switch for Entity.
*/
public void setSprinting(boolean sprinting)
{
this.setFlag(3, sprinting);
}
public boolean isGlowing()
{
return this.glowing || this.world.isRemote && this.getFlag(6);
}
public void setGlowing(boolean glowingIn)
{
this.glowing = glowingIn;
if (!this.world.isRemote)
{
this.setFlag(6, this.glowing);
}
}
public boolean isInvisible()
{
return this.getFlag(5);
}
/**
* Only used by renderer in EntityLivingBase subclasses.
* Determines if an entity is visible or not to a specfic player, if the entity is normally invisible.
* For EntityLivingBase subclasses, returning false when invisible will render the entity semitransparent.
*/
@SideOnly(Side.CLIENT)
public boolean isInvisibleToPlayer(EntityPlayer player)
{
if (player.isSpectator())
{
return false;
}
else
{
Team team = this.getTeam();
return team != null && player != null && player.getTeam() == team && team.getSeeFriendlyInvisiblesEnabled() ? false : this.isInvisible();
}
}
@Nullable
public Team getTeam()
{
return this.world.getScoreboard().getPlayersTeam(this.getCachedUniqueIdString());
}
/**
* Returns whether this Entity is on the same team as the given Entity.
*/
public boolean isOnSameTeam(Entity entityIn)
{
return this.isOnScoreboardTeam(entityIn.getTeam());
}
/**
* Returns whether this Entity is on the given scoreboard team.
*/
public boolean isOnScoreboardTeam(Team teamIn)
{
return this.getTeam() != null ? this.getTeam().isSameTeam(teamIn) : false;
}
public void setInvisible(boolean invisible)
{
this.setFlag(5, invisible);
}
/**
* Returns true if the flag is active for the entity. Known flags: 0: burning; 1: sneaking; 2: unused; 3: sprinting;
* 4: unused; 5: invisible; 6: glowing; 7: elytra flying
*/
protected boolean getFlag(int flag)
{
return (((Byte)this.dataManager.get(FLAGS)).byteValue() & 1 << flag) != 0;
}
/**
* Enable or disable a entity flag, see getEntityFlag to read the know flags.
*/
protected void setFlag(int flag, boolean set)
{
byte b0 = ((Byte)this.dataManager.get(FLAGS)).byteValue();
if (set)
{
this.dataManager.set(FLAGS, Byte.valueOf((byte)(b0 | 1 << flag)));
}
else
{
this.dataManager.set(FLAGS, Byte.valueOf((byte)(b0 & ~(1 << flag))));
}
}
public int getAir()
{
return ((Integer)this.dataManager.get(AIR)).intValue();
}
public void setAir(int air)
{
this.dataManager.set(AIR, Integer.valueOf(air));
}
/**
* Called when a lightning bolt hits the entity.
*/
public void onStruckByLightning(EntityLightningBolt lightningBolt)
{
this.attackEntityFrom(DamageSource.LIGHTNING_BOLT, 5.0F);
++this.fire;
if (this.fire == 0)
{
this.setFire(8);
}
}
/**
* This method gets called when the entity kills another one.
*/
public void onKillEntity(EntityLivingBase entityLivingIn)
{
}
protected boolean pushOutOfBlocks(double x, double y, double z)
{
BlockPos blockpos = new BlockPos(x, y, z);
double d0 = x - (double)blockpos.getX();
double d1 = y - (double)blockpos.getY();
double d2 = z - (double)blockpos.getZ();
if (!this.world.collidesWithAnyBlock(this.getEntityBoundingBox()))
{
return false;
}
else
{
EnumFacing enumfacing = EnumFacing.UP;
double d3 = Double.MAX_VALUE;
if (!this.world.isBlockFullCube(blockpos.west()) && d0 < d3)
{
d3 = d0;
enumfacing = EnumFacing.WEST;
}
if (!this.world.isBlockFullCube(blockpos.east()) && 1.0D - d0 < d3)
{
d3 = 1.0D - d0;
enumfacing = EnumFacing.EAST;
}
if (!this.world.isBlockFullCube(blockpos.north()) && d2 < d3)
{
d3 = d2;
enumfacing = EnumFacing.NORTH;
}
if (!this.world.isBlockFullCube(blockpos.south()) && 1.0D - d2 < d3)
{
d3 = 1.0D - d2;
enumfacing = EnumFacing.SOUTH;
}
if (!this.world.isBlockFullCube(blockpos.up()) && 1.0D - d1 < d3)
{
d3 = 1.0D - d1;
enumfacing = EnumFacing.UP;
}
float f = this.rand.nextFloat() * 0.2F + 0.1F;
float f1 = (float)enumfacing.getAxisDirection().getOffset();
if (enumfacing.getAxis() == EnumFacing.Axis.X)
{
this.motionX = (double)(f1 * f);
this.motionY *= 0.75D;
this.motionZ *= 0.75D;
}
else if (enumfacing.getAxis() == EnumFacing.Axis.Y)
{
this.motionX *= 0.75D;
this.motionY = (double)(f1 * f);
this.motionZ *= 0.75D;
}
else if (enumfacing.getAxis() == EnumFacing.Axis.Z)
{
this.motionX *= 0.75D;
this.motionY *= 0.75D;
this.motionZ = (double)(f1 * f);
}
return true;
}
}
/**
* Sets the Entity inside a web block.
*/
public void setInWeb()
{
this.isInWeb = true;
this.fallDistance = 0.0F;
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
if (this.hasCustomName())
{
return this.getCustomNameTag();
}
else
{
String s = EntityList.getEntityString(this);
if (s == null)
{
s = "generic";
}
return I18n.translateToLocal("entity." + s + ".name");
}
}
/**
* Return the Entity parts making up this Entity (currently only for dragons)
*/
@Nullable
public Entity[] getParts()
{
return null;
}
/**
* Returns true if Entity argument is equal to this Entity
*/
public boolean isEntityEqual(Entity entityIn)
{
return this == entityIn;
}
public float getRotationYawHead()
{
return 0.0F;
}
/**
* Sets the head's yaw rotation of the entity.
*/
public void setRotationYawHead(float rotation)
{
}
/**
* Set the render yaw offset
*/
public void setRenderYawOffset(float offset)
{
}
/**
* Returns true if it's possible to attack this entity with an item.
*/
public boolean canBeAttackedWithItem()
{
return true;
}
/**
* Called when a player attacks an entity. If this returns true the attack will not happen.
*/
public boolean hitByEntity(Entity entityIn)
{
return false;
}
public String toString()
{
return String.format("%s['%s'/%d, l='%s', x=%.2f, y=%.2f, z=%.2f]", this.getClass().getSimpleName(), this.getName(), this.entityId, this.world == null ? "~NULL~" : this.world.getWorldInfo().getWorldName(), this.posX, this.posY, this.posZ);
}
/**
* Returns whether this Entity is invulnerable to the given DamageSource.
*/
public boolean isEntityInvulnerable(DamageSource source)
{
return this.invulnerable && source != DamageSource.OUT_OF_WORLD && !source.isCreativePlayer();
}
public boolean getIsInvulnerable()
{
return this.invulnerable;
}
/**
* Sets whether this Entity is invulnerable.
*/
public void setEntityInvulnerable(boolean isInvulnerable)
{
this.invulnerable = isInvulnerable;
}
/**
* Sets this entity's location and angles to the location and angles of the passed in entity.
*/
public void copyLocationAndAnglesFrom(Entity entityIn)
{
this.setLocationAndAngles(entityIn.posX, entityIn.posY, entityIn.posZ, entityIn.rotationYaw, entityIn.rotationPitch);
}
/**
* Prepares this entity in new dimension by copying NBT data from entity in old dimension
*/
private void copyDataFromOld(Entity entityIn)
{
NBTTagCompound nbttagcompound = entityIn.writeToNBT(new NBTTagCompound());
nbttagcompound.removeTag("Dimension");
this.readFromNBT(nbttagcompound);
this.timeUntilPortal = entityIn.timeUntilPortal;
this.lastPortalPos = entityIn.lastPortalPos;
this.lastPortalVec = entityIn.lastPortalVec;
this.teleportDirection = entityIn.teleportDirection;
}
@Nullable
public Entity changeDimension(int dimensionIn)
{
if (this.world.isRemote || this.isDead) return null;
return changeDimension(dimensionIn, this.getServer().getWorld(dimensionIn).getDefaultTeleporter());
}
@Nullable // Forge: Entities that require custom handling should override this method, not the other
public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter)
{
if (!this.world.isRemote && !this.isDead)
{
if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(this, dimensionIn)) return null;
this.world.profiler.startSection("changeDimension");
MinecraftServer minecraftserver = this.getServer();
int i = this.dimension;
WorldServer worldserver = minecraftserver.getWorld(i);
WorldServer worldserver1 = minecraftserver.getWorld(dimensionIn);
this.dimension = dimensionIn;
if (i == 1 && dimensionIn == 1 && teleporter.isVanilla())
{
worldserver1 = minecraftserver.getWorld(0);
this.dimension = 0;
}
this.world.removeEntity(this);
this.isDead = false;
this.world.profiler.startSection("reposition");
BlockPos blockpos;
if (dimensionIn == 1 && teleporter.isVanilla())
{
blockpos = worldserver1.getSpawnCoordinate();
}
else
{
double moveFactor = worldserver.provider.getMovementFactor() / worldserver1.provider.getMovementFactor();
double d0 = MathHelper.clamp(this.posX * moveFactor, worldserver1.getWorldBorder().minX() + 16.0D, worldserver1.getWorldBorder().maxX() - 16.0D);
double d1 = MathHelper.clamp(this.posZ * moveFactor, worldserver1.getWorldBorder().minZ() + 16.0D, worldserver1.getWorldBorder().maxZ() - 16.0D);
double d2 = 8.0D;
if (false && dimensionIn == -1)
{
d0 = MathHelper.clamp(d0 / 8.0D, worldserver1.getWorldBorder().minX() + 16.0D, worldserver1.getWorldBorder().maxX() - 16.0D);
d1 = MathHelper.clamp(d1 / 8.0D, worldserver1.getWorldBorder().minZ() + 16.0D, worldserver1.getWorldBorder().maxZ() - 16.0D);
}
else if (false && dimensionIn == 0)
{
d0 = MathHelper.clamp(d0 * 8.0D, worldserver1.getWorldBorder().minX() + 16.0D, worldserver1.getWorldBorder().maxX() - 16.0D);
d1 = MathHelper.clamp(d1 * 8.0D, worldserver1.getWorldBorder().minZ() + 16.0D, worldserver1.getWorldBorder().maxZ() - 16.0D);
}
d0 = (double)MathHelper.clamp((int)d0, -29999872, 29999872);
d1 = (double)MathHelper.clamp((int)d1, -29999872, 29999872);
float f = this.rotationYaw;
this.setLocationAndAngles(d0, this.posY, d1, 90.0F, 0.0F);
teleporter.placeEntity(worldserver1, this, f);
blockpos = new BlockPos(this);
}
worldserver.updateEntityWithOptionalForce(this, false);
this.world.profiler.endStartSection("reloading");
Entity entity = EntityList.newEntity(this.getClass(), worldserver1);
if (entity != null)
{
entity.copyDataFromOld(this);
if (i == 1 && dimensionIn == 1 && teleporter.isVanilla())
{
BlockPos blockpos1 = worldserver1.getTopSolidOrLiquidBlock(worldserver1.getSpawnPoint());
entity.moveToBlockPosAndAngles(blockpos1, entity.rotationYaw, entity.rotationPitch);
}
else
{
entity.moveToBlockPosAndAngles(blockpos, entity.rotationYaw, entity.rotationPitch);
}
boolean flag = entity.forceSpawn;
entity.forceSpawn = true;
worldserver1.spawnEntity(entity);
entity.forceSpawn = flag;
worldserver1.updateEntityWithOptionalForce(entity, false);
}
this.isDead = true;
this.world.profiler.endSection();
worldserver.resetUpdateEntityTick();
worldserver1.resetUpdateEntityTick();
this.world.profiler.endSection();
return entity;
}
else
{
return null;
}
}
/**
* Returns false if this Entity is a boss, true otherwise.
*/
public boolean isNonBoss()
{
return true;
}
/**
* Explosion resistance of a block relative to this entity
*/
public float getExplosionResistance(Explosion explosionIn, World worldIn, BlockPos pos, IBlockState blockStateIn)
{
return blockStateIn.getBlock().getExplosionResistance(worldIn, pos, this, explosionIn);
}
public boolean canExplosionDestroyBlock(Explosion explosionIn, World worldIn, BlockPos pos, IBlockState blockStateIn, float p_174816_5_)
{
return true;
}
/**
* The maximum height from where the entity is alowed to jump (used in pathfinder)
*/
public int getMaxFallHeight()
{
return 3;
}
public Vec3d getLastPortalVec()
{
return this.lastPortalVec;
}
public EnumFacing getTeleportDirection()
{
return this.teleportDirection;
}
/**
* Return whether this entity should NOT trigger a pressure plate or a tripwire.
*/
public boolean doesEntityNotTriggerPressurePlate()
{
return false;
}
public void addEntityCrashInfo(CrashReportCategory category)
{
category.addDetail("Entity Type", new ICrashReportDetail<String>()
{
public String call() throws Exception
{
return EntityList.getKey(Entity.this) + " (" + Entity.this.getClass().getCanonicalName() + ")";
}
});
category.addCrashSection("Entity ID", Integer.valueOf(this.entityId));
category.addDetail("Entity Name", new ICrashReportDetail<String>()
{
public String call() throws Exception
{
return Entity.this.getName();
}
});
category.addCrashSection("Entity's Exact location", String.format("%.2f, %.2f, %.2f", this.posX, this.posY, this.posZ));
category.addCrashSection("Entity's Block location", CrashReportCategory.getCoordinateInfo(MathHelper.floor(this.posX), MathHelper.floor(this.posY), MathHelper.floor(this.posZ)));
category.addCrashSection("Entity's Momentum", String.format("%.2f, %.2f, %.2f", this.motionX, this.motionY, this.motionZ));
category.addDetail("Entity's Passengers", new ICrashReportDetail<String>()
{
public String call() throws Exception
{
return Entity.this.getPassengers().toString();
}
});
category.addDetail("Entity's Vehicle", new ICrashReportDetail<String>()
{
public String call() throws Exception
{
return Entity.this.getRidingEntity().toString();
}
});
}
public void setUniqueId(UUID uniqueIdIn)
{
this.entityUniqueID = uniqueIdIn;
this.cachedUniqueIdString = this.entityUniqueID.toString();
}
/**
* Return whether this entity should be rendered as on fire.
*/
@SideOnly(Side.CLIENT)
public boolean canRenderOnFire()
{
return this.isBurning();
}
/**
* Returns the UUID of this entity.
*/
public UUID getUniqueID()
{
return this.entityUniqueID;
}
public String getCachedUniqueIdString()
{
return this.cachedUniqueIdString;
}
public boolean isPushedByWater()
{
return true;
}
@SideOnly(Side.CLIENT)
public static double getRenderDistanceWeight()
{
return renderDistanceWeight;
}
@SideOnly(Side.CLIENT)
public static void setRenderDistanceWeight(double renderDistWeight)
{
renderDistanceWeight = renderDistWeight;
}
/**
* Get the formatted ChatComponent that will be used for the sender's username in chat
*/
public ITextComponent getDisplayName()
{
TextComponentString textcomponentstring = new TextComponentString(ScorePlayerTeam.formatPlayerName(this.getTeam(), this.getName()));
textcomponentstring.getStyle().setHoverEvent(this.getHoverEvent());
textcomponentstring.getStyle().setInsertion(this.getCachedUniqueIdString());
return textcomponentstring;
}
/**
* Sets the custom name tag for this entity
*/
public void setCustomNameTag(String name)
{
this.dataManager.set(CUSTOM_NAME, name);
}
public String getCustomNameTag()
{
return (String)this.dataManager.get(CUSTOM_NAME);
}
/**
* Returns true if this thing is named
*/
public boolean hasCustomName()
{
return !((String)this.dataManager.get(CUSTOM_NAME)).isEmpty();
}
public void setAlwaysRenderNameTag(boolean alwaysRenderNameTag)
{
this.dataManager.set(CUSTOM_NAME_VISIBLE, Boolean.valueOf(alwaysRenderNameTag));
}
public boolean getAlwaysRenderNameTag()
{
return ((Boolean)this.dataManager.get(CUSTOM_NAME_VISIBLE)).booleanValue();
}
/**
* Sets the position of the entity and updates the 'last' variables
*/
public void setPositionAndUpdate(double x, double y, double z)
{
this.isPositionDirty = true;
this.setLocationAndAngles(x, y, z, this.rotationYaw, this.rotationPitch);
this.world.updateEntityWithOptionalForce(this, false);
}
public void notifyDataManagerChange(DataParameter<?> key)
{
}
@SideOnly(Side.CLIENT)
public boolean getAlwaysRenderNameTagForRender()
{
return this.getAlwaysRenderNameTag();
}
/**
* Gets the horizontal facing direction of this Entity.
*/
public EnumFacing getHorizontalFacing()
{
return EnumFacing.getHorizontal(MathHelper.floor((double)(this.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3);
}
/**
* Gets the horizontal facing direction of this Entity, adjusted to take specially-treated entity types into
* account.
*/
public EnumFacing getAdjustedHorizontalFacing()
{
return this.getHorizontalFacing();
}
protected HoverEvent getHoverEvent()
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
ResourceLocation resourcelocation = EntityList.getKey(this);
nbttagcompound.setString("id", this.getCachedUniqueIdString());
if (resourcelocation != null)
{
nbttagcompound.setString("type", resourcelocation.toString());
}
nbttagcompound.setString("name", this.getName());
return new HoverEvent(HoverEvent.Action.SHOW_ENTITY, new TextComponentString(nbttagcompound.toString()));
}
public boolean isSpectatedByPlayer(EntityPlayerMP player)
{
return true;
}
public AxisAlignedBB getEntityBoundingBox()
{
return this.boundingBox;
}
/**
* Gets the bounding box of this Entity, adjusted to take auxiliary entities into account (e.g. the tile contained
* by a minecart, such as a command block).
*/
@SideOnly(Side.CLIENT)
public AxisAlignedBB getRenderBoundingBox()
{
return this.getEntityBoundingBox();
}
public void setEntityBoundingBox(AxisAlignedBB bb)
{
this.boundingBox = bb;
}
public float getEyeHeight()
{
return this.height * 0.85F;
}
public boolean isOutsideBorder()
{
return this.isOutsideBorder;
}
public void setOutsideBorder(boolean outsideBorder)
{
this.isOutsideBorder = outsideBorder;
}
public boolean replaceItemInInventory(int inventorySlot, ItemStack itemStackIn)
{
return false;
}
/**
* Send a chat message to the CommandSender
*/
public void sendMessage(ITextComponent component)
{
}
/**
* Returns {@code true} if the CommandSender is allowed to execute the command, {@code false} if not
*/
public boolean canUseCommand(int permLevel, String commandName)
{
return true;
}
/**
* Get the position in the world. <b>{@code null} is not allowed!</b> If you are not an entity in the world, return
* the coordinates 0, 0, 0
*/
public BlockPos getPosition()
{
return new BlockPos(this.posX, this.posY + 0.5D, this.posZ);
}
/**
* Get the position vector. <b>{@code null} is not allowed!</b> If you are not an entity in the world, return 0.0D,
* 0.0D, 0.0D
*/
public Vec3d getPositionVector()
{
return new Vec3d(this.posX, this.posY, this.posZ);
}
/**
* Get the world, if available. <b>{@code null} is not allowed!</b> If you are not an entity in the world, return
* the overworld
*/
public World getEntityWorld()
{
return this.world;
}
/**
* Returns the entity associated with the command sender. MAY BE NULL!
*/
public Entity getCommandSenderEntity()
{
return this;
}
/**
* Returns true if the command sender should be sent feedback about executed commands
*/
public boolean sendCommandFeedback()
{
return false;
}
public void setCommandStat(CommandResultStats.Type type, int amount)
{
if (this.world != null && !this.world.isRemote)
{
this.cmdResultStats.setCommandStatForSender(this.world.getMinecraftServer(), this, type, amount);
}
}
/**
* Get the Minecraft server instance
*/
@Nullable
public MinecraftServer getServer()
{
return this.world.getMinecraftServer();
}
public CommandResultStats getCommandStats()
{
return this.cmdResultStats;
}
/**
* Set the CommandResultStats from the entity
*/
public void setCommandStats(Entity entityIn)
{
this.cmdResultStats.addAllStats(entityIn.getCommandStats());
}
/**
* Applies the given player interaction to this Entity.
*/
public EnumActionResult applyPlayerInteraction(EntityPlayer player, Vec3d vec, EnumHand hand)
{
return EnumActionResult.PASS;
}
public boolean isImmuneToExplosions()
{
return false;
}
protected void applyEnchantments(EntityLivingBase entityLivingBaseIn, Entity entityIn)
{
if (entityIn instanceof EntityLivingBase)
{
EnchantmentHelper.applyThornEnchantments((EntityLivingBase)entityIn, entityLivingBaseIn);
}
EnchantmentHelper.applyArthropodEnchantments(entityLivingBaseIn, entityIn);
}
/* ================================== Forge Start =====================================*/
/**
* Returns a NBTTagCompound that can be used to store custom data for this entity.
* It will be written, and read from disc, so it persists over world saves.
* @return A NBTTagCompound
*/
public NBTTagCompound getEntityData()
{
if (customEntityData == null)
{
customEntityData = new NBTTagCompound();
}
return customEntityData;
}
/**
* Used in model rendering to determine if the entity riding this entity should be in the 'sitting' position.
* @return false to prevent an entity that is mounted to this entity from displaying the 'sitting' animation.
*/
public boolean shouldRiderSit()
{
return true;
}
/**
* Called when a user uses the creative pick block button on this entity.
*
* @param target The full target the player is looking at
* @return A ItemStack to add to the player's inventory, empty ItemStack if nothing should be added.
*/
public ItemStack getPickedResult(RayTraceResult target)
{
if (this instanceof net.minecraft.entity.item.EntityPainting)
{
return new ItemStack(net.minecraft.init.Items.PAINTING);
}
else if (this instanceof EntityLeashKnot)
{
return new ItemStack(net.minecraft.init.Items.LEAD);
}
else if (this instanceof net.minecraft.entity.item.EntityItemFrame)
{
ItemStack held = ((net.minecraft.entity.item.EntityItemFrame)this).getDisplayedItem();
if (held.isEmpty())
{
return new ItemStack(net.minecraft.init.Items.ITEM_FRAME);
}
else
{
return held.copy();
}
}
else if (this instanceof net.minecraft.entity.item.EntityMinecart)
{
return ((net.minecraft.entity.item.EntityMinecart)this).getCartItem();
}
else if (this instanceof net.minecraft.entity.item.EntityBoat)
{
return new ItemStack(((EntityBoat)this).getItemBoat());
}
else if (this instanceof net.minecraft.entity.item.EntityArmorStand)
{
return new ItemStack(net.minecraft.init.Items.ARMOR_STAND);
}
else if (this instanceof net.minecraft.entity.item.EntityEnderCrystal)
{
return new ItemStack(net.minecraft.init.Items.END_CRYSTAL);
}
else
{
ResourceLocation name = EntityList.getKey(this);
if (name != null && EntityList.ENTITY_EGGS.containsKey(name))
{
ItemStack stack = new ItemStack(net.minecraft.init.Items.SPAWN_EGG);
net.minecraft.item.ItemMonsterPlacer.applyEntityIdToItemStack(stack, name);
return stack;
}
}
return ItemStack.EMPTY;
}
public UUID getPersistentID()
{
return entityUniqueID;
}
/**
* Reset the entity ID to a new value. Not to be used from Mod code
*/
@Deprecated // TODO: remove (1.13?)
public final void resetEntityId()
{
this.entityId = nextEntityID++;
}
public boolean shouldRenderInPass(int pass)
{
return pass == 0;
}
/**
* Returns true if the entity is of the @link{EnumCreatureType} provided
* @param type The EnumCreatureType type this entity is evaluating
* @param forSpawnCount If this is being invoked to check spawn count caps.
* @return If the creature is of the type provided
*/
public boolean isCreatureType(EnumCreatureType type, boolean forSpawnCount)
{
if (forSpawnCount && (this instanceof EntityLiving) && ((EntityLiving)this).isNoDespawnRequired()) return false;
return type.getCreatureClass().isAssignableFrom(this.getClass());
}
/**
* If a rider of this entity can interact with this entity. Should return true on the
* ridden entity if so.
*
* @return if the entity can be interacted with from a rider
*/
public boolean canRiderInteract()
{
return false;
}
/**
* If the rider should be dismounted from the entity when the entity goes under water
*
* @param rider The entity that is riding
* @return if the entity should be dismounted when under water
*/
public boolean shouldDismountInWater(Entity rider)
{
return this instanceof EntityLivingBase;
}
@Override
public boolean hasCapability(net.minecraftforge.common.capabilities.Capability<?> capability, @Nullable net.minecraft.util.EnumFacing facing)
{
return capabilities != null && capabilities.hasCapability(capability, facing);
}
@Override
@Nullable
public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable net.minecraft.util.EnumFacing facing)
{
return capabilities == null ? null : capabilities.getCapability(capability, facing);
}
public void deserializeNBT(NBTTagCompound nbt)
{
this.readFromNBT(nbt);
}
public NBTTagCompound serializeNBT()
{
NBTTagCompound ret = new NBTTagCompound();
ret.setString("id", this.getEntityString());
return this.writeToNBT(ret);
}
/**
* Checks if this {@link Entity} can trample a {@link Block}.
*
* @param world The world in which the block will be trampled
* @param block The block being tested
* @param pos The block pos
* @param fallDistance The fall distance
* @return {@code true} if this entity can trample, {@code false} otherwise
*/
public boolean canTrample(World world, Block block, BlockPos pos, float fallDistance)
{
return world.rand.nextFloat() < fallDistance - 0.5F
&& this instanceof EntityLivingBase
&& (this instanceof EntityPlayer || net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(world, this))
&& this.width * this.width * this.height > 0.512F;
}
/* ================================== Forge End =====================================*/
/**
* Add the given player to the list of players tracking this entity. For instance, a player may track a boss in
* order to view its associated boss bar.
*/
public void addTrackingPlayer(EntityPlayerMP player)
{
}
/**
* Removes the given player from the list of players tracking this entity. See {@link Entity#addTrackingPlayer} for
* more information on tracking.
*/
public void removeTrackingPlayer(EntityPlayerMP player)
{
}
/**
* Transforms the entity's current yaw with the given Rotation and returns it. This does not have a side-effect.
*/
public float getRotatedYaw(Rotation transformRotation)
{
float f = MathHelper.wrapDegrees(this.rotationYaw);
switch (transformRotation)
{
case CLOCKWISE_180:
return f + 180.0F;
case COUNTERCLOCKWISE_90:
return f + 270.0F;
case CLOCKWISE_90:
return f + 90.0F;
default:
return f;
}
}
/**
* Transforms the entity's current yaw with the given Mirror and returns it. This does not have a side-effect.
*/
public float getMirroredYaw(Mirror transformMirror)
{
float f = MathHelper.wrapDegrees(this.rotationYaw);
switch (transformMirror)
{
case LEFT_RIGHT:
return -f;
case FRONT_BACK:
return 180.0F - f;
default:
return f;
}
}
public boolean ignoreItemEntityData()
{
return false;
}
public boolean setPositionNonDirty()
{
boolean flag = this.isPositionDirty;
this.isPositionDirty = false;
return flag;
}
/**
* 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 null;
}
public List<Entity> getPassengers()
{
return (List<Entity>)(this.riddenByEntities.isEmpty() ? Collections.emptyList() : Lists.newArrayList(this.riddenByEntities));
}
public boolean isPassenger(Entity entityIn)
{
for (Entity entity : this.getPassengers())
{
if (entity.equals(entityIn))
{
return true;
}
}
return false;
}
/**
* Recursively collects the passengers of this entity. This differs from getPassengers() in that passengers of
* passengers are recursively collected.
*/
public Collection<Entity> getRecursivePassengers()
{
Set<Entity> set = Sets.<Entity>newHashSet();
this.getRecursivePassengersByType(Entity.class, set);
return set;
}
/**
* Recursively collects the passengers of this entity with type denoted by the given class.
*/
public <T extends Entity> Collection<T> getRecursivePassengersByType(Class<T> entityClass)
{
Set<T> set = Sets.<T>newHashSet();
this.getRecursivePassengersByType(entityClass, set);
return set;
}
/**
* Recursively collects the passengers of this entity with the type denoted by the given class into the given Set.
*/
private <T extends Entity> void getRecursivePassengersByType(Class<T> entityClass, Set<T> theSet)
{
for (Entity entity : this.getPassengers())
{
if (entityClass.isAssignableFrom(entity.getClass()))
{
theSet.add((T)entity);
}
entity.getRecursivePassengersByType(entityClass, theSet);
}
}
public Entity getLowestRidingEntity()
{
Entity entity;
for (entity = this; entity.isRiding(); entity = entity.getRidingEntity())
{
;
}
return entity;
}
public boolean isRidingSameEntity(Entity entityIn)
{
return this.getLowestRidingEntity() == entityIn.getLowestRidingEntity();
}
public boolean isRidingOrBeingRiddenBy(Entity entityIn)
{
for (Entity entity : this.getPassengers())
{
if (entity.equals(entityIn))
{
return true;
}
if (entity.isRidingOrBeingRiddenBy(entityIn))
{
return true;
}
}
return false;
}
public boolean canPassengerSteer()
{
Entity entity = this.getControllingPassenger();
if (entity instanceof EntityPlayer)
{
return ((EntityPlayer)entity).isUser();
}
else
{
return !this.world.isRemote;
}
}
/**
* Get entity this is riding
*/
@Nullable
public Entity getRidingEntity()
{
return this.ridingEntity;
}
public EnumPushReaction getPushReaction()
{
return EnumPushReaction.NORMAL;
}
public SoundCategory getSoundCategory()
{
return SoundCategory.NEUTRAL;
}
protected int getFireImmuneTicks()
{
return 1;
}
}