Solved Jump Boost & Fall Damage

Discussion in 'Spigot Plugin Development' started by R3dThunderr, Apr 22, 2017.

  1. Looking for a solution to a problem, not coding help:

    I want to give a player jump boost, I need to be able to detect when they hit the ground (from a height that they'd take fall damage from).
    Unfortunately, at level 5 jump boost, the player doesn't take damage. Through testing, I've found it takes until level 15 before the player takes damage. But I don't want the player to jump that high...
     
  2. Well, usually the methods to check for collision is schelude a task and either checking position relative to block below and if the block below is solid or calling the method onGround() from the Player object
     
  3. I was thinking of this, but if I were to check repetitively if the player is on the ground, it wouldn't allow for me to check whether the player had just fallen.

    1) Player falls
    2) Player hits ground -- fires method

    ---
    I think the problem with your suggestion is..
    1) Player is on ground -- fires method
     
  4. What I meant is:
    1)Schelude a task for Player when jump
    2) Check every tick if on ground
    3)If true execute desire action else keep running
    4)cancel task
     
    • Winner Winner x 1
  5. Oh I understand now, thanks!
     
  6. Just check the entity damage event for damageCause == DamageCause.FALL and if they are affected by jump boost cancel the damage.

    No tasks reqired


    Sent from my iPhone using Tapatalk
     
  7. The biggest problem though, is that jump boost negates fall damage. I had to go up to jump boost 15 before the player would even recognize they should take damage.
     
  8. Oh you WANT them to take fall damage like they would normally if they didn't have jump boost.

    I suppose you could watch their velocity and if it's negative (falling) and they're not on the ground remove jump boost? Then they should take normal fall damage. If they are on ground and their y velocity isn't negative reapply it?


    Sent from my iPhone using Tapatalk
     
  9. Or, you could check the DamageCause for a EntityDamageEvent and check if the player has Jump Boost
     
  10. Tips:
    Check the damage cause
    Then set the damage to the amount you want with e.setDamage
     
  11. WAS

    WAS

    ... There is no damage cause, because there is no damage, or damage event.

    Like the others said I think the way about this is a task and checking location.
     
    • Agree Agree x 1
  12. What me and him are saying is, check the damagecause, if the player had jump boost, and the DamageCause was == Fall, then e.setCancelled(true);
     
    • Funny Funny x 1
    • Winner Winner x 1
  13. WAS

    WAS

    ....Anyways.

    This is from a past plugin that I made before they added the Slimeblock. Maybe it'll help you?

    Code (Java):
      @EventHandler
       public void onFallLand(PlayerMoveEvent e) {
         if ( e.isCancelled() ) return;
         if ( e.getPlayer().getEyeLocation().getBlock().getType().equals(Material.WATER)
             || e.getPlayer().getEyeLocation().getBlock().getType().equals(Material.STATIONARY_WATER)
             || e.getPlayer().getEyeLocation().getBlock().getType().equals(Material.LADDER) ) return;
         if ( e.getPlayer().isOnGround() ) return;
         if ( e.getFrom().getY() < e.getTo().getY()
             && e.getTo().getBlock().getRelative(BlockFace.DOWN, 1).getType().equals(Material.AIR)) {
           e.getPlayer().sendMessage("Jumped.");
           wasAirborn.put(e.getPlayer().getUniqueId(), true);
         } else if ( e.getFrom().getY() > e.getTo().getY()
             && e.getTo().getBlock().getRelative(BlockFace.DOWN, 1).getType().equals(Material.AIR) ) {
           e.getPlayer().sendMessage("Falling.");
           wasAirborn.put(e.getPlayer().getUniqueId(), true);
         } else if ( wasAirborn.containsKey(e.getPlayer().getUniqueId())
             && wasAirborn.get(e.getPlayer().getUniqueId()) ) {
           e.getPlayer().sendMessage("Landed.");
           wasAirborn.put(e.getPlayer().getUniqueId(), false);
         }
       }
    wasAirborn is a private map, UUID -> Boolean. I'd imagine the trick now is determine how many blocks a user is falling.

    PS I copy pasted and removed/replaced a bunch of stuff so it may be broken.... lol
     
    • Like Like x 1
  14. Did you not read the thread so far at all? This will NOT work as jump boost prevents the fall damage from happening at all to a larger height. The event will not be fired.

    One option, although perhaps a laggy one, is PlayerMoveEvent tracking. I think the nms entity has a onGround and a wasOnGround field which could be very useful for you, though I'm not sure how well they'd work with the event - you'll have to test.

    EDIT:
    It seems wasOnGround is limited to EntitySlime - All the same, there has to be some land handling - especially for the particles that are displayed when you fall from some height.

    You also have the option of checking Player#getFallDistance on move, which should be set to 0 when the player touches the ground. You'd have to store data from the previous tick perhaps.
     
    #14 Necrone, Apr 23, 2017
    Last edited: Apr 23, 2017
    • Winner Winner x 1
  15. Have you tried adding ignoreCancelled=True to your @EventHandler line and seeing if the event will fire? If it does you could unCancel the event and add back in some damage


    Sent from my iPhone using Tapatalk
     
  16. As the name would suggest, if you ignore cancelled versions of the event, your event will never fire if the event has been cancelled previously. That suggestion aside. As has been stated NUMEROUS times in this thread already, an EntityDamageEvent will NOT be called if the player doesn't take any damage.

    Bukkit doesn't handle the fall damage! Minecraft does!
     
  17. Er I meant ignoreCancelled = false, but yeah if the event never triggers you're going to have to watch the velocity and figure out on your own when to apply the damage. There have been several suggestions on how to manually do this have you tried any of them?


    Sent from my iPhone using Tapatalk
     
  18. I think I've figured it out:
    1) PlayerMoveEvent
    2) Check parameters to make sure the player should be have the rest of the code active
    3) Check if the player is on ground
    4) Check fall distance
    5) If fall distance > 3 do stuff
     
  19. Just so this dispute can be put to bed once and for all, here's the nms for handling fall damage

    Code (Text):

    public void e(float f, float f1) {
        super.e(f, f1);
        MobEffect mobeffect = this.getEffect(MobEffects.JUMP);
        float f2 = mobeffect == null?0.0F:(float)(mobeffect.getAmplifier() + 1);
        int i = MathHelper.f((f - 3.0F - f2) * f1);
        if(i > 0) {
            if(!this.damageEntity(DamageSource.FALL, (float)i)) {
                return;
            }

            this.a(this.e(i), 1.0F, 1.0F);
            int j = MathHelper.floor(this.locX);
            int k = MathHelper.floor(this.locY - 0.20000000298023224D);
            int l = MathHelper.floor(this.locZ);
            IBlockData iblockdata = this.world.getType(new BlockPosition(j, k, l));
            if(iblockdata.getMaterial() != Material.AIR) {
                SoundEffectType soundeffecttype = iblockdata.getBlock().getStepSound();
                this.a(soundeffecttype.g(), soundeffecttype.a() * 0.5F, soundeffecttype.b() * 0.75F);
            }
        }

    }
     
    As you can see, it will only damage if variable i (the potential damage) is above 0
     
  20. Glad you figured it out - Care to share code for people in the future? I wasn't sure if the fall distance would be reset once the MoveEvent is called and the player is onGround
     
    • Agree Agree x 1