Jump to content

Get entity being looked at


snow_56767
 Share

Recommended Posts

Hi guys,

    I am developing a mod that allows the player to use items on mobs from afar (things like they can insta-lasso the mob without getting to close)

I am currently having trouble with actually getting the mob though. I have tried using the rayTrace method (part of EntityLivingBase) but it never returns an entity.

It only ever returns a block position even though the player is clearly looking at the mob. I actually went so far as to bury my face in the mob and yet to no avail.

Is there a better way of doing this? (getting an entity being looked at) What am I doing wrong?

 

Thanks for helping :)

 

NOTE: I have searched the forums (both forge and minecraft forums) and found little to nothing. And minecraft doesn't exactly have documentation....

 

Some code for reference:

MovingObjectPosition mvObjPos = aPlayer.rayTrace(100D, 1F); // aPlayer is type EntityPlayer.

if (null == mvObjPos)
{
return aItemStack; // aItemStack is type ItemStack.
}
else
{
if (mvObjPos.entityHit instanceof EntityLiving)
        {
// -----------------It does continue on, I thought this would be sufficient though.----------------//

Link to comment
Share on other sites

Isn't there still a field for whatever the mouse is currently aiming at?

I know there used to be an MovingObjectPosition field inside the player object for that, I used it in 1.4/1.5 to draw info about the block or entity being looked at.

 

If you guys dont get it.. then well ya.. try harder...

Link to comment
Share on other sites

on the other hand you could make a coremods that increase the minimum interraction distance between you n the mobs so that the whole system takes care of that for your. the only thing is if you do that youll have to filter every other things to a smaller range (using event handlers)

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

Ok, I am currently trying to use world.getEntitiesWithinAABBExcludingEntity(Entity, AxisAlignBB) and player.canEntityBeSeen(Entity)

 

I am having a little trouble though with these, I'm not entirely sure what I'm doing because nothing is documented beyond simple, half-done dyoxygen comments. So I'm a little confused as to why it's not returning anything (an empty list). Here is the code:

 

// -- irrelevent stuff up here -- //
double nScalar = 50D;
Vec3 vLook = aPlayer.getLook(1F);
Vec3 vPos = aPlayer.getPosition(1F);
Vec3 vTarget = vPos.addVector(vLook.xCoord * nScalar, vLook.yCoord * nScalar, vLook.zCoord * nScalar);
List EntList = aWorld.getEntitiesWithinAABBExcludingEntity(null, AxisAlignedBB.getBoundingBox(vPos.xCoord, vPos.yCoord, vPos.zCoord, vTarget.xCoord, vTarget.yCoord, vTarget.zCoord));
// -- irrelevent stuff down here -- //

 

Also, why does rayTrace(double, float) not return any entities? That seems a little backward :/

Link to comment
Share on other sites

I have had to solve this issue myself awhile back -- I started by using the vanilla code for entity interaction, but extending the interaction range.

 

Essentially, it boils down to a roll-your-own ray-tracer with entity collision detection.  I have found many other uses for it since writing it.

 

you will need to determine the start and end points/vectors through some trig (take the players pitch, yaw, and x,y,z , offset for your desired 'search' length to get your tx coordinates)

 


/**
* 
* @param world
* @param x startX
* @param y startY
* @param z startZ
* @param tx endX
* @param ty endY
* @param tz endZ
* @param borderSize extra area to examine around line for entities
* @param excluded any excluded entities (the player, etc)
* @return a MovingObjectPosition of either the block hit (no entity hit), the entity hit (hit an entity), or null for nothing hit
*/
public static MovingObjectPosition tracePath(World world, float x, float y, float z, float tx, float ty, float tz, float borderSize, HashSet<Entity> excluded)
  {
  Vec3 startVec = Vec3.fakePool.getVecFromPool(x, y, z);
  Vec3 lookVec = Vec3.fakePool.getVecFromPool(tx-x, ty-y, tz-z);
  Vec3 endVec = Vec3.fakePool.getVecFromPool(tx, ty, tz);
  float minX = x < tx ? x : tx;
  float minY = y < ty ? y : ty;
  float minZ = z < tz ? z : tz;
  float maxX = x > tx ? x : tx;
  float maxY = y > ty ? y : ty; 
  float maxZ = z > tz ? z : tz;
  AxisAlignedBB bb = AxisAlignedBB.getAABBPool().getAABB(minX, minY, minZ, maxX, maxY, maxZ).expand(borderSize, borderSize, borderSize);
  List<Entity> allEntities = world.getEntitiesWithinAABBExcludingEntity(null, bb);  
  MovingObjectPosition blockHit = world.rayTraceBlocks(startVec, endVec);
  startVec = Vec3.fakePool.getVecFromPool(x, y, z);
  endVec = Vec3.fakePool.getVecFromPool(tx, ty, tz);
  float maxDistance = (float) endVec.distanceTo(startVec);
  if(blockHit!=null)
    {
    maxDistance = (float) blockHit.hitVec.distanceTo(startVec);
    }  
  Entity closestHitEntity = null;
  float closestHit = Float.POSITIVE_INFINITY;
  float currentHit = 0.f;
  AxisAlignedBB entityBb;// = ent.getBoundingBox();
  MovingObjectPosition intercept;
  for(Entity ent : allEntities)
    {    
    if(ent.canBeCollidedWith() && !excluded.contains(ent))
      {
      float entBorder =  ent.getCollisionBorderSize();
      entityBb = ent.boundingBox;
      if(entityBb!=null)
        {
        entityBb = entityBb.expand(entBorder, entBorder, entBorder);
        intercept = entityBb.calculateIntercept(startVec, endVec);
        if(intercept!=null)
          {
          currentHit = (float) intercept.hitVec.distanceTo(startVec);
          if(currentHit < closestHit || currentHit==0)
            {            
            closestHit = currentHit;
            closestHitEntity = ent;
            }
          } 
        }
      }
    }  
  if(closestHitEntity!=null)
    {
    blockHit = new MovingObjectPosition(closestHitEntity);
    }
  return blockHit;
  }

Link to comment
Share on other sites

  • 3 weeks later...

Thanks for the code, it was really useful!

I'd like to point out some things however:

 

1) This may not be an issue if you don't use this method too frequently, but you should only use the Vec3.fakePool for vectors that must be stored permanently. Use world.getWorldVec3Pool() to get short-lived vectors instead.

 

2) closestHit must be instantiated with maxDistance, not infinity. Otherwise you will always hit the entity when you are actually aiming at the block in front of it.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.