Solved Issue With Checking If In Air/Swimming

Discussion in 'Plugin Development' started by TheHandfish, Apr 29, 2014.

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

    TheHandfish

    In my plugin, I'm making it so when you respawn, you're teleported to your last location. The "last location" updates every time you move unless you are in the air or in lava. That's what it's supposed to do, at least. For example, if I'm on a bridge and I jump into lava, I die, but when I respawn I go right back to where the lava was. I want to make it so I spawn back on the bridge. Also, if I jump off of a cliff and fall to the ground, die, and respawn, I'll respawn on the ground, not the top of the cliff.

    Here is what I have:

    Code:javascript
    1. public static void updateRespawn(Player p)
    2. {
    3. if(p.getHealth() != 0.0 && p.getLocation().getBlock().getType() != Material.AIR)
    4. {
    5. if((p.getLocation().getBlock().getType() != Material.WATER) && (p.getLocation().getBlock().getType() != Material.STATIONARY_WATER))
    6. {
    7. if((p.getLocation().getBlock().getType() != Material.LAVA) && (p.getLocation().getBlock().getType() != Material.STATIONARY_LAVA))
    8. {
    9. p.setMetadata("lastLocX", new FixedMetadataValue(plugin, p.getLocation().getBlockX()));
    10. p.setMetadata("lastLocY", new FixedMetadataValue(plugin, p.getLocation().getBlockY()));
    11. p.setMetadata("lastLocZ", new FixedMetadataValue(plugin, p.getLocation().getBlockZ()));
    12. p.setMetadata("lastLocYaw", new FixedMetadataValue(plugin, p.getLocation().getYaw()));
    13. }
    14. }
    15. }
    16. }


    Bump. .-.

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

    mrgreen33gamer

    Idk how to exactly, but I think you have to put the player in a HashMap for everytime they move using the event:

    Code:
    public void onMoveEvent(PlayerMoveEvent event){}
    If I could give you a complete code, I would, it's just I don't know this.
     
  3. Offline

    thecrystalflame

    that is one very broad answer, it doesnt really help at all.

    @TheHandfishyour going to want to check the block under the players feet not the block directly at there location, start with this.
    Code:java
    1.  
    2. Bloack block = player.getLocation().clone().getBlock().getRelative(BlockFace.DOWN);
    3.  


    this will return the block directly under the players feet. from there you want to check the the type is not equal to lava, air or water and set there last x,y,z, and world values.
     
    TheHandfish likes this.
  4. Offline

    TheHandfish

  5. Offline

    Zach_1919

    TheHandfish Just a simple mistake. You are checking if the block at the player's location is not lava, water, or air, but the player's location will ALWAYS be air, water, or lava, unless they are inside of a solid block. The player's location is where the bottom half of their body is, so that would obviously be air if you're occupying that space. Instead, you can do this:
    Code:java
    1. if(p.getLocation().subtract(0,1,0).getBlock().getType() != Material.AIR){
    2. }

    or this:
    Code:java
    1. if(p.onGround()){
    2. }


    The second one is easier, but I'm not sure how it reacts with lava and water. Regardless, there's your problem. Just a silly mistake.
     
  6. Offline

    TheHandfish

    Zach_1919, thecrystalflame, mrgreen33gamer,

    Thanks for the help guys. However, I'm still getting problems.

    Code:javascript
    1. public static void updateRespawn(Player p)
    2. {
    3. Entity e = p.getVehicle();
    4. if(e.getLocation().subtract(0,1,0).getBlock().getType() != Material.AIR)
    5. {
    6. p.sendMessage("§6Stage 1: No air");
    7. if((e.getLocation().subtract(0,1,0).getBlock().getType() != Material.WATER) && (e.getLocation().subtract(0,1,0).getBlock().getType() != Material.STATIONARY_WATER))
    8. {
    9. p.sendMessage("§bStage 2: No water");
    10. if((e.getLocation().subtract(0,1,0).getBlock().getType() != Material.LAVA) && (e.getLocation().subtract(0,1,0).getBlock().getType() != Material.STATIONARY_LAVA))
    11. {
    12. p.sendMessage("§aStage 3: No lava, saving pos...");
    13. p.setMetadata("lastLocX", new FixedMetadataValue(plugin, p.getLocation().getBlockX()));
    14. p.setMetadata("lastLocY", new FixedMetadataValue(plugin, p.getLocation().getBlockY()));
    15. p.setMetadata("lastLocZ", new FixedMetadataValue(plugin, p.getLocation().getBlockZ()));
    16. p.setMetadata("lastLocYaw", new FixedMetadataValue(plugin, p.getLocation().getYaw()));
    17. }
    18. }
    19. }
    20. }


    The above is the most updated version of checker. I'm still able to jump in lava, die, then respawn in the lava for some reason. :I Keep in mind, my lava flows, it's not just a bunch of source blocks.
     
  7. Offline

    thecrystalflame

    Code:java
    1.  
    2. Block block = player.getLocation().getBlock().getRelative(BlockFace.DOWN);
    3. if (!block.isLiquid() && block.getType() != Material.AIR) {
    4.  
    5. }
    6.  
     
  8. Offline

    TheHandfish

    Code:javascript
    1. Entity e = p.getVehicle();
    2. Block block = e.getLocation().getBlock().getRelative(BlockFace.DOWN);
    3. if (!block.isLiquid() && block.getType() != Material.AIR)
    4. {
    5. p.sendMessage("§6Stage 1: No air");
    6. p.sendMessage("§aStage 3: No lava, saving pos...");
    7. p.setMetadata("lastLocX", new FixedMetadataValue(plugin, p.getLocation().getX()));
    8. p.setMetadata("lastLocY", new FixedMetadataValue(plugin, p.getLocation().getY()));
    9. p.setMetadata("lastLocZ", new FixedMetadataValue(plugin, p.getLocation().getZ()));
    10. p.setMetadata("lastLocYaw", new FixedMetadataValue(plugin, p.getLocation().getYaw()));
    11. }
    12. else
    13. {
    14. p.sendMessage("§6STAGE 1 §4ERROR!");
    15. }
    16.  
    17. if(p.getLocation().getBlock().getType() == Material.LAVA || p.getLocation().getBlock().getType() == Material.STATIONARY_LAVA || e.getLocation().getBlock().getType() == Material.LAVA || e.getLocation().getBlock().getType() == Material.STATIONARY_LAVA)
    18. {
    19. p.setHealth(0.0);
    20. }
    21.  


    thecrystalflame: Still spawns me in the lava. :I (Set it so it kills you instantly when you enter lava, BTW. Part of my plugin.)
     
  9. Offline

    Rocoty

    Probably because the block underneath the player after they stepped into the lava, is a solid block. For lava and water you should check the player's actual location as well.
     
    VanHaggen likes this.
  10. Offline

    mrgreen33gamer

    Oh I think I know, Maybe you can try to get the block that the player is walking on or inside of, your coding is not getting what the player should be doing, for instance, going into the water. Ill give you a code example, this code comes from my code Poseidon!

    Code:java
    1.  
    2. @EventHandler
    3. public void PoseidonKit(PlayerMoveEvent event) {
    4. Player p = event.getPlayer();
    5. if (Main.poseidon.contains(p.getName())) {
    6. if (event.getPlayer().getRemainingAir() < 200)
    7. event.getPlayer().setRemainingAir(200);
    8. if (p.getLocation().getBlock().isLiquid()) {
    9. p.addPotionEffect(new PotionEffect(
    10. PotionEffectType.INCREASE_DAMAGE, 40,
    11. this.potionMultiplier), true);
    12. p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 40,
    13. this.potionMultiplier), true);
    14. }
    15. }
    16. }
    17.  


    You want to get the player that is inside the water or air and do something. Enjoy :)
     
  11. Offline

    Rocoty

    Simple rule: if player is standing on solid block and player's position is not in liquid, player is safe
     
  12. Offline

    DrEinsteinium

  13. Offline

    Rocoty

    DrEinsteinium == works good for enums, as there would only ever be one instance of a constant anyway.
     
  14. DrEinsteinium No! getType() returns an enum, leave it alone.
     
  15. Offline

    DrEinsteinium

    Rocoty AdamQpzm Haha alright alright. Using equals is a habit to me if the objects are not primitive :p It's still good practice
     
  16. DrEinsteinium Disagreed. Good practice is knowing when to use what.
     
  17. Offline

    Rocoty

    AdamQpzm I concur. And in this case I would use a switch-statement.
     
    DrEinsteinium and AdamQpzm like this.
  18. Offline

    DrEinsteinium

    AdamQpzm All Objects have the .equals() method, primitives do not... I understand that enums are singleton constants and you don't have to use the method to compare them, but the efficiency difference is minimal if at all different.
    If I had access to a Java compiler right now I'd actually do the research and get the solid facts, but I'm assuming the difference in timings between .equals() and == is <10ms.

    Edit: And yeah, switches are my goto for enums.
     
  19. DrEinsteinium Of course it will be, it shouldn't take 10ms for a single call :S equals() is less efficient, but it will be such a tiny difference that it would be very hard to find a situation in which it will matter. But that wasn't really the point I was going for - if you want to use equals() feel free. But:
    1) Beware of any pitfalls that the method may result in
    and 2) Don't just dismiss alternatives, especially when they're as good as if not better than thing you're suggesting.

    Either way, simple fact is it won't fix the problem and isn't worth trying :p
     
  20. Offline

    Rocoty

    DrEinsteinium the difference is probably even less than that, seeing as the default implementation for equals() in enums, like in Object, only returns the result of ==. Therefore the best practice in this case is the best readable approach. In my opinion, that is ==.

    Oh...and == is null safe

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 7, 2016
  21. Offline

    DrEinsteinium

    Rocoty AdamQpzm Aren't you forgetting the fact that you can override the equals method in any object? I am not dismissing the == operator, as I use it all the time, I am just trying to get clarification.
     
  22. Offline

    Rocoty

    DrEinsteinium If I am only interested in whether two references point to the same object, I always use ==. Otherwise I mostly use equals()
     
  23. DrEinsteinium Not in enums. And what point does that make anyway? The fact that it can be overriden doesn't help your point, as let's assume I could override it in something that worked with both equals() and == - you decide which to use. So you go with using equals() because it's bound to work, right? It's equals()!

    But, what do we have here in my class?

    PHP:
    @Override
        
    public boolean equals(Object o) {
            
    System.out.println("I don't like the equals() method");
            
    System.exit(0);
            return 
    true;
        }
    Uh oh
     
  24. Offline

    Rocoty

    AdamQpzm That's taking it to the extreme lol. Any API could have any such method.
     
  25. Offline

    DrEinsteinium

    AdamQpzm Now you are just being immature... I didn't take into account programmers who would really be stupid enough to do that in their code... I am saying that if any programmer overwrote an equals() method for a complicated object it would always be more precise in situations where precision was required.

    I guess I can just let you continue to use == to compare ItemStacks and Strings. It's your choice after all :p
     
  26. Rocoty DrEinsteinium To be fair it was a joke. I don't know of any programmers who have an irrational hate for a specific method enough to do that. And if they did, I don't think you'd really need or want to use what they had wrote.
     
    Rocoty likes this.
  27. Offline

    TheHandfish

    Rocoty mrgreen33gamer:


    A little confused. The idea is to get the player to not do something if it's in the water/lava/air. :p I want to make it so if the player is in the air or in lava, his position isn't saved. For some reason, it is saving the position. Even my debug messages are telling me his location isn't being saved...

    UPDATE:

    Code:javascript
    1. public static void updateRespawn(Player p)
    2. {
    3. Entity e = p.getVehicle();
    4. Block block = e.getLocation().getBlock().getRelative(BlockFace.DOWN);
    5. if (!block.isLiquid() && block.getType() != Material.AIR)
    6. {
    7. p.sendMessage("§6Stage 1: No air");
    8. p.sendMessage("§aStage 3: No lava, saving pos...");
    9. p.setMetadata("lastLocX", new FixedMetadataValue(plugin, p.getLocation().getX()));
    10. p.setMetadata("lastLocY", new FixedMetadataValue(plugin, p.getLocation().getY()));
    11. p.setMetadata("lastLocZ", new FixedMetadataValue(plugin, p.getLocation().getZ()));
    12. p.setMetadata("lastLocPitch", new FixedMetadataValue(plugin, p.getLocation().getPitch()));
    13. p.setMetadata("lastLocYaw", new FixedMetadataValue(plugin, p.getLocation().getYaw()));
    14. }
    15. else
    16. {
    17. p.sendMessage("§6STAGE 1 §4ERROR!");
    18. }
    19.  
    20. if(e.getLocation().subtract(0,1,0).getBlock().getType() == Material.LAVA || e.getLocation().subtract(0,1,0).getBlock().getType() == Material.STATIONARY_LAVA)
    21. {
    22. p.setHealth(0.0);
    23. }
    24.  
    25. }


    This is beginning to work. The player is spawning on top of the bridge sometimes, but I think the problem relies with the fact that the player doesn't stop being on the ground until both feet of his vehicle are in the air (keep in mind, he's on a horse). I'll try and do both checks. ;)

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 7, 2016
  28. TheHandfish In that case you should be able to check the player's vehicle as well as the player themselves, right?

    DrEinsteinium Wait a sec, I said "knowing when to use what" not "blindly using ==".
     
  29. Offline

    TheHandfish

    AdamQpzm: I got it to work!

    Code:javascript
    1. public static void updateRespawn(Player p)
    2. {
    3. Entity e = p.getVehicle();
    4. Block block = e.getLocation().getBlock().getRelative(BlockFace.DOWN);
    5.  
    6. Location loc1 = e.getLocation().add(1,-1,1);
    7. Location loc2 = e.getLocation().add(-1,-1,1);
    8. Location loc3 = e.getLocation().add(1,-1,-1);
    9. Location loc4 = e.getLocation().add(-1,-1,-1);
    10. Location loc5 = e.getLocation().add(0,-1,-1);
    11. Location loc6 = e.getLocation().add(1,-1,0);
    12. Location loc7 = e.getLocation().add(-1,-1,0);
    13. Location loc8 = e.getLocation().add(0,-1,1);
    14.  
    15. Location tloc1 = e.getLocation().add(2,-1,2);
    16. Location tloc2 = e.getLocation().add(-2,-1,2);
    17. Location tloc3 = e.getLocation().add(2,-1,-2);
    18. Location tloc4 = e.getLocation().add(-2,-1,-2);
    19. Location tloc5 = e.getLocation().add(0,-1,-2);
    20. Location tloc6 = e.getLocation().add(2,-1,0);
    21. Location tloc7 = e.getLocation().add(-2,-2,0);
    22. Location tloc8 = e.getLocation().add(0,-1,2);
    23.  
    24. Location eloc1 = e.getLocation().add(3,-1,3);
    25. Location eloc2 = e.getLocation().add(-3,-1,3);
    26. Location eloc3 = e.getLocation().add(3,-1,-3);
    27. Location eloc4 = e.getLocation().add(-3,-1,-3);
    28. Location eloc5 = e.getLocation().add(3,-1,-3);
    29. Location eloc6 = e.getLocation().add(3,-1,0);
    30. Location eloc7 = e.getLocation().add(-3,-1,0);
    31. Location eloc8 = e.getLocation().add(0,-1,3);
    32. if (!block.isLiquid() && block.getType() != Material.AIR && e.getLocation().subtract(0,1,0).getBlock().getType() != Material.AIR && loc1.getBlock().getType() != Material.AIR && loc2.getBlock().getType() != Material.AIR && loc3.getBlock().getType() != Material.AIR && loc4.getBlock().getType() != Material.AIR && loc5.getBlock().getType() != Material.AIR && loc6.getBlock().getType() != Material.AIR && loc7.getBlock().getType() != Material.AIR && loc8.getBlock().getType() != Material.AIR)
    33. {
    34. if(tloc1.getBlock().getType() != Material.AIR && tloc2.getBlock().getType() != Material.AIR && tloc3.getBlock().getType() != Material.AIR && tloc4.getBlock().getType() != Material.AIR && tloc5.getBlock().getType() != Material.AIR && tloc6.getBlock().getType() != Material.AIR && tloc7.getBlock().getType() != Material.AIR && tloc8.getBlock().getType() != Material.AIR)
    35. {
    36. if(eloc1.getBlock().getType() != Material.AIR && eloc2.getBlock().getType() != Material.AIR && eloc3.getBlock().getType() != Material.AIR && eloc4.getBlock().getType() != Material.AIR && eloc5.getBlock().getType() != Material.AIR && eloc6.getBlock().getType() != Material.AIR && eloc7.getBlock().getType() != Material.AIR && eloc8.getBlock().getType() != Material.AIR)
    37. {
    38. p.sendMessage("§6Stage 1: No air");
    39.  
    40. p.sendMessage("§aStage 3: No lava, saving pos...");
    41. p.setMetadata("lastLocX", new FixedMetadataValue(plugin, p.getLocation().getX()));
    42. p.setMetadata("lastLocY", new FixedMetadataValue(plugin, p.getLocation().getY()));
    43. p.setMetadata("lastLocZ", new FixedMetadataValue(plugin, p.getLocation().getZ()));
    44. p.setMetadata("lastLocPitch", new FixedMetadataValue(plugin, p.getLocation().getPitch()));
    45. p.setMetadata("lastLocYaw", new FixedMetadataValue(plugin, p.getLocation().getYaw()));
    46. }
    47. }
    48. }
    49. else
    50. {
    51. p.sendMessage("§6STAGE 1 §4ERROR!");
    52. }
    53.  
    54. if(e.getLocation().subtract(0,1,0).getBlock().getType() == Material.LAVA || e.getLocation().subtract(0,1,0).getBlock().getType() == Material.STATIONARY_LAVA && p.getGameMode() != GameMode.CREATIVE)
    55. {
    56. p.setHealth(0.0);
    57. }
    58.  
    59. }
    60.  

    ^ As you can see, it's a bit messy. Is there a way I could simplify this, not needing to declare as many Location variables like that?
     
Thread Status:
Not open for further replies.

Share This Page