Solved setNoDamageTicks

Discussion in 'Spigot Plugin Development' started by He-light, Feb 5, 2020.

  1. Hi, I want to set the NoDamageTicks of a player to 0, if he is hit by an Arrow. My goal is to acheave, that if, for example, 5 arrows hit the player at the same time, he should take damage from 5 arrows and not just one.
    My code looks something like (pseudocode):

    @EventHandler
    private void hitByProjectile(EntityDamageByEntityEvent e) {

    if (e.getEntity() instanceof LivingEntity) {
    LivingEntity damagedEntity = (LivingEntity) e.getEntity();
    //set damage
    damagedEntity.setNoDamageTicks(0);
    }

    Any suggestions?

    SOLVED:
    Sandeep was so kind and provided working code to solve the issue. (Should be the last post)
     
    #1 He-light, Feb 5, 2020
    Last edited: Feb 6, 2020

  2. i tried now:

    Code (Java):
    @EventHandler
    private void hitByProjectile(EntityDamageByEntityEvent e) {

    if (e.getEntity() instanceof LivingEntity) {
    LivingEntity damagedEntity = (LivingEntity) e.getEntity();
    //set damage
    entity.setNoDamageTicks(0);
    entity.setLastDamage(Integer.MAX_VALUE);
    }
    But it didn't work. 4 out of 5 arrows bounced back

    I have already tried the solution of this thread before
     
  3. I assume this is happening, because the event is called before the entity is actually damaged. You could try something like this:
    Code (Java):
        @EventHandler
        public void onDmg(EntityDamageByEntityEvent e) {
            if (e.getEntity() instanceof LivingEntity && e.getDamager() instanceof Arrow) {
                LivingEntity ent = (LivingEntity) e.getEntity();
                int mndt = ent.getMaximumNoDamageTicks();        
                ent.setMaximumNoDamageTicks(0);
       
                Bukkit.getScheduler().runTaskLater(/* Your plugin */, () -> {
                    ent.setMaximumNoDamageTicks(mndt);
                }, 1L);
            }
        }
    and see if that solves your issue.

    Furthermore, while this may solve your issue. This solution is pretty crude, inside your plugin you might want to create a better system.
     
    #6 Heretere, Feb 5, 2020
    Last edited: Feb 5, 2020
  4. it seems, it still doesn't work somehow...
    It happens sometimes, that 2 out of 5 arrows hit and apply damage but not every time.

    Code (Text):
    @EventHandler
        private void hitByProjectile(EntityDamageByEntityEvent e) {

            if (e.getEntity() instanceof LivingEntity) {
                LivingEntity damagedEntity = (LivingEntity) e.getEntity();

                if (e.getDamager() instanceof Arrow) {
                    int mndt = damagedEntity.getMaximumNoDamageTicks();
                    damagedEntity.setMaximumNoDamageTicks(0);
                     
                    e.setDamage(/*Damage*/);
                   Bukkit.broadcastMessage("damage = " + e.getDamage());
                    Bukkit.getScheduler().runTaskLater(p, () -> {
                        damagedEntity.setMaximumNoDamageTicks(mndt);
                    }, 1L);
                }
             

            }
        }
     
  5. This is why I said it was a crude system. Trying changing 1L to something like 20L
     
  6. i tried 1L, 5L, 20L and 40L but always same result. 1 hit out of 5 and sometimes 2...

    But I really appreciate your help! Thank you for that^^
     
  7. I think I can help but I don’t understand what this is supposed to look like in game
     
  8. With my plugin, you have the ability to do a special attack, where you shoot 5 arrows at the same time. And my problem is, that this would be pointless, if (like it is in vanilla minecraft) you get the NoDamageTickets after beeing hit by one arrow. That would mean you shoot 5 arrows at the same time at a target, but only one causes damage, because the other 4 bounce off the target(due to the noDamageTickets) and deal no damage.
     
  9. This code should work
    Code (Text):

    // Normal listener annotation
    @EventHandler
    public void onPlayerInteractEvent(PlayerInteractEvent e) {
       Player player = e.getPlayer();
       if (firing.contains(player.getUniqueId())) return;// this is an empty list that is initiated at the onEnable
       if (e.getAction() == Action.LEFT_CLICK_AIR && player.getInventory().getItemInMainHand().getType() == org.bukkit.Material.BOW) {
          throwArrow(player, 0, 5); // Method that is used later on which lets you fire the arrows after an interval
          firing.add(player.getUniqueId()); // Add to the firing list (prevents spamming)
       }
    }

    private final void throwArrow(Player player, int i, int max) {
       if (i == max) { // if the number i reaches the max number of arrows to be thrown then stop
          firing.remove(player.getUniqueId());
          return;
       }

       Bukkit.getScheduler().runTaskLater(this, () -> { // if it does not meet the max amount then run a task

          Arrow arrow = player.launchProjectile(Arrow.class); // fire arrow
          arrow.setMetadata("specialArrow", new FixedMetadataValue(this, true));
          throwArrow(player, i + 1, max);  // run the same method again but increase 'i' so it can eventually stop and won't throw runtime errors
       }, 20/max/2);
    }

    @EventHandler
    public void onHit(EntityDamageByEntityEvent event) {
       if (event.getDamager().hasMetadata("specialArrow")) { // entity hit with arrow
          if (event.getEntity() instanceof LivingEntity) {
             Bukkit.getScheduler().runTaskLaterAsynchronously(this, ()->{
                ((LivingEntity) event.getEntity()).setNoDamageTicks(0); // after 100ms you will set the no damage ticks to 0 so arrows can hurt again
             }, 2L);
          }
       }
    }
     
     
    • Agree Agree x 1
  10. WOW, thats amazing!
    Thank you soo much for your help and effort!!
     
  11. Do you get what I did? I think the problem was you were firing the arrows at once and not at intervals since a for loop doesn’t do what you wanted
     
  12. Yes, i got it. At first i actually wanted to shoot them all at once, but i know now, that this does not work, so the idea of the ability is slightly changed, but that doesn't matter. Thanks again!