Skip to content

Instantly share code, notes, and snippets.

@Daomephsta
Created December 10, 2017 21:28
Show Gist options
  • Save Daomephsta/10bc4e485d85d89befc89ada10fc37d0 to your computer and use it in GitHub Desktop.
Save Daomephsta/10bc4e485d85d89befc89ada10fc37d0 to your computer and use it in GitHub Desktop.
Raytracing issues
public void fire(ItemStack stack, World world, EntityLivingBase shooter, EnumHand hand)
{
shooter.setActiveHand(hand);
Vec3d eyeVec = shooter.getPositionVector().addVector(0.0D, shooter.getEyeHeight(), 0.0D);
Vec3d targetVec = eyeVec.add(shooter.getLookVec().scale(maxRange));
if(pierceCount > 1) //Piercing
{
List<RayTraceResult> results = new ArrayList<>(pierceCount);
Helper.raytraceAll(results, world, shooter, eyeVec, targetVec);
if(results.isEmpty()) return;
//Sort the list in ascending order of distance from the shooter
results.sort((resultA, resultB) ->
{
double distanceA = resultA.hitVec.distanceTo(shooter.getPositionVector());
double distanceB = resultB.hitVec.distanceTo(shooter.getPositionVector());
return Double.compare(distanceA, distanceB);
});
//Truncate the list to contain only the results that will be pierced/hit
results = results.subList(0, Math.min(pierceCount, results.size()));
for(RayTraceResult result : results)
{
effect.apply(stack, world, shooter, result);
}
}
else //Non-piercing
{
RayTraceResult result = Helper.raytraceClosestObject(world, shooter, eyeVec, targetVec);
if(result != null) effect.apply(stack, world, shooter, result);
}
}
public static RayTraceResult raytraceClosestObject(World world, @Nullable Entity exclude, Vec3d startVec, Vec3d endVec)
{
RayTraceResult result = world.rayTraceBlocks(startVec, endVec);
double blockHitDistance = 0.0D; //The distance to the block that was hit
if(result != null) blockHitDistance = result.hitVec.distanceTo(startVec);
//Encloses the entire area where entities that could collide with this ray exist
AxisAlignedBB entitySearchArea = new AxisAlignedBB(startVec.xCoord, startVec.yCoord, startVec.zCoord, endVec.xCoord, endVec.yCoord, endVec.zCoord);
Entity hitEntity = null; //The closest entity that was hit
double entityHitDistance = 0.0D; //The squared distance to the closest entity that was hit
for(Entity entity : world.getEntitiesInAABBexcluding(exclude, entitySearchArea, EntitySelectors.NOT_SPECTATING))
{
world.spawnParticle(EnumParticleTypes.HEART, entity.posX, entity.posY + entity.height, entity.posZ, 0.0D, 0.0D, 0.0D);
//The collision AABB of the entity expanded by the collision border size
AxisAlignedBB collisionBB = entity.getEntityBoundingBox().expandXyz(entity.getCollisionBorderSize());
RayTraceResult intercept = collisionBB.calculateIntercept(startVec, endVec);
if(intercept != null)
{
double distance = startVec.distanceTo(intercept.hitVec);
if((distance < blockHitDistance || blockHitDistance == 0) && (distance < entityHitDistance || entityHitDistance == 0.0D))
{
entityHitDistance = distance;
hitEntity = entity;
world.spawnParticle(EnumParticleTypes.CRIT_MAGIC, entity.posX, entity.posY + entity.height, entity.posZ, 0.0D, 1.0D, 0.0D);
}
}
}
if(hitEntity != null) result = new RayTraceResult(hitEntity, hitEntity.getPositionVector());
return result;
}
public static void raytraceAll(List<RayTraceResult> results, World world, @Nullable Entity exclude, Vec3d startVec, Vec3d endVec)
{
RayTraceResult blockRaytrace = world.rayTraceBlocks(startVec, endVec);
if(blockRaytrace != null) results.add(blockRaytrace);
//Encloses the entire area where entities that could collide with this ray exist
AxisAlignedBB entitySearchArea = new AxisAlignedBB(startVec.xCoord, startVec.yCoord, startVec.zCoord, endVec.xCoord, endVec.yCoord, endVec.zCoord);
for(Entity entity : world.getEntitiesInAABBexcluding(exclude, entitySearchArea, EntitySelectors.NOT_SPECTATING))
{
world.spawnParticle(EnumParticleTypes.HEART, entity.posX, entity.posY + entity.height, entity.posZ, 0.0D, 0.0D, 0.0D);
//The collision AABB of the entity expanded by the collision border size
AxisAlignedBB collisionBB = entity.getEntityBoundingBox().expandXyz(entity.getCollisionBorderSize());
RayTraceResult intercept = collisionBB.calculateIntercept(startVec, endVec);
if(intercept != null) results.add(new RayTraceResult(entity, intercept.hitVec));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment