Solved DamageCause in PlayerDeathEvent won't work for some causes.

Discussion in 'Plugin Development' started by puyttre, Dec 12, 2012.

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

    puyttre

    Hi,

    I have the following code:
    Code:java
    1. @EventHandler
    2. public void onDeath(PlayerDeathEvent e){
    3. e.getDrops().clear();
    4. e.setDroppedExp(0);
    5.  
    6. Player killed = e.getEntity();
    7. Player killer = killed.getKiller();
    8.  
    9. ChatColor gold = ChatColor.GOLD;
    10. ChatColor yellow = ChatColor.YELLOW;
    11.  
    12. DamageCause dc = e.getEntity().getLastDamageCause().getCause();
    13. EntityDamageByEntityEvent damageEvent;
    14. try {
    15. damageEvent = (EntityDamageByEntityEvent) e.getEntity().getLastDamageCause();
    16. } catch (Exception ex) {
    17. return;
    18. }
    19.  
    20. switch(dc){
    21. case ENTITY_ATTACK:
    22. if(e.getEntity().getLastDamageCause().getEntity() instanceof Player){
    23. Player pk = (Player)e.getEntity().getKiller();
    24. e.setDeathMessage(gold + killed.getName() + yellow + " has been killed by " + gold + killer.getDisplayName() + yellow + ".");
    25. }
    26. case PROJECTILE:
    27. if(damageEvent.getDamager().getType() == EntityType.ARROW){
    28. Arrow arrow = (Arrow)damageEvent.getDamager();
    29. Player bowkiller = (Player)arrow.getShooter();
    30. e.setDeathMessage(gold + killed.getName() + yellow + " has been killed by " + gold + bowkiller.getDisplayName() + yellow + "'s arrow.");
    31. }
    32. case CONTACT:
    33. e.setDeathMessage(gold + killed.getName() + yellow + " was killed by a cactus.");
    34. case FALL:
    35. e.setDeathMessage(gold + killed.getName() + yellow + " has fell to their death.");
    36. case LAVA:
    37. e.setDeathMessage(gold + killed.getName() + yellow + " was burnt by lava.");
    38. case DROWNING:
    39. e.setDeathMessage(gold + killed.getName() + yellow + " was burnt by lava.");
    40. case FIRE:
    41. e.setDeathMessage(gold + killed.getName() + yellow + " was killed in a fire.");
    42. default:
    43. e.setDeathMessage(gold + killed.getName() + yellow + " died.");
    44. }
    45.  
    46. }
    What this code does, is switch through the death cause to find the cause of death.

    Everything involving PvP and killing by mobs/explosives works, but many don't work. Contact, fall, lava, fire, drowning, and a few more still give the default death message when a player dies. I have no clue why this is happening since the switch loop should eventually catch the reason, right?

    Does anyone know how to fix this?

    Thanks.
     
  2. Offline

    Chlorek

    I am not at home and I can't check your code, but it looks ok (or I just do not see something). However I think that Bukkit works fine, but I see some errors in your code, for example where 'killed' is defined? Paste whole listener function. Also I would add killed.sendMessage() to every cause, so I could know is some event called or not, maybe just the death message is not set.
     
  3. Offline

    Don Redhorse

    look at deathdetail in deathtpplus... detection the death cause is hard... also anvil isn't correctly implemented atm.
     
  4. Offline

    puyttre

    Ok I updated the code in the main post.
     
  5. Offline

    chasechocolate

    BTW in your code, if the player drowns it will say they were burnt by lava...
     
  6. Offline

    nisovin

    You have a try-catch that completely ignores a relevant error. This is your problem. Remove that try-catch and you'll see exactly what's wrong. Not all damage is caused by entities, so you can't always cast to EntityDamageByEntityEvent.
     
  7. Offline

    Hoolean

    Hey puyttre !

    As you have a Resetti avatar, I shall help you :D

    At the end of the code for each case, put:
    Code:
    break;
    NOTE: This will not be needed for default!
     
  8. Offline

    puyttre

    I love you :) How could I be so dumb xD

    I the EntityDamageByEntityEvent is only used for the PROJECTILE case. Look at the code again.

    EDIT: MrBluebear3 , It didn't work. :( Same problem as before -- Only the PROJECTILE and ENTITY_DAMAGE work, all the others give Minecraft's default death message.
     
  9. Offline

    nisovin

    It may be only used there, but you're forcing the event to be casted. If it is in fact NOT an EntityDamageByEntityEvent, that will throw an exception which you silently ignore and just return before any other code can run.
     
  10. Offline

    puyttre

    So instead of putting "break" when I catch the exception, can I switch that to "continue" and still be safe? Or should I just put the try and catch statement in the PROJECTILE case?
     
  11. Offline

    nisovin

    Moving the try/catch to the projectile case would work. Also, you've put "return" in the catch, which ends the method call. You can't put "break" or "continue" there, because there's no code construct to break or continue from.
     
    puyttre likes this.
  12. Offline

    puyttre

    Thanks :)
    I moved the try-catch to the PROJECTILE case because it wouldn't let my put continue.
     
Thread Status:
Not open for further replies.

Share This Page