prevent a player from moving (x,y,z, but allow turning head)

Discussion in 'Spigot Plugin Development' started by NoobDoesMC, Jul 19, 2018.

  1. well a recent post just like this stated that you can set the player to ride an entity like armorstand and make it invisible thus the player will stay in one place but will still be able to look around regarding the interactions you can cancel that with other events
     
  2. the code above is effectively useless as if he toggles the move for one player, he won't be able to for the others.
     
  3. Ok, look. The OP might not want to use the PlayerMoveEvent, but it might be the best if not only option here.

    Let's take a look at my listener class from my Freeze plugin. I'll explain it as I go.
    Code (Text):
    public class PlayerMoveListener implements Listener {
       
        private final FreezePlus plugin;
       
        public PlayerMoveListener(FreezePlus plugin) {
            this.plugin = plugin;
            plugin.getServer().getPluginManager().registerEvents(this, plugin);
        }
       
        @EventHandler
        public void onPlayerMove(PlayerMoveEvent e) {
            if (plugin.freezeCommand.frozenPlayers.containsKey(e.getPlayer())) {
                if (SETTINGS.ALLOW_CAMERA_MOVEMENT.getConfigValue()) {
                    if (e.getFrom().getX() != e.getTo().getX() || e.getFrom().getY() != e.getTo().getY() || e.getFrom().getZ() != e.getTo().getZ()) {
                        Location loc = e.getFrom();
                        e.getPlayer().teleport(loc.setDirection(e.getTo().getDirection()));
                    }
                    return;
                }
               
                e.setCancelled(true);
            }
        }
    }
    The first check in the move event is
    Code (Text):
    if (plugin.freezeCommand.frozenPlayers.containsKey(e.getPlayer())) {
    }
    The frozenPlayers variable is in another class and it is set up like so:
    Code (Text):
    public HashMap<Player, Boolean> frozenPlayers = new HashMap<>();
    We are checking to see if the player is in the map so that we can freeze them.
    Next is a check to see if the config allows for players to look around.
    Code (Text):
    if (SETTINGS.ALLOW_CAMERA_MOVEMENT.getConfigValue()) {
    }
    This is completely optional, but for my plugin, it's what I do.
    Then finally we check to see if they are moving. However, the move event counts looking around as movement, so we have to check to see if the have moved position on the X Y and Z plane.

    To do that, we use this code:
    Code (Text):
    if (e.getFrom().getX() != e.getTo().getX() || e.getFrom().getY() != e.getTo().getY() || e.getFrom().getZ() != e.getTo().getZ()) {
    }
    To put it simply, we are checking to see if their X value is going to the next predicted X value. Same goes for the Y and Z values.

    Then, now that we have checked to see if they have moved, we teleport them back to the location.
    Code (Text):
    Location loc = e.getFrom();
    e.getPlayer().teleport(loc.setDirection(e.getTo().getDirection()));
    This allows for fluid movement for Yaw and Pitch but prevents the user from moving on the X Y and Z plane. Jumping, on the other hand, will look slightly jittery, but that's because of how quickly the event fires. However, if the player is standing still, looking around will be smooth as butter.
     
  4. You can change the teleport location to the old yaw and pitch but you are right, that is not so nice ;)
     
  5. I've already done something like

    player.teleport(new Location(world, oldx, oldy, oldz, player.getLocation().getPitch(), player.getLocation().getYaw()))

    or w/e the correct methods are

    but that causes the jittery effect I don't want

    the player can turn their heads with this, but it is very awkward and ugly
     
  6. Looks like it will work. I will run a check every tick though, rather than on the event.
     
  7. To disable movement:
    Code (Java):
    player.setWalkSpeed(0F);
    To disable jumping:
    Code (Java):
    PotionEffect effect = new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 128);
    player.addPotionEffect(effect);
    This will sent an an infinite amount of the no-jump effect. To set it to a specific time, you just do seconds*20 rather than Integer.MAX_VALUE.

    To remove the no-jump effect:
    Code (Java):
    player.removePotionEffect(PotionEffectType.JUMP);
    To make the player move again with the speed that he/she already had, you'd first get the movement speed with:
    Code (Java):
    float walk_speed = player.getWalkSpeed();
    //yada yada yada
    player.setWalkSpeed(walk_speed);
    If you want to store it in a HashMap, either do a static HashMap in a different class, or make a global HashMap in that class and store with the UUID-float key-value combination.

    This is something you could do:
    Code (Java):
    public class SomeClassThatShouldDoStuffIThink
    {

        //Oopa! Static items don't need to be instanced!
        private static HashMap<UUID, Float> PlayerSpeedMap = new HashMap<UUID, Float>();
     
        public SomeClassThatShouldDoStuffIThink()
        {
            //constructor needed? Not really here!
       
            //But making it because why the hecc not!
        }
     
        //Nani?!
        public static void disablePlayerMovement(Player player)
        {
            //Just so you don't get the wretched NPE's
            if(player != null)
            {
                //could add it directly but this is pretty to the eye
                float speed = player.getWalkSpeed();
                UUID uuid = player.getUniqueId();
           
                //Time to store to the map!
                PlayerSpeedMap.put(uuid, speed);
           
                //Adios! Speed!
                player.setWalkSpeed(0F);
           
                //Let's see if player has the nego-jump effect, because it doesn't overwrite
                player.removePotionEffect(PotionEffectType.JUMP);
           
                //Kk, let's make the effect
                PotionEffect effect = new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 128);
           
                //Apply it!
                player.addPotionEffect(effect);
           
                //There, no waling nor jumping!
            }
        }
     
     
        //CMD > Run > oHeccThePlayerNeedsToMove.exe
        public static boolean enablePlayerMovement(Player player)
        {
            //Why the bool! Well wouldn't you want to know?!
            boolean statement = false;
            //It's just to check if the player was disabled. (I have crippling depression)
       
            //Mr. UUID, do come!
            UUID uuid = player.getUniqueId();
       
            if(PlayerSpeedMap.containsKey(uuid))
            {
                //At one point the player was disabled
           
                //Enable le jumping
                player.removePotionEffect(PotionEffectType.JUMP);
           
                //get le moving
                player.setWalkSpeed(PlayerSpeedMap.get(uuid));
           
                //So it will say "Yep, he was disabled alright!"
                statement = true;
            }
       
            //This is a boolean so it's A-ok.
            if(statement)
                PlayerSpeedMap.remove(uuid);
            //I removed it here because I didn't want to risk
            //getting an NPE...
       
            return statement;
        }
    }
    Everything is static because then you could just import it to your project and use it directly with:
    Code (Java):
    SomeClassThatShouldDoStuffIThink.disablePlayerMovement(player);
    SomeClassThatShouldDoStuffIThink.enablePlayerMovement(player);
     
    #27 Zastrix, Jul 19, 2018
    Last edited: Jul 19, 2018
    • Agree Agree x 1
  8. These two in conjunction don't stun the player

    spamming space and holding w bypasses
     
  9. Then use the PlayerMoveEvent along with those to fix that? Let the event prevent movement and let the speed/jump prevent 'jittering'.
     
  10. ScarabCoder

    ScarabCoder Retired Resource Staff
    Retired

    Try making the player sit on a fake entity via packets. The only downside is the client will have the sitting animation/pose, however other players won't see it.