Why do arrows kill mobs in one hit??

Discussion in 'Plugin Development' started by Armadillo, Sep 16, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Armadillo

    I've been trying to write a plugin that makes objects act like guns. All of my "guns" kill mobs in 1 hit, and I don't want it to do that. Also, I want my arrows to fly straight, not have any drop.
    Here's my code:
    Code:
    public void onPlayerUse(PlayerInteractEvent event){
           
            final Player player = event.getPlayer();
           
            if (player.getItemInHand().getType().toString() == "STICK" && event.getAction() == Action.LEFT_CLICK_AIR ||event.getAction() == Action.LEFT_CLICK_BLOCK && player.getInventory().contains(Material.SEEDS)) {
                  Arrow arrow = player.launchProjectile(Arrow.class);
                  //arrow.setShooter((LivingEntity)player); I don't need this it dosent do anything
                  Vector velo = arrow.getVelocity().multiply(10000);
                  arrow.setVelocity(velo);
                  player.getInventory().removeItem(ammo);
                  //Gets the arrow to shoot straight
            }
     
  2. Offline

    Taco

    If I remember correctly, the damage an arrow does has to do with its velocity, and seeing as you're setting it extremely high, that would be the case.
     
  3. Offline

    Armadillo

    Never thought of that. I wonder if there is a way to make damage not rely on velocity.
    Thanks Taco.
     
  4. Offline

    SnowGears

    You could listen for mob death and check if death was by arrow. If it was check velocity of arrow and if its the same as the velocity you set cancel the death. Or lower the health of mob. Your choice
     
  5. Offline

    Armadillo

    Good idea Tooner101, I think I will use that idea, I would of never thought of that!!! Thanks!!!
     
  6. Offline

    SnowGears

    No problem! Coding is all about finding cool little checks you can do to solve problems! Let me know if you need more help!
     
    Armadillo and Taco like this.
  7. Offline

    Armadillo

    Thats why I love to code, finding cool ways to solve problems!!!
     
  8. Offline

    SnowGears

    Thats what keeps it interesting. If everything was easy it would get boring!
     
    bobacadodl likes this.
  9. Offline

    Armadillo


    I think I figured out how to do it:
    Code:
     
    public void onEnityDeath(EntityDeathEvent e) {
    if(e.getLastDamageCause().getCause() == DamageCause.PROJECTILE) {
        //Give the mob health
    }
     
    
    The only problem is that Eclipse is giving me the error "The method getLastDamageCause() is undefined for the type EntityDeathEvent."
    I just need to find a way to fix that.
     
  10. Offline

    SnowGears

    Try instanceof instead of ==
     
  11. Offline

    Armadillo

    Like this
    Code:
    public void onEnityDeath(EntityDeathEvent e) {
    if(e.getLastDamageCause().getCause() instanceof DamageCause.PROJECTILE) {
        //Give mob the heath
    }
     
    }
    
    It does not work, it gives me errors
     
  12. Offline

    SnowGears

    What errors specifically?

    This should do it for you.
    Code:
    public void onEnityDeath(EntityDeathEvent e) {
    if(e.getEntity().getLastDamageCause() == null)
    return;
    if(e.getEntity().getLastDamageCause().getCause() == DamageCause.PROJECTILE) {
        //Give mob the heath
    }
    }
    
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 28, 2016
  13. Offline

    Armadillo

    That works!!! Thanks Tooner101 for all of your help!!!!
     
  14. Offline

    SnowGears

    No problem. Glad I could help.
     
  15. Offline

    Armadillo

    Here is my final code, I haven't tested it yet but it should work, for now it only works for zombies.
    Code:
        public void onEnityDeath(EntityDeathEvent e) {
            if(e.getEntity().getLastDamageCause() == null)
            return;
            if(e.getEntity().getLastDamageCause().getCause() == DamageCause.PROJECTILE ) {
                if(e.getEntity().getHealth() == 20){
                e.getEntity().setHealth(10);
            }
           
            if(e.getEntity().getHealth() > 10){
                e.getEntity().setHealth(e.getEntity().getHealth()-10);
            }
       
        if(e.getEntity().getHealth() < 10)
            e.getEntity().setHealth(0);
        }
       
        }
     
  16. Offline

    evilmidget38

    Why not just decrement the value by 10 rather than all this "if" nonsense?
     
  17. Code:
    entity.setHealth(Math.max((entity.getHealth() - 10), 0));
     
    ferrybig and Armadillo like this.
  18. Offline

    Armadillo

    Never thought of that either. Thanks Digi and evilmidget38 for the code/ideas.
     
  19. Offline

    libraryaddict

    Why not use EntityDamageEvent instead of DeathEvent?

    DamageEvent will fire before DeathEvent and you are able to set the damage.
     
  20. Offline

    Armadillo

    I just thought of this. If the mob dies subtracting 10 health from it would make it not come back to life. Shouldn't I give the mob 10 health.
     
  21. Offline

    libraryaddict

    Yes
     
  22. Offline

    Armadillo

    What is the health in integers for a zombie. Isn't it 20???? Also, can mob health go negative???

    Here is my code:
    Code:
    public void onEnityDeath(EntityDeathEvent e) {
    if (e.getEntity().getLastDamageCause() == null)
    return;
    if (e.getEntity().getLastDamageCause().getCause() == DamageCause.PROJECTILE) {
    e.getEntity().setHealth(10);
    }
    }
    
    I just tested it, and when I kill a mob (of any type) they do not stay at 10 health, they just die. Is there a way to fix this.

    EDIT:
    Is it because onEnityDeath event fires after the mob dies so it can't bring the mob back to life???

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 28, 2016
  23. Offline

    LukeSFT

    I think you have to cancel the event with:
    e.setCancelled(true);
     
  24. Offline

    Armadillo

    It won't let me do that.
     
  25. The code I provided subtracts 10 from current health and picks the bigger number between the subtraction and 0, that's what Math.max() does... so it will be limited to 0, won't get negative :)

    For health values you should consult the wiki, I don't think zombies have 20hp tough.
     
  26. Offline

    Armadillo

    I think they have 4 hearts in normal. Also, do you know if it would be possible to bring a zombie back to life after I kill it???
     
  27. Offline

    Zidkon

    EntityDeathEvent fires whenever an entity is ABOUT to die, you can't cancel the event (bukkit doesn't allow it), so you have a projectile that is really fast, more specific arrows, arrows have a hit value depending on their speed (they said that before so I believe them xD).

    So lets represent what you are trying to do, you hit an entity with the full speed arrow, the damage is very high, so their heart go to 0, at the death of the entity the event triggers just before it dies, the code sets 10 hearts to them, but they still die because you cannot cancel the death.

    Is a little hard to explain, the EntityDeathEvent is just before the entity is death, but because you cannot cancel the event the entity will eventually die no matter what you do.

    I think is much better you do it with DamageEvent, and cancelling the damage, but setting the health as you are trying to do.

    Oh about bringing a Zombie back to life, that would be spawning a NEW zombie ¿with specific life? (have never done this) in the same spot the last one died, I think you cannot identify wich Zombie died exactly since they have not an ID (I think) xD
     
  28. Zidkon Yes, the EnttiyDamage(ByEntity)Event is the way to go. But not with cancelling, you can set the damage in the event. So override that incredible high instant-killing number. Also no need to think about negative values that way, minecraft will do all this for you (iirc).


    But a zombie has a ID. Every entity has it's own, unique ID. Also you would have to apply all the potion effects from the old zombie, noAirTicks, noDamageTicks (well, as we just damaged the may be 0 anyway) and so on. It's way more easy to manipulate the damage at the event.
     
    Zidkon likes this.
  29. Offline

    Zidkon

  30. Offline

    Armadillo

    I was going to bring the zombie back to life so that I could set it's health to half, it was an alternative for what you said. Thanks Zidkon and V10lator for your help. I'm going to use this.
     
Thread Status:
Not open for further replies.

Share This Page