Solved Get blocks under player feet.

Discussion in 'Plugin Development' started by Shevchik, Aug 18, 2013.

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

    Shevchik

    I now that i can get block under player feet using player.getLocation().add(0,-1,0).getBlock()

    But player can stand on 4 blocks at a time and i need to get them all, is there a bukkit method for this?
     
  2. Offline

    CubieX

    Technically a player can only stand on one block at a time.
    But if he stands on the edge of a block or what you mean, stands on the intersection of 4 adjacent blocks,
    his "model" will occupy space within all 4 blocks at his feet (and head level also of course).

    There is no Bukkit method for this.
    But player.getLocation().getX() /Y()/Z() returns a double value.
    If you stand centered on a block with block coordinates 0/y/0, your location will be 0.5/y/0.5.
    If you stand on the edges of the block in x direction, it will be 0.000000 (or 0.0000..1 not sure...) or 0.9999999,
    but for the game, you are still standing within block coordinate 0/y/0, because those are integers.
    And the game will calculate effects that blocks have on the player (e.g. pushing him, blocking him, damaging him)
    by using the block coordinates.
    So you can build your own logic around that.

    An easier way would be, to select not 4 but 9 blocks. The one he is standing on,
    and the 8 blocks surrounding it.
    So you would not have to fiddle with double values.
    But if this makes sense depends on your application.

    Can you explain a bit what you are planning to do?
     
  3. Offline

    mbcx2

    player.getLocation().getBlock().getRelative(BlockFace.DOWN).getY() will give you the location of the block you are standing on, But I don't think it is possible to get the 4 blocks that you are standing on easily.
     
  4. Offline

    Shevchik

    TNTRun minigame plugin. Every block player steps on falls. But you can just stand on 4 blocks and plugin will delete only 1 and player won't fall, so i was searching for a fast method to get those 4 blocks.
     
  5. Offline

    Quantix

    Here's a method that will return all potential blocks the player could be standing on. If he's standing on one, it'll return an ArrayList of blocks with only 1 block (the one he's standing on) while if he's standing on four different blocks at once it'll return all 4. You can get the size() of the ArrayList my methods return to quickly find out how many blocks the player is standing on. I've posted the code below. There are two diferent methods, both have the same result but use a different method to arrive at that result. You'd have to test them to see which one is more efficient:
    Code:java
    1. public ArrayList<Block> getBlocksBelow(Player player) {
    2. ArrayList<Block> blocksBelow = new ArrayList<Block>();
    3. EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
    4. AxisAlignedBB boundingBox = entityPlayer.boundingBox;
    5. World world = player.getWorld();
    6. double yBelow = player.getLocation().getY() - 0.0001;
    7. Block northEast = new Location(world, boundingBox.d, yBelow, boundingBox.c).getBlock();
    8. Block northWest = new Location(world, boundingBox.a, yBelow, boundingBox.c).getBlock();
    9. Block southEast = new Location(world, boundingBox.d, yBelow, boundingBox.f).getBlock();
    10. Block southWest = new Location(world, boundingBox.a, yBelow, boundingBox.f).getBlock();
    11. Block[] blocks = {northEast, northWest, southEast, southWest};
    12. for (Block block : blocks) {
    13. if (!blocksBelow.isEmpty()) {
    14. boolean duplicateExists = false;
    15. for (int i = 0; i < blocksBelow.size(); i++) {
    16. if (blocksBelow.get(i).equals(block)) {
    17. duplicateExists = true;
    18. }
    19. }
    20. if (!duplicateExists) {
    21. blocksBelow.add(block);
    22. }
    23. } else {
    24. blocksBelow.add(block);
    25. }
    26. }
    27. return blocksBelow;
    28. }

    Here's the other method:
    Code:java
    1. public ArrayList<Block> getBlocksBelow(Player player) {
    2. ArrayList<Block> blocksBelow = new ArrayList<Block>();
    3. Location location = player.getLocation();
    4. double x = location.getX();
    5. double z = location.getZ();
    6. World world = player.getWorld();
    7. double yBelow = player.getLocation().getY() - 0.0001;
    8. Block northEast = new Location(world, x + 0.3, yBelow, z - 0.3).getBlock();
    9. Block northWest = new Location(world, x - 0.3, yBelow, z - 0.3).getBlock();
    10. Block southEast = new Location(world, x + 0.3, yBelow, z + 0.3).getBlock();
    11. Block southWest = new Location(world, x - 0.3, yBelow, z + 0.3).getBlock();
    12. Block[] blocks = {northEast, northWest, southEast, southWest};
    13. for (Block block : blocks) {
    14. if (!blocksBelow.isEmpty()) {
    15. boolean duplicateExists = false;
    16. for (int i = 0; i < blocksBelow.size(); i++) {
    17. if (blocksBelow.get(i).equals(block)) {
    18. duplicateExists = true;
    19. }
    20. }
    21. if (!duplicateExists) {
    22. blocksBelow.add(block);
    23. }
    24. } else {
    25. blocksBelow.add(block);
    26. }
    27. }
    28. return blocksBelow;
    29. }
    I can't guarantee that this will always work a 100% of the time (not sure what it does when standing in the middle of fences or other scenarios that could potentially cause strange results). These methods right now only return the blocks right below the players feet so if he jumps on flat ground and is in the air the methods will return air unless he lands on the ground again. If you don't want this and instead want it to return the blocks below even if he's not exactly above them, change the yBelow to:
    Code:java
    1. double yBelow = player.getLocation().getY() - 1;
    Hope this helped!
     
    _Flames1 and Shevchik like this.
  6. Offline

    Shevchik

    Thanks man, i slightly redone this to suite my needs.

    This will return Location of first nonAir block under player feet (use player.getLocation().add(0,-1,0) as argument to get it)
    Code:java
    1.  
    2. private Location getPlayerStandOnBlockLocation(Location locationUnderPlayer)
    3. {
    4. Location b11 = locationUnderPlayer.clone().add(0.3,0,-0.3);
    5. if (b11.getBlock().getType() != Material.AIR)
    6. {
    7. return b11;
    8. }
    9. Location b12 = locationUnderPlayer.clone().add(-0.3,0,-0.3);
    10. if (b12.getBlock().getType() != Material.AIR)
    11. {
    12. return b12;
    13. }
    14. Location b21 = locationUnderPlayer.clone().add(0.3,0,0.3);
    15. if (b21.getBlock().getType() != Material.AIR)
    16. {
    17. return b21;
    18. }
    19. Location b22 = locationUnderPlayer.clone().add(-0.3,0,+0.3);
    20. if (b22.getBlock().getType() != Material.AIR)
    21. {
    22. return b22;
    23. }
    24. return locationUnderPlayer;
    25. }
    26.  


    This is code is not optimal and can be written better, but i don't have time for this currently.
     
Thread Status:
Not open for further replies.

Share This Page