Find what way player is facing?

Discussion in 'Plugin Development' started by xGamingGeneration, May 23, 2011.

Thread Status:
Not open for further replies.
  1. So how can I find the direction of a player that does the /facing command (I know how o listen for the command) All I need is how can I find what ways he's facing (North,South,Etc.)
     
  2. I'm not sure if you need the exact BlockFace.NORTH etc, but you can use player.getLocation().getDirection() to get a vector which goes the same direction as the player
     
  3. Offline

    Shamebot

    Maybe:
    Code:
    Location ploc = player.getLocation();
    Location bloc = ploc.toVector().add(ploc.getDirection().normalize()).toLocation(ploc.getWorld());
    BlockFace face = ploc.getWorld().getBlockAt(ploc).getFace(ploc.getWorld().getBlockAt(bloc));
    But I'm merely guessing so...
     
  4. Offline

    FrozenBrain

    Have a look at a snippet from sk89qs' CommandBook plugin:
    Code:
    /**
         * Get the cardinal compass direction of a player.
         * 
         * @param player
         * @return
         */
        public static String getCardinalDirection(Player player) {
            double rot = (player.getLocation().getYaw() - 90) % 360;
            if (rot < 0) {
                rot += 360.0;
            }
            return getDirection(rot);
        }
    
        /**
         * Converts a rotation to a cardinal direction name.
         * 
         * @param rot
         * @return
         */
        private static String getDirection(double rot) {
            if (0 <= rot && rot < 22.5) {
                return "North";
            } else if (22.5 <= rot && rot < 67.5) {
                return "Northeast";
            } else if (67.5 <= rot && rot < 112.5) {
                return "East";
            } else if (112.5 <= rot && rot < 157.5) {
                return "Southeast";
            } else if (157.5 <= rot && rot < 202.5) {
                return "South";
            } else if (202.5 <= rot && rot < 247.5) {
                return "Southwest";
            } else if (247.5 <= rot && rot < 292.5) {
                return "West";
            } else if (292.5 <= rot && rot < 337.5) {
                return "Northwest";
            } else if (337.5 <= rot && rot < 360.0) {
                return "North";
            } else {
                return null;
            }
        }
     
  5. Offline

    DreadKyller

    the thing is @FrozenBrain : That would work, but the script above it would as well, plus it's more simpler
     
  6. Offline

    Shamebot

    If you refer to mine, I didn't try it and I'm not sure what happens if you're in the air because you'd get a null from getBlockAt() wouldn't you?
     
  7. Offline

    DreadKyller

    @Shamebot : Nope, blocks only return null over 127, otherwise they are just air blocks, but you can still get faces, and however, I tried your method and it worked 100%, I used both codes right after each other to print the direction, they both said same direction, only problem is seeing that a block has only 4 sides it only has north south west and east, no such stuff as south-east etc... but I think it would work for what he's thinking, IDK though.
     
  8. Offline

    Shamebot

    @DreadKyller
    I tested it myself and it isn't working well, I got a lot of NPEs and it wasn't very accurate either, but I got some NORTH_EAST and SOUTH_EAST.
    The NPEs should be caused by the calculated block not being next to the other, maybe using BlockVectors would solve this.

    Edit:The NPEs are rather due to BlockFace not having NORTH_DOWN,NORTH_UP,...
    but I couldn't figure out which component to set to 0, should be Y, shouldn't it?.
     
  9. Offline

    nisovin

    Less code != simpler. In my opinion, the code FrozenBrain posted is simpler, and easier to understand.
     
  10. Offline

    Shamebot

    True, but I'm lazy :D
     
  11. Offline

    DreadKyller

    @nisovin what's not simple about Shamebots' script, it gets the block in front of the player and gets the direction of the face in the same direction as the player, I mean FrozenBrains' script also handles the south-west and type stuff, but would be a slower code to operate. I tested both out, they gave the same answer, only Frozens' script lagged me over 15 times more that Shamebots' so if it's still effective, and creates less lag, I would personally use it, but to each their own preference.
     
  12. Offline

    nisovin

    You claim that the first method is simpler. However, that first method is actually much more complex than the second. The first method may only have three lines of code, but it uses a bunch of vector math, plus some getBlockAt() API calls. The second method just uses one line of math and an if/else block.

    Test Code (open)
    Code:
        public void runTests(Player player) {
    
            long startTime, totalTime;
    
            for (int i = 0; i < 10; i++) {
                    startTime = System.currentTimeMillis();
                    for (int j = 0; j < 10000; j++) {
                            method1(player);
                    }
                    totalTime = System.currentTimeMillis() - startTime;
                    System.out.println("method 1, interation " + i + ": " + totalTime + " ms");
            }
    
            for (int i = 0; i < 10; i++) {
                    startTime = System.currentTimeMillis();
                    for (int j = 0; j < 10000; j++) {
                            method2(player);
                    }
                    totalTime = System.currentTimeMillis() - startTime;
                    System.out.println("method 2, interation " + i + ": " + totalTime + " ms");
            }
    
    }
    
    public String method1(Player player) {
            Location ploc = player.getLocation();
            Location bloc = ploc.toVector().add(ploc.getDirection().normalize().setY(0)).toLocation(ploc.getWorld());
            BlockFace face = ploc.getWorld().getBlockAt(ploc).getFace(ploc.getWorld().getBlockAt(bloc));
            return face.toString();
    }
    
    public String method2(Player player) {
        double rot = (player.getLocation().getYaw() - 90) % 360;
            if (rot < 0) {
                    rot += 360.0;
            }
            return getDirection(rot);
    }
    
    private static String getDirection(double rot) {
            if (0 <= rot && rot < 22.5) {
                    return "North";
            } else if (22.5 <= rot && rot < 67.5) {
                    return "Northeast";
            } else if (67.5 <= rot && rot < 112.5) {
                    return "East";
            } else if (112.5 <= rot && rot < 157.5) {
                    return "Southeast";
            } else if (157.5 <= rot && rot < 202.5) {
                    return "South";
            } else if (202.5 <= rot && rot < 247.5) {
                    return "Southwest";
            } else if (247.5 <= rot && rot < 292.5) {
                    return "West";
            } else if (292.5 <= rot && rot < 337.5) {
                    return "Northwest";
            } else if (337.5 <= rot && rot < 360.0) {
                    return "North";
            } else {
                    return null;
            }
    }
    


    And here are the results:

    Results (open)

    17:04:02 [INFO] method 1, interation 0: 13 ms
    17:04:02 [INFO] method 1, interation 1: 10 ms
    17:04:02 [INFO] method 1, interation 2: 6 ms
    17:04:02 [INFO] method 1, interation 3: 6 ms
    17:04:02 [INFO] method 1, interation 4: 6 ms
    17:04:02 [INFO] method 1, interation 5: 7 ms
    17:04:02 [INFO] method 1, interation 6: 7 ms
    17:04:02 [INFO] method 1, interation 7: 7 ms
    17:04:02 [INFO] method 1, interation 8: 6 ms
    17:04:02 [INFO] method 1, interation 9: 6 ms
    17:04:02 [INFO] method 2, interation 0: 1 ms
    17:04:02 [INFO] method 2, interation 1: 2 ms
    17:04:02 [INFO] method 2, interation 2: 0 ms
    17:04:02 [INFO] method 2, interation 3: 0 ms
    17:04:02 [INFO] method 2, interation 4: 0 ms
    17:04:02 [INFO] method 2, interation 5: 0 ms
    17:04:02 [INFO] method 2, interation 6: 1 ms
    17:04:02 [INFO] method 2, interation 7: 1 ms
    17:04:02 [INFO] method 2, interation 8: 0 ms
    17:04:02 [INFO] method 2, interation 9: 0 ms

    17:04:20 [INFO] method 1, interation 0: 8 ms
    17:04:20 [INFO] method 1, interation 1: 8 ms
    17:04:20 [INFO] method 1, interation 2: 6 ms
    17:04:20 [INFO] method 1, interation 3: 7 ms
    17:04:20 [INFO] method 1, interation 4: 7 ms
    17:04:20 [INFO] method 1, interation 5: 7 ms
    17:04:20 [INFO] method 1, interation 6: 6 ms
    17:04:20 [INFO] method 1, interation 7: 6 ms
    17:04:20 [INFO] method 1, interation 8: 6 ms
    17:04:20 [INFO] method 1, interation 9: 6 ms
    17:04:20 [INFO] method 2, interation 0: 0 ms
    17:04:20 [INFO] method 2, interation 1: 0 ms
    17:04:20 [INFO] method 2, interation 2: 0 ms
    17:04:20 [INFO] method 2, interation 3: 0 ms
    17:04:20 [INFO] method 2, interation 4: 1 ms
    17:04:20 [INFO] method 2, interation 5: 0 ms
    17:04:20 [INFO] method 2, interation 6: 0 ms
    17:04:20 [INFO] method 2, interation 7: 0 ms
    17:04:20 [INFO] method 2, interation 8: 0 ms
    17:04:20 [INFO] method 2, interation 9: 0 ms

    17:04:36 [INFO] method 1, interation 0: 6 ms
    17:04:36 [INFO] method 1, interation 1: 7 ms
    17:04:36 [INFO] method 1, interation 2: 6 ms
    17:04:36 [INFO] method 1, interation 3: 6 ms
    17:04:36 [INFO] method 1, interation 4: 5 ms
    17:04:36 [INFO] method 1, interation 5: 6 ms
    17:04:36 [INFO] method 1, interation 6: 7 ms
    17:04:36 [INFO] method 1, interation 7: 7 ms
    17:04:36 [INFO] method 1, interation 8: 6 ms
    17:04:36 [INFO] method 1, interation 9: 6 ms
    17:04:36 [INFO] method 2, interation 0: 0 ms
    17:04:36 [INFO] method 2, interation 1: 0 ms
    17:04:36 [INFO] method 2, interation 2: 0 ms
    17:04:36 [INFO] method 2, interation 3: 0 ms
    17:04:36 [INFO] method 2, interation 4: 0 ms
    17:04:36 [INFO] method 2, interation 5: 1 ms
    17:04:36 [INFO] method 2, interation 6: 1 ms
    17:04:36 [INFO] method 2, interation 7: 0 ms
    17:04:36 [INFO] method 2, interation 8: 0 ms
    17:04:36 [INFO] method 2, interation 9: 0 ms


    As you can see, method 2 is consistently better than method 1. In fact, I couldn't even get method 2 to give any results besides 0 ms until I got it up to 10000 iterations, while method 1 had results greater than 0 ms at even 100 iterations.

    Edit: That was uncalled for, sorry. I removed the rude bits.
     
  13. Offline

    SnowGears

    I know I am replying to a really old thread but I was wondering if you could help me with something really quick. If I wanted to get the block I am facing I want to do this:

    if(player.getLocation().getBlock().getRelative(player.getLocation().getDirection()).getType()!=Material.AIR)

    But getRelative() for a vector does not exist... do you know how I could do this? Thanks
     
Thread Status:
Not open for further replies.

Share This Page