Solved Check if a Player move trough a Block?

Discussion in 'Plugin Development' started by Uniclaw, Dec 15, 2012.

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

    Uniclaw

    Hi!

    How can i check if a player is moving trough a block?

    I've tryed this: (in a move event)
    Code:
    public boolean hasReach(Location loc){
    for(Location l : plugin.sL){
    //System.out.println(l);
    if(loc.distance(l) <= 0.5){
    return true;
    }else{
    return false;
    }
    }
    return false;
    }
    With the value "0.5", nothing happens. But if i change the 0.5 to 1, that what i would do is fired three times!

    And with
    if(l.getBlock().getLocation().distance(loc.getBlock().getLocation()) == 0.0)
    its executed 4times..

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  2. Offline

    Cybermaxke

    Something like this?
    Code:
    if (!player.getLocation().getBlock().getType().equals(Material.AIR)) {
        //Code 
    }
     
  3. Offline

    Uniclaw

    No, not really :( Because i must check if its a specified block from a arraylist, but if i just check the locations, my code is fired 3-5 times..

    Anyone :( ?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  4. Offline

    Barinade

    Check the player's location compared to the blocks location on your list?
     
  5. Offline

    Uniclaw

    Barinade Read my post :p If i do that, the thing what i would do is fired 3-5 times..
     
  6. Offline

    Barinade

    Don't check if he's within .5 blocks of it, check and see if he is in it
     
  7. Offline

    fireblast709

    Uniclaw post more of the code, it might be a bug in the caller code (as this code always is executed once internally)
     
  8. Offline

    Barinade

    Code:
                                                        Block[] b = null;
                                                        Player pl = null;
                                                        for (Block b2 : b) {
                                                            if (pl.getLocation() == b2.getLocation()) {
                                                                //do things
                                                            }
                                                        }
    Just fill in the blanks
     
  9. Offline

    Likaos

    First, do you really need that precision ?

    What I would do:

    Code:
    @EventHandler(ignoreCancelled = true)
        public void onPlayerMove(PlayerMoveEvent event) {
         
            //Doesn't fire if it's not a block change
            if (event.getFrom().getBlock() == event.getTo().getBlock()) {
                return;
            }     
            //Suppose you store your location as block value and NOT as location double
            //(do you really need double precision?) 
            Location BlockTo = event.getTo().getBlock().getLocation();     
            for (Location l : plugin.sL) {
                //Is it useful for performances to check if
                //... l.getWorld() == BlockTo.getWorld() ?
                if (l == BlockTo) {
                    //FIRE in the Hole !!             
                }
            }     
        }
     
  10. Offline

    Uniclaw

    That the same thing from above - event is fired more than 1 time. Because: If i call it in a move event, and the player fall trough the block, he is in the block 3-5 ticks, and every tick this is called.
    EDIT: @to the post over the post over this post

    Likaos Yes, precision is needed ;)
    And thanks, i try it :) !!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  11. Is the task to fire some event (or do something) whenever a player is moving onto a new block (be it any or one of a list/set)?

    You could store blocks directly in a list (or better a HashSet<Block>) and test with ...contains(player.getLocation().getBlock()) (or add(...), which also returns if it was already contained).

    And don't use == on objects unless you know that the exact object is contained, potentially. All getBlock calls will create a new block, so == will always be false if you test against a new getBlock() result.
    ....
    Edit: to compare objects for equality use equals(other), or the contains calls. Locations contain the looking direction, so if you store player.getLocation and compare to another it will be different virtually every time. If you have to store the looking direction you could also use variables with the block coordinates (player.getLocation().... getBlockX() ....) and iterate over the stored locations, then compare to getBlockX() etc of the stored locations.
     
  12. Offline

    Likaos

    I nether saw a plugin where the double precision is needed with pitch and yaw too, can you say us why ?

    With that method, you alway can check if a player change block or move in an other.

    Just change player's location to player.getlocation().getblock().getLocation()
    of juste change it with Location loc = locToBlock(player.getLocation());

    Is it important for you if the player is at X = 1, Y = 120 and Z = 34 or X=1,2, Y = 120,6 and Z = 34,7 and pitch 0,109209 and yaw 0,1901092?

    If you just want to match the block, you dont need the full location.

    Edit: Agree with asofold, the final way for this check is to store in your hashmap only:
    worldName(string) + X(int) + Y(int) + Z(int) >> Create new objet ?
    Instead of (world(Objet) + X(float) + Y(float) + Z(float) + pitch(float) + yaw (float).

    My suggestion for the location test is just for a Test.

    Edit2: this antispam is boring ... I'm late in the discussion.
     
  13. Offline

    fireblast709

    Why not create a String representation of the block and check equality against that :3
    Code:java
    1. StringBuilder sb = new StringBuilder();
    2. sb.append(block.getX()).append(",");
    3. sb.append(block.getY()).append(",");
    4. sb.append(block.getZ()).append(",");
    5. sb.append(block.getWorld().getName());
    6. String blockRepresentation = sb.toString();
     
  14. I just mentioned pitch and yaw, because locations seemed to have been in use, leading to the question if those are needed.

    Main point for checking if a block is still the same should be to compare the block coordinates, if you do it by storing blocks in a HashMap directly (less code) or if you use a variation with a String with comma separation should not matter too much. Not sure about performance considerations, but getting the concept in place should be most important.
     
  15. Offline

    Uniclaw

    Likaos asofold fireblast709 Thanks :) !
    And no, pitch and yaw are not needed, but the rest must be exaclty the same ;)

    Okay, now my code is this:
    Code:
    @EventHandler
    public void onPlayerMove(PlayerMoveEvent event) {
        
            if (event.getFrom().getBlock() == event.getTo().getBlock()) {
                return;
            }     
            
            Location BlockTo = event.getTo().getBlock().getLocation();
            StringBuilder sb = new StringBuilder(); sb.append(BlockTo.getX()).append(",");sb.append(BlockTo.getY()).append(",");sb.append(BlockTo.getZ()).append(","); sb.append(BlockTo.getWorld().getName());
            
            String bR1 = sb.toString();
            
            for (Location l : plugin.sL) {
           
           StringBuilder sb1 = new StringBuilder(); sb.append(l.getX()).append(",");sb.append(l.getY()).append(",");sb.append(l.getZ()).append(","); sb.append(l.getWorld().getName());
           String bR2 = sb1.toString();
           
                if (bR1.equalsIgnoreCase(bR2)) {
                    event.getPlayer().performCommand("sle");             
                }else{System.out.println(":(");}
            }     
        }
    But if i move trough one of the defined blocks, nothing happens ._.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  16. Offline

    fireblast709

    Uniclaw use getBlockX(), getBlockY() and getBlockZ()
     
  17. Offline

    Uniclaw

  18. Offline

    fireblast709

    print out the string representation of the Location object, to compare if they are the same yourself. It always could be a small error in the String creation
    (like: System.out.println(bR1+" : "+bR2))
     
  19. Offline

    Uniclaw

    10:47:55 [INFO] 135,88,-1023,world1 :

    Uhm, why bR2 is blank :eek:
     
  20. Offline

    fireblast709

    good question. Where are you executing this line?
     
  21. Offline

    Uniclaw

    fireblast709
    Code:
    @EventHandler
    public void onPlayerMove(PlayerMoveEvent event) {
        if( (event.getTo().getX() == event.getFrom().getX()) && (event.getTo().getY() == event.getFrom().getY()) && (event.getTo().getZ() == event.getFrom().getZ())){
      return;
        }
            if (event.getFrom().getBlock() == event.getTo().getBlock()) {
                return;
            } 
         
            Location BlockTo = event.getTo().getBlock().getLocation();
            StringBuilder sb = new StringBuilder(); sb.append(BlockTo.getBlockX()).append(",");sb.append(BlockTo.getBlockY()).append(",");sb.append(BlockTo.getBlockZ()).append(","); sb.append(BlockTo.getWorld().getName());
         
            String bR1 = sb.toString();
         
            for (Location l : plugin.sL) {
       
          StringBuilder sb1 = new StringBuilder(); sb.append(l.getBlockX()).append(",");sb.append(l.getBlockY()).append(",");sb.append(l.getBlockZ()).append(","); sb.append(l.getWorld().getName());
          String bR2 = sb1.toString();
       
          System.out.println(bR1+" : "+bR2);
       
                if (bR1.equalsIgnoreCase(bR2)) {
                    event.getPlayer().performCommand("sle");         
                }else{System.out.println("H");}
            } 
        }
    After the loop trough "sL"..
    The error can not be that sL has no content, because then the systemout not is executed..
     
  22. Offline

    fireblast709

    how about you try to store the String representation in the list?
     
  23. Offline

    Uniclaw

    fireblast709 Good Idea, i try it out :D !

    fireblast709 Yeeaaah, works :D!!! But now its fired 3times :(

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  24. Offline

    fireblast709

    after event.getPlayer() do 'break;'. Besides, note that this event even gets called when you rotate, so a check if he actually moved might be nice (might be by saving a String representation of the location, and checking that ;3)
     
  25. Offline

    Uniclaw

    Doesn't works :(
    Code:
    @EventHandler
    public void onPlayerMove(PlayerMoveEvent event) {
        if( (event.getTo().getX() == event.getFrom().getX()) && (event.getTo().getY() == event.getFrom().getY()) && (event.getTo().getZ() == event.getFrom().getZ())){ 
       return;
        }   
            
            for (String l : plugin.sL) {
           
           String bR1 =plugin.convertRepresentation(event.getTo().getBlock().getLocation());
           //System.out.println(bR1+" : " + l);
           
                if (bR1.equalsIgnoreCase(l)) {
                    event.getPlayer().performCommand("sle"); 
                    break;
                }
            }     
        }
     
  26. Offline

    fireblast709

    again, use getBlockX(), getBlockY(), getBlockZ() :3
     
  27. Offline

    Uniclaw

  28. Offline

    fireblast709

  29. You could also store that string for each player (Map player name -> block string / block) and upon next move check if the string changed - if string is the same as stored... ignore with a quick return, otherwise continue processing.
    ...
    Edit: missed the last messages...
     
Thread Status:
Not open for further replies.

Share This Page