Calculate distance between a block and a player (location)

Discussion in 'Plugin Development' started by bergerkiller, Sep 27, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    bergerkiller

    I bet no one has an answer to this, but it's worth asking anyway. :)
    How can I get the distance between a player and a block, as in, hit-test distance. As if you point a laser distance pointer at the block and a readout of the distance appears. I got it till this:

    Code:
        public void onPlayerInteract(PlayerInteractEvent event) {
            Block b = event.getClickedBlock();
            if (b == null) b = event.getPlayer().getTargetBlock(null, 150);
            if (b != null) {
                //right/left clicked a sign
                //get location relative to the block
                Location l = event.getPlayer().getEyeLocation().subtract(b.getLocation());
                //distance between this location and the bounding box of the block
                net.minecraft.server.Block nb = net.minecraft.server.Block.byId[b.getTypeId()];
                double distance = ???;
    
                l = Util.move(event.getPlayer().getEyeLocation(), new Vector(0, 0, distance));
                l.getWorld().dropItem(l, new ItemStack(Material.GLASS, 1));
            }
        }
    I spawn a glass block at the pointed location to indicate correct distances. Any thoughts?
    The native block has min/max bounding values BTW, but this is far from being a distance...
    [​IMG]
    To make it clear: NOT location.distance; this has to do with the block's boundaries.
     
  2. Offline

    Taco

    Can't you use Location.distance(Location loc); ?
     
  3. Offline

    oyasunadev

    yeah you can do that.

    also you can:
    block.location - player.location
     
  4. Offline

    nisovin

    Yeah, it's as simple as:

    Code:
    event.getPlayer().getEyeLocation().distance(b.getLocation());
     
  5. Offline

    moose517

    watching this thread to see what others say. Anyways i did a quick google and was given this formula to get the distance
    [​IMG]

    P and Q represent the 2 locations to check the distance, each set being one of the coordinates

    EDIT: i guess i'm too slow and complicated LOLLOL
     
  6. Offline

    bergerkiller

    This includes the outsides of the block: hit detection. If location.distance did the job I wouldn't ask, but I have a 3D rectangle and a point, and I need to get the SMALLEST distance between the two. I could try and convert the scene into 2D and use a 2D formula if present, but it would be hard to get it into a 2D perspective.

    EDIT

    I am considering taking small leaps until I enter the rectangle (cuboid), and from then on take smaller and smaller leaps. Until someone has a different idea, that will be my method...although it is a bit slow.
     
  7. I don't know if you still want this, but If you create a vector you can do tons of fun stuff :D
     
  8. Offline

    bergerkiller

    Then I'd need to calculate the distance to all 8 lines (or bones) of the box, which is possible. Then I'd need to check for all 8 bones if they need to make another vector with another bone or not. No idea how to do that lol.

    Also, rotation not really important since I can translate the points.
     
  9. Offline

    oyasunadev

    I would suggest creating bones. This is in C++, probably wont help you, but give it a try. This is how FEAR does it: <Edit by Moderator: Redacted mediafire url>
     
    Last edited by a moderator: Nov 12, 2016
  10. Offline

    bergerkiller

    Any idea what .cpp file I need? Hard to look for the correct one.
    Also, I now use this. (it fails 80% of the time, but did proof accurate on blocks most of the time)
    Code:
        public void onPlayerInteract(PlayerInteractEvent event) {
            Block b = event.getClickedBlock();
            if (b == null) b = event.getPlayer().getTargetBlock(null, 150);
            if (b != null) {
                //right/left clicked a sign
                //get location relative to the block
                Location l = event.getPlayer().getEyeLocation().subtract(b.getLocation());
                //distance between this location and the bounding box of the block
                net.minecraft.server.Block nb = net.minecraft.server.Block.byId[b.getTypeId()];
                Cuboid c = new Cuboid();
                c.xMin = nb.minX;
                c.yMin = nb.minY;
                c.zMin = nb.minZ;
                c.xMax = nb.maxX;
                c.yMax = nb.maxY;
                c.zMax = nb.maxZ;
                //go closer until we reach destination
                //take a first major leap
                double distance = l.length() - c.length();
                l = Util.move(l, new Vector(0, 0, distance));
                System.out.println("d: " + distance);
                double factor = c.minlength();
                int maxi = 100;
                while (true) {
                    Location newl = Util.move(l, new Vector(0, 0, factor));
                    if (c.isIn(newl)) {
                        factor /= 2;
                    } else {
                        distance += factor;
                        l = newl;
                    }
                    if (factor < 0.1) break;
                    if (maxi == 0) break;
                    maxi--;
                }
    
                l = Util.move(event.getPlayer().getEyeLocation(), new Vector(0, 0, distance));
                l.getWorld().dropItem(l, new ItemStack(Material.GLASS, 1));
            }
        }
    Code:
        public class Cuboid {
            public double xMin, xMax, yMin, yMax, zMin, zMax;
    
            public boolean isIn(Location loc) {
                if (loc.getBlockX() < xMin) return false;
                if (loc.getBlockX() > xMax) return false;
                if (loc.getBlockY() < yMin) return false;
                if (loc.getBlockY() > yMax) return false;
                if (loc.getBlockZ() < zMin) return false;
                if (loc.getBlockZ() > zMax) return false;
                return true;
            }
    
            public double widthX() {
                return this.xMax - this.xMin;
            }
            public double widthY() {
                return this.yMax - this.yMin;
            }
            public double widthZ() {
                return this.zMax - this.zMin;
            }
            public double minlength() {
                double a = Math.min(widthX(), widthZ());
                return Math.min(widthZ(), a);
            }
            public double length() {
                double x = widthX();
                double y = widthY();
                double z = widthZ();
                return Math.sqrt(x * x + y * y + z * z);
            }
    
        }
     
  11. Offline

    oyasunadev

    nope havnt modified the sdk in years
     
Thread Status:
Not open for further replies.

Share This Page