1.14.4 Check Player Movement probably not working

Discussion in 'Spigot Plugin Development' started by RealRivex, Mar 25, 2020.

  1. Hi, i am trying to add damage to a player, whenever he is NOT moving, so he has to move permanently.
    i tried this, but it doesnt work, have i did something wrong?
    if yes please dont judge :c

    Code (Text):
            new BukkitRunnable() {
                Map<Player, Location> previousLocations = new HashMap<Player, Location>();

                @Override
                public void run() {
                    for (Player p : Bukkit.getOnlinePlayers()) {
                        Location previousLocation = previousLocations.get(p);

                        Location currentLocation = p.getLocation();

                        if (previousLocation == currentLocation) {
                            p.sendMessage("Player is not moving");
                        }else
                            p.sendMessage("Player is moving");

                    }

                }
            }.runTaskTimer(this, 0L, 10L);
     
  2. I believe you're creating a new hashmap everytime the runnable runs, move the map outside of the runnable?
     
  3. tried, still not working. still sends me "player is moving" every 10 ticks, doesnt matter if i am moving or not.

    Code (Text):
        Map<Player, Location> previousLocations = new HashMap<Player, Location>();

        public void move() {

            new BukkitRunnable() {

                @Override
                public void run() {
                    for (Player p : Bukkit.getOnlinePlayers()) {
                        Location previousLocation = previousLocations.get(p);

                        Location currentLocation = p.getLocation();

                        if (previousLocation == currentLocation) {
                            p.sendMessage("Player is not moving");
                        } else
                            p.sendMessage("Player is moving");

                    }

                }
            }.runTaskTimer(this, 0L, 10L);
        }
     
     
  4. If not mistaken, you should be comparing the contents of location, so getX == getX, getY == getY etc.
     
  5. == checks if the memory address is the same, .equals checks if the content is the same. So, which one should you use?
     
  6. still the same. if i got it right

    Code (Text):
        new BukkitRunnable() {

                @Override
                public void run() {
                    for (Player p : Bukkit.getOnlinePlayers()) {
                        Location previousLocation = previousLocations.get(p);

                        Location currentLocation = p.getLocation();

                        if (previousLocation.getX() == currentLocation.getX()) {
                            if (previousLocation.getY() == currentLocation.getY()) {
                                if (previousLocation.getZ() == currentLocation.getZ()) {
                                    p.sendMessage("Player is not moving");
     
     
  7. My mistake ^^ use .equals, plus that should still work, print out the values to see output
     
  8. Im new to such things, so idk how do you mean i should use .equals. can you maybe tell me? :)
    and just print it out after the "p.sendMessage"?
     
  9. Code (Java):
    currentlocation.equals(otherLocation)
    However, if you only want to check xyz changes, then checking each individual value is the way to go, but otherwise .equals is better

    I'd put the print statement before the if(location.equals(loc)) but it doesn't particularly matter
     
  10. Code (Text):
    [Lobby] Task #20 for Lobby v1.0 generated an exception java.lang.NullPointerException: null at lobby.main.Main$2.run(Main.java:100) ~[?:?] at org.bukkit.craftbukkit.v1_14_R1.scheduler.CraftTask.run(CraftTask.java:84) ~[minecraft_server.jar:git-Paper-"7caed1a8"] at org.bukkit.craftbukkit.v1_14_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:452) ~[minecraft_server.jar:git-Paper-"7caed1a8"] at net.minecraft.server.v1_14_R1.MinecraftServer.b(MinecraftServer.java:1148) ~[minecraft_server.jar:git-Paper-"7caed1a8"] at net.minecraft.server.v1_14_R1.DedicatedServer.b(DedicatedServer.java:417) ~[minecraft_server.jar:git-Paper-"7caed1a8"] at net.minecraft.server.v1_14_R1.MinecraftServer.a(MinecraftServer.java:1075) ~[minecraft_server.jar:git-Paper-"7caed1a8"] at net.minecraft.server.v1_14_R1.MinecraftServer.run(MinecraftServer.java:919) ~[minecraft_server.jar:git-Paper-"7caed1a8"] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_232]
    if i switch prevLoc and currentLoc, it prints out nothing than an empty Line every second
     
  11. What's line 100..?
     
  12. Getting a value from a hashmap will return null if there is no value for the specified key. You have to define the previous location before you can get it, obviously.
     
  13. Line 100 is this:
    if (previousLocation.equals(currentLocation)) {
    if i use:
    if (currentLocation.equals(previousLocation)) {
    it gives me an empty console line every sec
     
  14. Are you putting their current location into the map?
     
  15. well, how do i do that? if i dont did already :confused:
     
  16. drives_a_ford

    Moderator

    You are not doing that anywhere.
    You need to use Map#put to put the player's current location to the map at the end of each iteration.
     
    • Winner Winner x 1
  17. i never really worked with HashMaps before, this is my first time i do it. is this right? :(

    Code (Text):
    for (Player p : Bukkit.getOnlinePlayers()) {
                        Location previousLocation = previousLocations.get(p);
                        Location currentLocation = p.getLocation();
                        previousLocations.put(p, currentLocation); //HERE

                        if (currentLocation.equals(previousLocation)) {
                            previousLocations.put(p, currentLocation); //HERE
                            p.sendMessage("Player is not moving");
     
  18. Also to add to Fords comment...

    Make sure to put them in the map.
    You can get the players location with map#get(key) to get the value (location), and you can loop through the map by looping through the map#keySet or map#values
     
  19. Yes that looks right to me
     
  20. Once is enough. I'd also simplify it, to where you always get a value through Map#getOrDefault, so you instantly deal damage as soon as the runnable starts. You really only need to put the location back in the map, if they are moving.