Solved Check for mob onPlayerDeath

Discussion in 'Spigot Plugin Development' started by Danijel72, Apr 16, 2018.

  1. Can somebody tell me how to check if mob killed a player?
    But not just any mob, I want to specify it, like Zombie, Creeper etc.

    I tried something like
    Code (Text):
    if (e.getEntity().getKiller() instanceof Zombie) {
     Bukkit.broadcastMessage(Utils.chat(plugin.getConfig().getString("Mobs.Zombie")));
    but it's not working...
    And if you ask for errors, im not getting any.
     
  2. Did you register the event in your onEnable()?
     
  3. Main class? post ur main class or Bukkit.getServer().getPluginManager().registerEvents(new YourClass(), this);
     
  4. Check it out:
    Code (Text):
    if (e.getEntity().getKiller().getType() == EntityType.ZOMBIE) {
     Bukkit.broadcastMessage(Utils.chat(plugin.getConfig().getString("Mobs.Zombie")));
     
  5. If you want to make it more dynamic you can use the name of the enum for the string location

    Example:
    Code (Text):
      String message = Utils.chat(plugin.getConfig().getString("Mobs." + e.getEntity().getKiller().getType().name()));
       Bukkit.broadcastMessage(message);
     
  6. e.getEntity().getKiller() only works if the player gets killed by another player. If the player got killed by anything other than a player, that method returns null; not really what you want.
    e.getEntity().getKiller().getType() will always return PLAYER or NULL, nothing else.


    Instead you have to look at who did damage to the player that died:

    First: Get the damage event of the last damage the player took with e.getEntity().getLastDamageCause()
    The returned EntityDamageEvent contains the damage cause: e.g. death by lava, suffocation, a projectile, an entity contact, ...
    However the event does not contain the information about the entity type that did the last damage.

    The EntityDamageByEntityEvent, a subtype of above event, allows you to get the entity itself that did the damage.
    Since the EntityDamageByEntityEvent is a subtype of the EntityDamageEvent, you can check (via instanceof) if the EntityDamageEvent returned by e.getEntity().getLastDamageCause() is an EntityDamageByEntityEvent.
    If it is, you can get the "killer" entity with EntityDamageByEntityEvent#getDamager and do stuff depending on its type (Entity#getType).


    Keep in mind: When a mob shoots/launches a player off a cliff, but the player doesn't die immediately but instead dies from the resulting fall damage, the last DamageEvent is the fall damage, not the entity that did the damage previously. So depending on your purpose you might have to keep track of the last x damage events that each player got affected by.
     
    • Useful Useful x 1
  7. Or simply using the EntityDeathEvent instead of the PlayerDeathEvent. The OP can then do some checks to see whether a player died or not and afterwards the OP would be able to get it's killer using e.getEntity().getKiller().
     
  8. Sure, the EntityDeathEvent would work as well but would provide zero benefits. Even worse: You'd have to check if the killed entity is a player or not. And according to the first post OP only wants to detect if a player gets killed by another entity - so why not directly use the PlayerDeathEvent?

    That's still the same method with the same problem: LivingEntity#getKiller only works when the killer is a player since the returned object type is Player and not Entity.

    Without using the damage event previously to the death itself it isn't possible to get the killer-entity (once again: unless the killer is a player).
     
    • Like Like x 1
  9. Yeah. Thinking back you'll have to get creative with the EntityDamageByEntityEvent.
     
  10. Back on to the topic. I suggest keeping track of the last damage dealt by an entity like Coww said.
    You should also discard the entity that dealt damage last if they haven't gotten any damage in a while, otherwise you'll end up with invalid information for instance, dying to a zombie that hit you once 5 minutes ago while you actually fell to your death.
     
  11. You are indeed correct, my apologies.

    Code (Java):

        @EventHandler
        public void onEntDeath(EntityDamageByEntityEvent e) {
    //  (if the entity is not a instance of player || if the damager is an instance of Player)
                return;
            if (((Player) e.getEntity()).getHealth() - e.getFinalDamage() > 0) // If the player's health - the final damage is bigger than 0 simply return
                return;
        Entity killer = e.getDamager();
        // Do sh1t  .-.
        }
     
    That's what I came up with. Hope it helps you out. Pretty easy to understand and use. Correct me if I've made any mistake.
     
  12. For Entity and killer im getting that they cannot be resolved to a variable...
     
  13. Have you sorted out your imports? Make sure to take a look at your imports again, not sure if that's the issue. Also make sure that the event is correct, "EntityDamageByEntityEvent".
     
  14. I checked my imports and seems like they're fine. Event is correct also..
     
  15. A screenshot of your IDE showing the full event code would help me understand your issue.
     
  16. instanceof needs to go to Entity.ZOMBIE (or maybe LivingEntity.ZOMBIE) but not EntityType.ZOMBIE.

    That would be if you did event.getEntity().getType().equals(EntityType.ZOMBIE)
     
  17. Thank you all! I figured it out :)
     

Share This Page