Commit 7739602fd6546d4b43a69637f0ddd53dc371bf2a

Authored by Mumfrey
1 parent 76707749

Add utility method for ray tracing including entities

src/main/java/com/mumfrey/liteloader/util/EntityUtilities.java
@@ -5,18 +5,132 @@ @@ -5,18 +5,132 @@
5 */ 5 */
6 package com.mumfrey.liteloader.util; 6 package com.mumfrey.liteloader.util;
7 7
  8 +import java.util.List;
  9 +
  10 +import com.google.common.base.Predicate;
  11 +import com.google.common.base.Predicates;
  12 +
8 import net.minecraft.entity.Entity; 13 import net.minecraft.entity.Entity;
  14 +import net.minecraft.util.EntitySelectors;
  15 +import net.minecraft.util.math.AxisAlignedBB;
9 import net.minecraft.util.math.RayTraceResult; 16 import net.minecraft.util.math.RayTraceResult;
10 import net.minecraft.util.math.Vec3d; 17 import net.minecraft.util.math.Vec3d;
11 18
12 public abstract class EntityUtilities 19 public abstract class EntityUtilities
13 { 20 {
14 - public static RayTraceResult rayTraceFromEntity(Entity entity, double traceDistance, float partialTicks) 21 + static final Predicate<Entity> TRACEABLE = Predicates.and(EntitySelectors.NOT_SPECTATING, new Predicate<Entity>()
  22 + {
  23 + @Override
  24 + public boolean apply(Entity entity)
  25 + {
  26 + return entity != null && entity.canBeCollidedWith();
  27 + }
  28 + });
  29 +
  30 + static final class EntityTrace
  31 + {
  32 + Entity entity;
  33 + Vec3d location;
  34 + double distance;
  35 +
  36 + EntityTrace(double entityDistance)
  37 + {
  38 + this.distance = entityDistance;
  39 + }
  40 +
  41 + RayTraceResult asRayTraceResult()
  42 + {
  43 + return new RayTraceResult(this.entity, this.location);
  44 + }
  45 + }
  46 +
  47 + public static RayTraceResult rayTraceFromEntity(Entity source, double traceDistance, float partialTicks, boolean includeEntities)
  48 + {
  49 + RayTraceResult blockRay = EntityUtilities.rayTraceFromEntity(source, traceDistance, partialTicks);
  50 +
  51 + if (!includeEntities)
  52 + {
  53 + return blockRay;
  54 + }
  55 +
  56 + Vec3d traceStart = EntityUtilities.getPositionEyes(source, partialTicks);
  57 + double blockDistance = (blockRay != null) ? blockRay.hitVec.distanceTo(traceStart) : traceDistance;
  58 + EntityTrace entityRay = EntityUtilities.rayTraceEntities(source, traceDistance, partialTicks, blockDistance, traceStart);
  59 +
  60 + if (entityRay.entity != null && (entityRay.distance < blockDistance || blockRay == null))
  61 + {
  62 + return entityRay.asRayTraceResult();
  63 + }
  64 +
  65 + return blockRay;
  66 + }
  67 +
  68 + private static EntityTrace rayTraceEntities(Entity source, double traceDistance, float partialTicks, double blockDistance, Vec3d traceStart)
  69 + {
  70 + EntityTrace trace = new EntityTrace(blockDistance);
  71 +
  72 + Vec3d lookDir = source.getLook(partialTicks).scale(traceDistance);
  73 + Vec3d traceEnd = traceStart.add(lookDir);
  74 +
  75 + for (final Entity entity : EntityUtilities.getTraceEntities(source, traceDistance, lookDir, EntityUtilities.TRACEABLE))
  76 + {
  77 + AxisAlignedBB entityBB = entity.getEntityBoundingBox().expandXyz(entity.getCollisionBorderSize());
  78 + RayTraceResult entityRay = entityBB.calculateIntercept(traceStart, traceEnd);
  79 +
  80 + if (entityBB.isVecInside(traceStart))
  81 + {
  82 + if (trace.distance >= 0.0D)
  83 + {
  84 + trace.entity = entity;
  85 + trace.location = entityRay == null ? traceStart : entityRay.hitVec;
  86 + trace.distance = 0.0D;
  87 + }
  88 + continue;
  89 + }
  90 +
  91 + if (entityRay == null)
  92 + {
  93 + continue;
  94 + }
  95 +
  96 + double distanceToEntity = traceStart.distanceTo(entityRay.hitVec);
  97 +
  98 + if (distanceToEntity < trace.distance || trace.distance == 0.0D)
  99 + {
  100 + if (entity.getLowestRidingEntity() == source.getLowestRidingEntity())
  101 + {
  102 + if (trace.distance == 0.0D)
  103 + {
  104 + trace.entity = entity;
  105 + trace.location = entityRay.hitVec;
  106 + }
  107 + }
  108 + else
  109 + {
  110 + trace.entity = entity;
  111 + trace.location = entityRay.hitVec;
  112 + trace.distance = distanceToEntity;
  113 + }
  114 + }
  115 + }
  116 +
  117 + return trace;
  118 + }
  119 +
  120 + private static List<Entity> getTraceEntities(Entity source, double traceDistance, Vec3d dir, Predicate<Entity> filter)
  121 + {
  122 + AxisAlignedBB boundingBox = source.getEntityBoundingBox();
  123 + AxisAlignedBB traceBox = boundingBox.addCoord(dir.xCoord, dir.yCoord, dir.zCoord);
  124 + List<Entity> entities = source.worldObj.getEntitiesInAABBexcluding(source, traceBox.expand(1.0F, 1.0F, 1.0F), filter);
  125 + return entities;
  126 + }
  127 +
  128 + public static RayTraceResult rayTraceFromEntity(Entity source, double traceDistance, float partialTicks)
15 { 129 {
16 - Vec3d var4 = EntityUtilities.getPositionEyes(entity, partialTicks);  
17 - Vec3d var5 = entity.getLook(partialTicks);  
18 - Vec3d var6 = var4.addVector(var5.xCoord * traceDistance, var5.yCoord * traceDistance, var5.zCoord * traceDistance);  
19 - return entity.worldObj.rayTraceBlocks(var4, var6, false, false, true); 130 + Vec3d traceStart = EntityUtilities.getPositionEyes(source, partialTicks);
  131 + Vec3d lookDir = source.getLook(partialTicks).scale(traceDistance);
  132 + Vec3d traceEnd = traceStart.add(lookDir);
  133 + return source.worldObj.rayTraceBlocks(traceStart, traceEnd, false, false, true);
20 } 134 }
21 135
22 public static Vec3d getPositionEyes(Entity entity, float partialTicks) 136 public static Vec3d getPositionEyes(Entity entity, float partialTicks)