6
\$\begingroup\$

I am currently making a mod for Minecraft but I have come to a stop because I am lacking in some knowledge. I need to get data for the entity I am looking at, which I believe requires the use vectors, something I don't really know how to use.

How would I achieve this? Some stuff that I think could help are mc.thePlayer.getLookVector() which returns the normalized vector of the user and mc.theWorld.loadedEntityList, which is a List with all the loaded currently loaded entities.

\$\endgroup\$
  • \$\begingroup\$ Isn't is possible to simply get the block which is x,y,z blocks away given the vector? \$\endgroup\$ – OmniOwl Jul 28 '13 at 17:11
  • \$\begingroup\$ To avoid an XY problem can you briefly explain what you're trying to solve by doing this? Maybe there's a simpler mechanic to get the result you want. \$\endgroup\$ – WildWeazel Jul 29 '13 at 21:35
3
\$\begingroup\$

Using Existing Methods/Variables

Since you are making a mod for Minecraft, and judging by the naming scheme of the methods you mentioned, I would suggest looking into the methods EntityRenderer.getMouseOver() and EntityLivingBase.rayTrace() (getMouseOver() uses it, and you can access the method by using mc.renderViewEntity.rayTrace()).

Also mc.objectMouseOver (an instance of MovingObjectPosition) may interest you. It is the variable set by using EntityRenderer.getMouseOver(). The MovingObjectPosition class has a field of type EnumMovingObjectType and also a field of type Entity. The former may be able to help you, but I'm pretty sure the latter is the field that you would be more interested in, seeing as if you are pointing at an entity, that would be the entity within range.

Re-implementing or modifying the methods

Aside from that, you could re-implement/modify the ray tracing clip that the game already uses to find whatever object you are pointing at and make the range of the trace larger (currently looks to be the range in which you can touch/hit blocks) and also filter out all non-entities, however I do not know how much work this would require, and there are several layers of methods you may need to duplicate the effects of.

\$\endgroup\$
3
\$\begingroup\$

Here is how it's accomplished for the IngameInfo mod (my code): https://github.com/bspkrs/IngameInfo/blob/master/src/net/minecraft/src/mod_IngameInfo.java#L968

MovingObjectPosition objectMouseOver = mc.objectMouseOver;
if (objectMouseOver != null)
{
    if (objectMouseOver.typeOfHit == EnumMovingObjectType.ENTITY)
    {
        return objectMouseOver.entityHit.getEntityName();
    }
    else if (objectMouseOver.typeOfHit == EnumMovingObjectType.TILE)
    {
        Block block = Block.blocksList[world.getBlockId(objectMouseOver.blockX, objectMouseOver.blockY, objectMouseOver.blockZ)];
        if (block != null)
        {
            ItemStack pickBlock = block.getPickBlock(objectMouseOver, world, objectMouseOver.blockX, objectMouseOver.blockY, objectMouseOver.blockZ);
            if (pickBlock != null)
            {
                return pickBlock.getDisplayName();
            }
            return block.getLocalizedName();
        }
    }
}

This example returns the name of the Entity or Block the player is currently looking at.

\$\endgroup\$
  • 3
    \$\begingroup\$ This is practically a code only answer. You should add comments to your code, or explain the algorithm in words. \$\endgroup\$ – MichaelHouse Oct 2 '13 at 21:25
0
\$\begingroup\$

Here's a solution for 1.7.2. I also wanted to "recognise" an entity.

Minecraft mc = Minecraft.getMinecraft();
MovingObjectPosition objectMouseOver = mc.objectMouseOver;
// makes a variable for where you look
if(mc.objectMouseOver != null && mc.objectMouseOver.entityHit != null) {
    // checks if you hit an Entity
    Entity Target = objectMouseOver.entityHit;
    // make a variable: Target(just so I can use it easier) AND makes it "select the Entity"
    if(Target instanceof EntityLiving) /* or whatever you want recognised */ {
        // < Your operation >
    }
}

Just change < Your operation > appropriately.

\$\endgroup\$
0
\$\begingroup\$

Personally, I needed something with a little longer range than the default when I needed this. If that's the case for you too, I pretty much copied getMouseOver(), changing a few variables and names to get what I needed. Here's the original:

public void getMouseOver(float par1)
{
    if (this.mc.renderViewEntity != null)
    {
        if (this.mc.theWorld != null)
        {
            this.mc.pointedEntity = null;
            double d0 = (double)this.mc.playerController.getBlockReachDistance();
            this.mc.objectMouseOver = this.mc.renderViewEntity.rayTrace(d0, par1);
            double d1 = d0;
            Vec3 vec3 = this.mc.renderViewEntity.getPosition(par1);

            if (this.mc.playerController.extendedReach())
            {
                d0 = 6.0D;
                d1 = 6.0D;
            }
            else
            {
                if (d0 > 3.0D)
                {
                    d1 = 3.0D;
                }

                d0 = d1;
            }

            if (this.mc.objectMouseOver != null)
            {
                d1 = this.mc.objectMouseOver.hitVec.distanceTo(vec3);
            }

            Vec3 vec31 = this.mc.renderViewEntity.getLook(par1);
            Vec3 vec32 = vec3.addVector(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0);
            this.pointedEntity = null;
            Vec3 vec33 = null;
            float f1 = 1.0F;
            List list = this.mc.theWorld.getEntitiesWithinAABBExcludingEntity(this.mc.renderViewEntity, this.mc.renderViewEntity.boundingBox.addCoord(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0).expand((double)f1, (double)f1, (double)f1));
            double d2 = d1;

            for (int i = 0; i < list.size(); ++i)
            {
                Entity entity = (Entity)list.get(i);

                if (entity.canBeCollidedWith())
                {
                    float f2 = entity.getCollisionBorderSize();
                    AxisAlignedBB axisalignedbb = entity.boundingBox.expand((double)f2, (double)f2, (double)f2);
                    MovingObjectPosition movingobjectposition = axisalignedbb.calculateIntercept(vec3, vec32);

                    if (axisalignedbb.isVecInside(vec3))
                    {
                        if (0.0D < d2 || d2 == 0.0D)
                        {
                            this.pointedEntity = entity;
                            vec33 = movingobjectposition == null ? vec3 : movingobjectposition.hitVec;
                            d2 = 0.0D;
                        }
                    }
                    else if (movingobjectposition != null)
                    {
                        double d3 = vec3.distanceTo(movingobjectposition.hitVec);

                        if (d3 < d2 || d2 == 0.0D)
                        {
                            if (entity == this.mc.renderViewEntity.ridingEntity && !entity.canRiderInteract())
                            {
                                if (d2 == 0.0D)
                                {
                                    this.pointedEntity = entity;
                                    vec33 = movingobjectposition.hitVec;
                                }
                            }
                            else
                            {
                                this.pointedEntity = entity;
                                vec33 = movingobjectposition.hitVec;
                                d2 = d3;
                            }
                        }
                    }
                }
            }

            if (this.pointedEntity != null && (d2 < d1 || this.mc.objectMouseOver == null))
            {
                this.mc.objectMouseOver = new MovingObjectPosition(this.pointedEntity, vec33);

                if (this.pointedEntity instanceof EntityLivingBase || this.pointedEntity instanceof EntityItemFrame)
                {
                    this.mc.pointedEntity = this.pointedEntity;
                }
            }
        }

I put this all in it's own method, making float par1 an argument (which has something to do with ticks, put 1.0F) and how far away you want to look, which is double d0. I subtracted the if-else loop that changes d0 and d1 according to player reach (4.5 survival, 6.0 creative), and used the mc object in my class. Here's my modified version, which returns the EntityLivingBase that the cursor is on:

private EntityLivingBase getTarget(float par1, double distance)
{
    Minecraft mc = Minecraft.getMinecraft();

    Entity pointedEntity;
    double d0 = distance;
    MovingObjectPosition omo = mc.renderViewEntity.rayTrace(d0, par1);
    double d1 = d0;
    Vec3 vec3 = mc.renderViewEntity.getPosition(par1);
    Vec3 vec31 = mc.renderViewEntity.getLook(par1);
    Vec3 vec32 = vec3.addVector(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0);
    pointedEntity = null;
    Vec3 vec33 = null;
    float f1 = 1.0F;
    List list = mc.theWorld.getEntitiesWithinAABBExcludingEntity(mc.renderViewEntity, mc.renderViewEntity.boundingBox.addCoord(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0).expand((double)f1, (double)f1, (double)f1));
    double d2 = d1;

    for (int i = 0; i < list.size(); ++i)
    {
        Entity entity = (Entity)list.get(i);

        if (entity.canBeCollidedWith())
        {
            float f2 = entity.getCollisionBorderSize();
            AxisAlignedBB axisalignedbb = entity.boundingBox.expand((double)f2, (double)f2, (double)f2);
            MovingObjectPosition movingobjectposition = axisalignedbb.calculateIntercept(vec3, vec32);

            if (axisalignedbb.isVecInside(vec3))
            {
                if (0.0D < d2 || d2 == 0.0D)
                {
                    pointedEntity = entity;
                    vec33 = movingobjectposition == null ? vec3 : movingobjectposition.hitVec;
                    d2 = 0.0D;
                }
            }
            else if (movingobjectposition != null)
            {
                double d3 = vec3.distanceTo(movingobjectposition.hitVec);

                if (d3 < d2 || d2 == 0.0D)
                {
                    if (entity == mc.renderViewEntity.ridingEntity && !entity.canRiderInteract())
                    {
                        if (d2 == 0.0D)
                        {
                            pointedEntity = entity;
                            vec33 = movingobjectposition.hitVec;
                        }
                    }
                    else
                    {
                        pointedEntity = entity;
                        vec33 = movingobjectposition.hitVec;
                        d2 = d3;
                    }
                }
            }
        }
    }
    if (pointedEntity != null && (d2 < d1 || omo == null))
    {
        omo = new MovingObjectPosition(pointedEntity, vec33);

        if (pointedEntity instanceof EntityLivingBase || pointedEntity instanceof EntityItemFrame)
        {
            mc.pointedEntity = pointedEntity;
        }
    }
    if (omo != null)
    {
        if (omo.typeOfHit == MovingObjectType.ENTITY)
        {
            if(omo.entityHit instanceof EntityLivingBase)
            {
                return (EntityLivingBase)omo.entityHit;
            }
        }
    }
    return null;
}

Hope this helps, and good luck with your mod.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.