Skip to content

Instantly share code, notes, and snippets.

@TheGreyGhost
Created August 14, 2015 23:13
Show Gist options
  • Save TheGreyGhost/db79ee859f15a9c238c3 to your computer and use it in GitHub Desktop.
Save TheGreyGhost/db79ee859f15a9c238c3 to your computer and use it in GitHub Desktop.
RayTraceServer - which block is player pointing at
package info.ata4.minecraft.dragon.server.util;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.entity.passive.EntityTameable;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import java.util.List;
/**
* Created by TGG on 8/07/2015.
*/
public class RayTraceServer
{
/**
* Find what the player is looking at (block or entity), up to a maximum range
* based on code from EntityRenderer.getMouseOver
* Will not target entities which are tamed by the player
* @return the block or entity that the player is looking at / targeting with their cursor. null if no collision
*/
public static MovingObjectPosition getMouseOver(World world, EntityPlayerSP entityPlayerSP, float maxDistance) {
final float PARTIAL_TICK = 1.0F;
Vec3 positionEyes = entityPlayerSP.getPositionEyes(PARTIAL_TICK);
Vec3 lookDirection = entityPlayerSP.getLook(PARTIAL_TICK);
Vec3 endOfLook = positionEyes.addVector(lookDirection.xCoord * maxDistance,
lookDirection.yCoord * maxDistance,
lookDirection.zCoord * maxDistance);
final boolean STOP_ON_LIQUID = true;
final boolean IGNORE_BOUNDING_BOX = false;
final boolean RETURN_NULL_IF_NO_COLLIDE = true;
MovingObjectPosition targetedBlock = world.rayTraceBlocks(positionEyes, endOfLook,
STOP_ON_LIQUID, IGNORE_BOUNDING_BOX,
!RETURN_NULL_IF_NO_COLLIDE);
double collisionDistanceSQ = maxDistance * maxDistance;
if (targetedBlock != null) {
collisionDistanceSQ = targetedBlock.hitVec.squareDistanceTo(positionEyes);
endOfLook = targetedBlock.hitVec;
}
final float EXPAND_SEARCH_BOX_BY = 1.0F;
AxisAlignedBB searchBox = entityPlayerSP.getEntityBoundingBox();
Vec3 endOfLookDelta = endOfLook.subtract(positionEyes);
searchBox = searchBox.addCoord(endOfLookDelta.xCoord, endOfLookDelta.yCoord, endOfLookDelta.zCoord);
searchBox = searchBox.expand(EXPAND_SEARCH_BOX_BY, EXPAND_SEARCH_BOX_BY, EXPAND_SEARCH_BOX_BY);
List<Entity> nearbyEntities = (List<Entity>) world.getEntitiesWithinAABBExcludingEntity(
entityPlayerSP, searchBox);
Entity closestEntityHit = null;
double closestEntityDistanceSQ = Double.MAX_VALUE;
for (Entity entity : nearbyEntities) {
if (!entity.canBeCollidedWith() || entity == entityPlayerSP.ridingEntity) {
continue;
}
if (entity instanceof EntityTameable) {
EntityTameable tamedEntity = (EntityTameable)entity;
if (tamedEntity.isOwner(entityPlayerSP)) {
continue;
}
}
float collisionBorderSize = entity.getCollisionBorderSize();
AxisAlignedBB axisalignedbb = entity.getEntityBoundingBox()
.expand(collisionBorderSize, collisionBorderSize, collisionBorderSize);
MovingObjectPosition movingobjectposition = axisalignedbb.calculateIntercept(positionEyes, endOfLook);
if (axisalignedbb.isVecInside(endOfLook)) {
double distanceSQ = (movingobjectposition == null) ? positionEyes.squareDistanceTo(endOfLook)
: positionEyes.squareDistanceTo(movingobjectposition.hitVec);
if (distanceSQ <= closestEntityDistanceSQ) {
closestEntityDistanceSQ = distanceSQ;
closestEntityHit = entity;
}
} else if (movingobjectposition != null) {
double distanceSQ = positionEyes.squareDistanceTo(movingobjectposition.hitVec);
if (distanceSQ <= closestEntityDistanceSQ) {
closestEntityDistanceSQ = distanceSQ;
closestEntityHit = entity;
}
}
}
if (closestEntityDistanceSQ <= collisionDistanceSQ) {
assert (closestEntityHit != null);
return new MovingObjectPosition(closestEntityHit, closestEntityHit.getPositionVector());
}
return targetedBlock;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment