Solved Strange velocity behaviour

Discussion in 'Spigot Plugin Development' started by RandomRobinnnn, Jan 13, 2020.

Thread Status:
Not open for further replies.
  1. Hi all,

    So I've got a plugin that enables a user to doublejump, which works perfectly fine, except for one thing. When the player does a regular jump, lands on the ground, and right after it lands activates doublejump, it seems to apply the x and z values of the doublejump velocity, while the y value gets set to 0.4xxx (even though this should be 0.8. It's hardcoded). I can confirm this by listening to the PlayerVelocityEvent. The 0.4xxx seems to be about the same height as a regular jump, which makes me think the regular jump is somehow interfearing with the doublejump. So in short, whenever the player actives doubejump at a specific point, y seems to get overridden by the regular jump (or so it seems).

    So after a while I tried some other doublejump plugins (Can't remember which ones exactly, Probably the top 3 in Google) and they all seemed to have the same exact problem. I even tried in 1.8.9, 1.14.4 and 1.15.1, all of which have the same problem.

    So then I tried listening to incoming movement packets (PacketPlayInPosition), and cancel those for 5 ticks from when doublejump is activated. This also didn't solve the issue (And yes, I can confirm cancelling the packet works, as cancelling for 40 ticks would cause a Player moved to quickly warning).

    After that I've also tried delaying the doublejump when it gets activated, removing e.setCancelled(true), and more of these tiny modifications to see if it changes, but most of those just lead to a broken DoubleJump, while others simply don't fix the issue.

    So at this point I have no clue how to fix this issue. Is there something I'm missing, or should I get a completely different approach on implementing DoubleJump?

    Here's my code, although this code will not compile because it's extending another custom class (Which is not the cause of this issue):
    Code (Java):
    public class DoubleJump {

        private boolean enabled;
        private double horizontalModifier;
        private double verticalModifier;

        public DoubleJump(Player player) {
            setHorizontalModifier(0.7);
            setVerticalModifier(0.76);
        }

        public void setHorizontalModifier(double horizontalModifier) {
            this.horizontalModifier = horizontalModifier;
        }

        public void setVerticalModifier(double verticalModifier) {
            this.verticalModifier = verticalModifier;
        }

        @EventHandler
        public void onPlayerToggleFlight(PlayerToggleFlightEvent e) {
            if (e.getPlayer() != player)
                return;

            if (!enabled)
                return;

            if (player.getAllowFlight()) {
                e.setCancelled(true);

    //            Location loc = player.getLocation();
    //            Vector dir = loc.getDirection();
    //            Vector velocity = new Vector(dir.getX() * horizontalModifier, verticalModifier, dir.getZ() * horizontalModifier);
                player.setAllowFlight(false);
                player.setFlying(false);
                player.setVelocity(e.getPlayer().getLocation().getDirection().multiply(1.5).setY(1));

    //            player.setVelocity(velocity);
    //            player.setFallDistance(-5F);
                player.setFallDistance(100);
            }
        }

    //    @EventHandler
    //    public void onVelocityChange(PlayerVelocityEvent e) {
    //        if (e.getPlayer() != player)
    //            return;
    //
    //        if (e.getVelocity().getY() == 0.41999998688697815) {
    //            e.setCancelled(true);
    //        }
    //
    //        player.sendMessage(e.getVelocity().getY() + "");
    //    }

    //    @EventHandler
    //    public void onPlayerMove(PlayerMoveEvent e) {
    //        if (e.getPlayer() != player)
    //            return;
    //
    //        if (shouldRecharge()) {
    //            player.setAllowFlight(true);
    //            player.setFlying(false);
    //            player.setFallDistance(0);
    //        }
    //    }

        @EventHandler
        public void onPlayerDamage(EntityDamageEvent e) {

            if (e.getEntity() == player && e.getCause() == EntityDamageEvent.DamageCause.FALL) {

                e.setCancelled(true);

                player.setAllowFlight(true);
            }
        }

        @Override
        public void onStart() {
            enabled = true;
            player.setAllowFlight(true);
        }

        @Override
        public void onStop() {
            enabled = false;
        }

        private boolean shouldRecharge() {
            if (player.getAllowFlight()) {
                return false;
            }

            boolean shouldRecharge = false;
            Location location = player.getLocation();
            double x = location.getX();
            double y = location.getY() - 0.001;
            double z = location.getZ();
            World world = location.getWorld();
            Location locationUnderPlayer = new Location(world, x, y, z);
            List<Location> toCheck = new ArrayList<>();
            toCheck.add(locationUnderPlayer.clone().add(0.3, 0, -0.3));
            toCheck.add(locationUnderPlayer.clone().add(-0.3, 0, -0.3));
            toCheck.add(locationUnderPlayer.clone().add(0.3, 0, 0.3));
            toCheck.add(locationUnderPlayer.clone().add(-0.3, 0, 0.3));

            for (Location loc : toCheck) {
                if (!loc.getBlock().isPassable()) {
                    shouldRecharge = true;
                    break;
                }
            }

            return shouldRecharge;
        }
    }
     

    (For some reason I am forced to pick a prefix for this post, so the prefix might not properly reflect this question)
     
  2. So I've been playing around a little more and I found out that applying a just boost upon doublejump activate helps solving this issue, but not quite. See, I am not able to consistently let doublejump fail (no Y boost) the way I could before, but I can still get it to fail quite a lot of I really try to time it perfectly.

    Obviously this method isn't perfect, mainly because using a jumpboost will not have the identical velocity to a proper doublejump, which is what I'm looking for. However, I have yet to discover a fix for this issue.

    Code (Text):
    player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 1, 6, true, false));
     
  3. How are you activating this double jump?
     
  4. Just by activating flight / pressing space twice. That's when it activates doublejump
     
  5. if you can record when the velocity is less than desired, why not figure out when youre looking at a velocity that you wish to modify, and set it there? ie in playervelocityevent, change the velocity to 1 if its at .4 or whatever
     
  6. Unfortunately that doesn't work either. See, sometimes the Y value appears correct, yet it doesn't get applied for some reason. I've made a video to show what exactly is happening. Hope you can make sense of it!
     
  7. Bumpydump. Any help would be nice! :D
     
  8. I have this same issue on my 1.8 mini-game. The fact that it's still around as far out as 1.14 isn't encouraging. I was planning on updating to a more recent version sometime soon and I was hoping the issue wouldn't persist, but considering your experience, I imagine it will. Like you, I've tried various things from adding a boost if they're close to the ground, adding a delay, using NMS velocity directly, etc. Nothing has fixed it so far. I know there's a way to fix this as servers like Mineplex don't have this issue and as far as I know, never have, but I'm honestly running out of ideas.
     
Thread Status:
Not open for further replies.