Improve death events
This adds the ability to cancel the death events and to modify the sound an entity makes when dying. (In cases were no sound should it will be called with shouldPlaySound set to false allowing unsilencing of silent entities) It makes handling of entity deaths a lot nicer as you no longer need to listen on the damage event and calculate if the entity dies yourself to cancel the death which has the benefit of also receiving the dropped items and experience which is otherwise only properly possible by using internal code. == AT == public net.minecraft.world.entity.LivingEntity getDeathSound()Lnet/minecraft/sounds/SoundEvent; public net.minecraft.world.entity.LivingEntity getSoundVolume()F
This commit is contained in:
@@ -2517,7 +2517,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
@Override
|
||||
public void sendHealthUpdate() {
|
||||
FoodData foodData = this.getHandle().getFoodData();
|
||||
this.sendHealthUpdate(this.getScaledHealth(), foodData.getFoodLevel(), foodData.getSaturationLevel());
|
||||
// Paper start - cancellable death event
|
||||
ClientboundSetHealthPacket packet = new ClientboundSetHealthPacket(this.getScaledHealth(), foodData.getFoodLevel(), foodData.getSaturationLevel());
|
||||
if (this.getHandle().queueHealthUpdatePacket) {
|
||||
this.getHandle().queuedHealthUpdatePacket = packet;
|
||||
} else {
|
||||
this.getHandle().connection.send(packet);
|
||||
}
|
||||
// Paper end
|
||||
}
|
||||
|
||||
public void injectScaledMaxHealth(Collection<AttributeInstance> collection, boolean force) {
|
||||
|
||||
@@ -902,8 +902,15 @@ public class CraftEventFactory {
|
||||
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
|
||||
CraftWorld world = (CraftWorld) entity.getWorld();
|
||||
EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(world.getHandle(), damageSource.getEntity()));
|
||||
populateFields(victim, event); // Paper - make cancellable
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
// Paper start - make cancellable
|
||||
if (event.isCancelled()) {
|
||||
return event;
|
||||
}
|
||||
playDeathSound(victim, event);
|
||||
// Paper end
|
||||
victim.expToDrop = event.getDroppedExp();
|
||||
|
||||
for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
|
||||
@@ -921,7 +928,14 @@ public class CraftEventFactory {
|
||||
PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage);
|
||||
event.setKeepInventory(keepInventory);
|
||||
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
|
||||
populateFields(victim, event); // Paper - make cancellable
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
// Paper start - make cancellable
|
||||
if (event.isCancelled()) {
|
||||
return event;
|
||||
}
|
||||
playDeathSound(victim, event);
|
||||
// Paper end
|
||||
|
||||
victim.keepLevel = event.getKeepLevel();
|
||||
victim.newLevel = event.getNewLevel();
|
||||
@@ -944,6 +958,31 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
// Paper start - helper methods for making death event cancellable
|
||||
// Add information to death event
|
||||
private static void populateFields(net.minecraft.world.entity.LivingEntity victim, EntityDeathEvent event) {
|
||||
event.setReviveHealth(event.getEntity().getAttribute(org.bukkit.attribute.Attribute.MAX_HEALTH).getValue());
|
||||
event.setShouldPlayDeathSound(!victim.silentDeath && !victim.isSilent());
|
||||
net.minecraft.sounds.SoundEvent soundEffect = victim.getDeathSound();
|
||||
event.setDeathSound(soundEffect != null ? org.bukkit.craftbukkit.CraftSound.minecraftToBukkit(soundEffect) : null);
|
||||
event.setDeathSoundCategory(org.bukkit.SoundCategory.valueOf(victim.getSoundSource().name()));
|
||||
event.setDeathSoundVolume(victim.getSoundVolume());
|
||||
event.setDeathSoundPitch(victim.getVoicePitch());
|
||||
}
|
||||
|
||||
// Play death sound manually
|
||||
private static void playDeathSound(net.minecraft.world.entity.LivingEntity victim, EntityDeathEvent event) {
|
||||
if (event.shouldPlayDeathSound() && event.getDeathSound() != null && event.getDeathSoundCategory() != null) {
|
||||
net.minecraft.world.entity.player.Player source = victim instanceof net.minecraft.world.entity.player.Player ? (net.minecraft.world.entity.player.Player) victim : null;
|
||||
double x = event.getEntity().getLocation().getX();
|
||||
double y = event.getEntity().getLocation().getY();
|
||||
double z = event.getEntity().getLocation().getZ();
|
||||
net.minecraft.sounds.SoundEvent soundEffect = org.bukkit.craftbukkit.CraftSound.bukkitToMinecraft(event.getDeathSound());
|
||||
net.minecraft.sounds.SoundSource soundCategory = net.minecraft.sounds.SoundSource.valueOf(event.getDeathSoundCategory().name());
|
||||
victim.level().playSound(source, x, y, z, soundEffect, soundCategory, event.getDeathSoundVolume(), event.getDeathSoundPitch());
|
||||
}
|
||||
}
|
||||
// Paper end
|
||||
/**
|
||||
* Server methods
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user