Search code examples
javaminecraftbukkit

How to get entity that killed player bukkit?


I am trying to make custom death messages when you get killed in certain ways. I want separate messages for when you get blown up by TNT or get blown up by a creeper. I tried debugging it and spawning a creeper and TNT and in the console it outputs the e.getEntity().getKiller() as null in the console. If I do e.getEntity().getKiller().getName(), it gives out an error.

here is my code for the debugger:

package me.Pale_Gray.BetterDeathMessages.deathmessages;

import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.PlayerDeathEvent;

public class DeathByTnt implements Listener{

    @EventHandler
    public void onPlayerDeath(PlayerDeathEvent e) {
        String msg = e.getDeathMessage();
        System.out.println((Player) e.getEntity().getKiller());
        if (e.getEntity().getLastDamageCause().getCause().equals(DamageCause.ENTITY_EXPLOSION)) {
            msg = ChatColor.translateAlternateColorCodes('&', "&cIt went off with a BANG!");
            e.setDeathMessage(msg);
        }
    }
    
}

I am only asking to focus in on the System.out.println((Player) e.getEntity().getKiller()); because I know the if statement isn't selective on entities.


Solution

    1. There are @Nullable annotations on methods and javadocs so you know what method can be null.
    2. PlayerDeathEvent#getEntity#getKiller method returns Player so you don't need to cast Player object to it.
      • Otherwise, this method only returns Player, if it killed by another living Player.
    3. Entity#getLastDamageCause method can return null
    4. getCause() method returns an enum so you don't need to use equals, you only need == for comparing enum values.
    5. You could check some other DamageCause fields, including ENTITY_EXPLOSION. Sometimes when creeper explodes the damage cause can be BLOCK_EXPLOSION, maybe because too far away.