Easiest way to determine player's cause of death

Discussion in 'Plugin Development' started by aciid, Nov 27, 2012.

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

    aciid

    Hi all, struggling to find the easiest way to determine a players cause of death.
    Well actually I've found a way, my solution so far is basically upon EntityDamageByEntityEvent schedule a 1 second delayed task to check if the entity is dead.

    Is there no easier way to do this? AFAIK this is the only way to get the LivingEntity cause :(
    (EntityDeathEvent is useless for this, however works great when its a player killing an entity but not vice-versa)

    I was trying to use getLastDamageCause on EntityDeathEvent with a few variants, and no luck

    E2A:
    I'm trying to get the mob (LivingEntity) that killed the player.

    It's easy to get the player that killed the mob, or the damagecause that killed the player. But not what I want :(

    This is what I have, and it works, but I am asking if anyone knows a more effective way
    Code:
     
        @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
        public void trackPlayerDeaths(EntityDamageByEntityEvent event) {
            if ((event.getEntity() instanceof Player) && (event.getDamager() instanceof LivingEntity)) {
                final Player victim = (Player)event.getEntity();
                final LivingEntity killer = (LivingEntity)event.getDamager();
             
                plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
                    public void run() {
                        if (victim.isDead()) {
                            // blah blah blah
                        }
                    }
                }, 20L);
            }
        }
    
    Huge problem with this is that being attacked by multiple entities sets off a lot of these events when I only need it once
     
  2. Offline

    gomeow

    PlayerDeathEvent?
    if(event.getCause() == such and such)
     
  3. Offline

    aciid

    event.getCause doesn't exist in playerdeathevent.

    Also I NEED LivingEntity to be returned, not damage cause or anything else :(
     
  4. Offline

    Woobie

    Code:
    if(e.getLastDamageCause().equals(DamageCause.POOP))
    {
      //stuff 
    Something like that.
     
    afistofirony likes this.
  5. Offline

    aciid

    Just said I need LivingEntity nothing else :(
     
  6. Offline

    gomeow

    event.getEntity()
     
  7. Offline

    aciid

    Returns the entity that just died
     
  8. Offline

    gomeow

    You did not specify which entity you wanted, just a LivingEntity
    If you want the killer: .getKiller()
    If you want the damager: .getDamager()
     
  9. Offline

    aciid

    Yes getDamager on EntityDamageByEntityEvent is what I'm using currently, works well but I am wondering if there isn't an easier way instead of relying on a scheduled task to check if the attacked entity has died.
     
  10. Offline

    raGan.

    So you need to know how player died, yes ?
    In PlayerDeathEvent, it is possible to do this:
    Code:
    event.getEntity().getLastDamageCause().getCause()
    It returns DamageCause. Is that what you want ?
     
  11. Offline

    gomeow

    It seems like he wants a way to know how to check if the entity has died without a scheduler or EntityDeathEvent
     
  12. Offline

    raGan.

    Isn't it what the thing you quoted does ?
     
  13. Offline

    gomeow

    But I think for non-player entities as well, not sure though
     
  14. Offline

    raGan.

    Yo sho ?
    Edit: I see yo no sho.
     
  15. Offline

    gomeow

    ...
    Also, I checked, he wants a living entity, not specifically a player
     
  16. Offline

    aciid

    I'm trying to get the mob that killed the player.

    It's easy to get the player that killed the mob, or the damagecause that killed the player. But not what I want :(

    This is what I have, and it works, but I am asking if anyone knows a more effective way
    Code:
     
        @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
        public void trackPlayerDeaths(EntityDamageByEntityEvent event) {
            if ((event.getEntity() instanceof Player) && (event.getDamager() instanceof LivingEntity)) {
                final Player victim = (Player)event.getEntity();
                final LivingEntity killer = (LivingEntity)event.getDamager();
             
                plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
                    public void run() {
                        if (victim.isDead()) {
                            // blah blah blah
                        }
                    }
                }, 20L);
            }
        }
    
    Huge problem with this is that being attacked by multiple entities sets off a lot of these events when I only need it once
     
  17. Offline

    Fyre

    This is what you're looking for right?
    Code:java
    1. @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
    2. public void trackPlayerDeaths(EntityDamageByEntityEvent event) {
    3. if ((event.getEntity() instanceof Player) && (event.getDamager() instanceof LivingEntity)) {
    4. Player victim = (Player) event.getEntity();
    5. LivingEntity killer = (LivingEntity) event.getDamager();
    6.  
    7. if (event.getDamage >= victim.getHealth()) {
    8. // Do Stuff
    9. }
    10. }
    11. }
     
  18. Offline

    jamietech

    EDIT: Oops.
    Use PlayerDeathEvent:
    Code:
        @EventHandler
        public void onPlayerDeath(PlayerDeathEvent event) {
            EntityDamageEvent lastDamage = event.getEntity().getLastDamageCause();
        }
     
  19. Offline

    aciid

    Great thank you this is better! However still getting multiple triggers when being attacked by multiple enemies, any idea how to avoid this? I'm trying to think of something now.
    Not what I need bro
     
  20. Offline

    raGan.

    You need to listen to EntityDamageByEntity as you do now, but check
    Code:
    if(victim.getHealth()-event.getDamage() > 0) {
    return;
    }
    It works. I use it in quester.
     
    aciid likes this.
  21. Offline

    Lolmewn

    Code:
    public void onPlayerDeath(PlayerDeathEvent ev){
    Player p =event.getEntity();
    if(ev instanceof EntityDamageEntityEvent){
    EntityDamageEntityEvent even = (EntityDamageEntityEvent)ev;
    //get killer, damagecauses, anything.
    }
    }
     
    aciid likes this.
  22. Lolmewn Almost...
    Code:java
    1. public void onPlayerDeath(PlayerDeathEvent ev)
    2. {
    3. Player p =event.getEntity();
    4. EntityDamageEvent ev2 = p.getLastDamageCause();
    5. if(ev2 instanceof EntityDamageEntityEvent)
    6. {
    7. EntityDamageEntityEvent even = (EntityDamageEntityEvent)ev2;
    8. //get killer, damagecauses, anything.
    9. }
    10. }

    But there's something more scary in this thread:

    ...
    ...
    ... What is 'Thread-Safety' and how it affects me?
     
  23. Offline

    Lolmewn

  24. Offline

    aciid

    It's async because all I need to do is add a mysql entry to my db scheduler, that should be OK?

    You mean EntityDamageByEntityEvent?
    Cannot cast from PlayerDeathEvent to EntityDamageByEntityEvent
    and EntityDamageEvent gives Incompatible conditional operand types PlayerDeathEvent and EntityDamageEvent :(

    Thank you very much for your help, will report back on how it goes :)

    Edit: The problem is being hit by lots of entities causes this problem because the event is fired each time we're hit, it never actually triggers the code you posted.
    [​IMG]
     
  25. Offline

    Lolmewn

  26. aciid Well, as long as you know the difference between async an sync and are sure that victim.isDead() is thread safe it should be fine. I just posted this because (from my experience) most devs don't know it and use async blindly.
     
  27. Offline

    aciid

    Legend!! Works perfectly, completely missed the code you posted x)
    Thanks for all your help guys
     
  28. Offline

    raGan.

    Interesting. I don't really understand why it happens but I will definitely change it to the one you use.
     
  29. Offline

    aciid

    I'm guessing player.isDead() checks if their hp is 0 or less
     
  30. Offline

    raGan.

    I mean why my solution bugs out so hard.
     
Thread Status:
Not open for further replies.

Share This Page