Hi.
Some players have started killing others with ender crystals, so of course this needs to be counted as a PvP statistic. Because of this the event chain that leads to a player death can be quite complicated, as an example:
Player → shoots arrow → it blows up ender crystal → the explosion kills the player
(Or even more complex arrow → crystal → -> explosion → fall-damage)
I’m only doing the simpler one (for now) where the explosion kills the player directly - I think my code should work, but I could use a sanity check from someone more familiar with the Sponge cause API.
What I am unsure of is if event.getCause().allOf(EntityDamageSource.class)
returns the different hits the entity has taken, or if it has the chain I described above inside it.
Here is my code so far
@Listener
public void onEntityDeath(DestructEntityEvent.Death event) {
// Get the damage chain that lead to this death
List<EntityDamageSource> causes = event.getCause().allOf(EntityDamageSource.class);
Optional<Player> foundKiller = findKiller(causes, 0);
}
public Optional<Player> findKiller(List<EntityDamageSource> causes, int depth) {
if (causes.isEmpty() || causes.size() < depth) {
return Optional.empty();
}
EntityDamageSource damageSource = causes.get(depth);
Entity killerEntity = damageSource.getSource();
if (killerEntity instanceof Player) return Optional.of((Player) killerEntity);
if (killerEntity instanceof Projectile) return getShooter((Projectile) killerEntity);
// Go one deeper in the cause chain to see what killed the EnderCrystal
if (killerEntity instanceof EnderCrystal) return findKiller(causes, depth + 1);
return Optional.empty();
}