package slimeknights.tconstruct.library.utils;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import java.util.List;
public final class EntityUtil {
private EntityUtil() {
}
public static RayTraceResult raytraceEntityPlayerLook(EntityPlayer player, float range) {
Vec3d eye = new Vec3d(player.posX, player.posY + (double) player.getEyeHeight(), player.posZ); // Entity.getPositionEyes
Vec3d look = player.getLook(1.0f);
return raytraceEntity(player, eye, look, range, true);
}
// based on EntityRenderer.getMouseOver
public static RayTraceResult raytraceEntity(Entity entity, Vec3d start, Vec3d look, double range, boolean ignoreCanBeCollidedWith) {
//Vec3 look = entity.getLook(partialTicks);
Vec3d direction = start.addVector(look.xCoord * range, look.yCoord * range, look.zCoord * range);
//Vec3 direction = vec3.addVector(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0);
Entity pointedEntity = null;
Vec3d hit = null;
AxisAlignedBB bb = entity.getEntityBoundingBox().addCoord(look.xCoord * range, look.yCoord * range, look.zCoord * range).expand(1, 1, 1);
@SuppressWarnings("unchecked")
List<Entity> entitiesInArea = entity.getEntityWorld().getEntitiesWithinAABBExcludingEntity(entity, bb);
double range2 = range; // range to the current candidate. Used to find the closest entity.
for(Entity candidate : entitiesInArea) {
if(ignoreCanBeCollidedWith || candidate.canBeCollidedWith()) {
// does our vector go through the entity?
double colBorder = candidate.getCollisionBorderSize();
AxisAlignedBB entityBB = candidate.getEntityBoundingBox().expand(colBorder, colBorder, colBorder);
RayTraceResult movingobjectposition = entityBB.calculateIntercept(start, direction);
// needs special casing: vector starts inside the entity
if(entityBB.isVecInside(start)) {
if(0.0D < range2 || range2 == 0.0D) {
pointedEntity = candidate;
hit = movingobjectposition == null ? start : movingobjectposition.hitVec;
range2 = 0.0D;
}
}
else if(movingobjectposition != null) {
double dist = start.distanceTo(movingobjectposition.hitVec);
if(dist < range2 || range2 == 0.0D) {
if(candidate == entity.getRidingEntity() && !entity.canRiderInteract()) {
if(range2 == 0.0D) {
pointedEntity = candidate;
hit = movingobjectposition.hitVec;
}
}
else {
pointedEntity = candidate;
hit = movingobjectposition.hitVec;
range2 = dist;
}
}
}
}
}
if(pointedEntity != null && range2 < range) {
return new RayTraceResult(pointedEntity, hit);
}
return null;
}
}