aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches
diff options
context:
space:
mode:
authorMax Lee <[email protected]>2018-09-08 02:14:48 +0200
committerZach <[email protected]>2018-09-07 20:14:48 -0400
commit4e30b91d4eabcf6738ed7881837968a4bdca6242 (patch)
tree3f2956fab391f65590ca9b93342f8f39ed959062 /Spigot-Server-Patches
parent2d45ec855f256473d2b3a1e2397a73a043e31a5d (diff)
downloadPaper-4e30b91d4eabcf6738ed7881837968a4bdca6242.tar.gz
Paper-4e30b91d4eabcf6738ed7881837968a4bdca6242.zip
Improve death events (#1362)
* Improve death events This adds the ability to cancel the events and to specify the sound.
Diffstat (limited to 'Spigot-Server-Patches')
-rw-r--r--Spigot-Server-Patches/0003-MC-Dev-fixes.patch24
-rw-r--r--Spigot-Server-Patches/0356-Improve-death-events.patch416
2 files changed, 428 insertions, 12 deletions
diff --git a/Spigot-Server-Patches/0003-MC-Dev-fixes.patch b/Spigot-Server-Patches/0003-MC-Dev-fixes.patch
index 1599093c0f..a14692b127 100644
--- a/Spigot-Server-Patches/0003-MC-Dev-fixes.patch
+++ b/Spigot-Server-Patches/0003-MC-Dev-fixes.patch
@@ -1,4 +1,4 @@
-From f4214b8d94c5a9690fa2e41f7b547545dec26549 Mon Sep 17 00:00:00 2001
+From 00d132db37f8d96814d5ce793d584937c0a0f896 Mon Sep 17 00:00:00 2001
From: Aikar <[email protected]>
Date: Wed, 30 Mar 2016 19:36:20 -0400
Subject: [PATCH] MC Dev fixes
@@ -110,19 +110,19 @@ index a540167d6..b2860555d 100644
return this.a(jsonelement, type, jsondeserializationcontext);
}
}
+diff --git a/src/main/java/net/minecraft/server/Registry.java b/src/main/java/net/minecraft/server/Registry.java
+index 723372f26..c38c3768c 100644
+--- a/src/main/java/net/minecraft/server/Registry.java
++++ b/src/main/java/net/minecraft/server/Registry.java
+@@ -1,3 +1,3 @@
+ package net.minecraft.server;
+
+-public interface Registry extends Iterable {}
++public interface Registry<T> extends Iterable<T> {} // Paper - decompile fix
diff --git a/src/main/java/net/minecraft/server/RegistryBlockID.java b/src/main/java/net/minecraft/server/RegistryBlockID.java
-index 58f47d0de..8860a0129 100644
+index 58f47d0de..03894df54 100644
--- a/src/main/java/net/minecraft/server/RegistryBlockID.java
+++ b/src/main/java/net/minecraft/server/RegistryBlockID.java
-@@ -8,7 +8,7 @@ import java.util.Iterator;
- import java.util.List;
- import javax.annotation.Nullable;
-
--public class RegistryBlockID<T> implements Registry<T> {
-+public class RegistryBlockID<T> implements Registry { // Paper - Fix decompile error
-
- private final IdentityHashMap<T, Integer> a;
- private final List<T> b;
@@ -26,7 +26,7 @@ public class RegistryBlockID<T> implements Registry<T> {
this.a.put(t0, Integer.valueOf(i));
@@ -252,5 +252,5 @@ index f5bcbdbe1..3190cadfc 100644
for (ZipEntry clazzEntry; (clazzEntry = nmsZipStream.getNextEntry()) != null; ) {
final String entryName = clazzEntry.getName();
--
-2.17.1
+2.18.0.windows.1
diff --git a/Spigot-Server-Patches/0356-Improve-death-events.patch b/Spigot-Server-Patches/0356-Improve-death-events.patch
new file mode 100644
index 0000000000..736c0785a2
--- /dev/null
+++ b/Spigot-Server-Patches/0356-Improve-death-events.patch
@@ -0,0 +1,416 @@
+From b8c6e5d80cd3b21db5b3d9a031439d37143eb467 Mon Sep 17 00:00:00 2001
+From: Phoenix616 <[email protected]>
+Date: Tue, 21 Aug 2018 01:39:35 +0100
+Subject: [PATCH] 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.
+
+diff --git a/src/main/java/net/minecraft/server/CombatTracker.java b/src/main/java/net/minecraft/server/CombatTracker.java
+index 7a076f3e4..bddd66e79 100644
+--- a/src/main/java/net/minecraft/server/CombatTracker.java
++++ b/src/main/java/net/minecraft/server/CombatTracker.java
+@@ -175,6 +175,7 @@ public class CombatTracker {
+ this.h = null;
+ }
+
++ public void reset() { this.g(); } // Paper - OBFHELPER
+ public void g() {
+ int i = this.f ? 300 : 100;
+
+diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
+index b0b49f4ff..d0dcce945 100644
+--- a/src/main/java/net/minecraft/server/Entity.java
++++ b/src/main/java/net/minecraft/server/Entity.java
+@@ -1471,6 +1471,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper
+ return false;
+ }
+
++ public void runKillTrigger(Entity entity, int kills, DamageSource damageSource) { this.a(entity, kills, damageSource); } // Paper - OBFHELPER
+ public void a(Entity entity, int i, DamageSource damagesource) {
+ if (entity instanceof EntityPlayer) {
+ CriterionTriggers.c.a((EntityPlayer) entity, this, damagesource);
+@@ -2267,6 +2268,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper
+
+ }
+
++ public void onKill(EntityLiving entityLiving) { this.b(entityLiving); } // Paper - OBFHELPER
+ public void b(EntityLiving entityliving) {}
+
+ protected boolean i(double d0, double d1, double d2) {
+@@ -2965,6 +2967,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper
+ return EnumPistonReaction.NORMAL;
+ }
+
++ public SoundCategory getDeathSoundCategory() { return bK();} // Paper - OBFHELPER
+ public SoundCategory bK() {
+ return SoundCategory.NEUTRAL;
+ }
+diff --git a/src/main/java/net/minecraft/server/EntityArmorStand.java b/src/main/java/net/minecraft/server/EntityArmorStand.java
+index dca497072..454c1e7d0 100644
+--- a/src/main/java/net/minecraft/server/EntityArmorStand.java
++++ b/src/main/java/net/minecraft/server/EntityArmorStand.java
+@@ -641,7 +641,8 @@ public class EntityArmorStand extends EntityLiving {
+ }
+
+ public void killEntity() {
+- org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, drops); // CraftBukkit - call event
++ org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, drops); // CraftBukkit - call event // Paper - make cancellable
++ if (event.isCancelled()) return; // Paper - make cancellable
+ this.die();
+ }
+
+diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
+index 14637be49..dec4b442c 100644
+--- a/src/main/java/net/minecraft/server/EntityLiving.java
++++ b/src/main/java/net/minecraft/server/EntityLiving.java
+@@ -75,14 +75,14 @@ public abstract class EntityLiving extends Entity {
+ public float aR;
+ public EntityHuman killer;
+ public int lastDamageByPlayerTime; // Paper - public
+- protected boolean aU;
++ protected boolean aU; protected void setDying(boolean dying) { this.aU = dying; } protected boolean isDying() { return this.aU; } // Paper - OBFHELPER
+ protected int ticksFarFromPlayer;
+ protected float aW;
+ protected float aX;
+ protected float aY;
+ protected float aZ;
+ protected float ba;
+- protected int bb;
++ protected int bb; protected int getKillCount() { return this.bb; } // Paper - OBFHELPER
+ public float lastDamage;
+ protected boolean bd;
+ public float be;
+@@ -117,6 +117,7 @@ public abstract class EntityLiving extends Entity {
+ public org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes;
+ public boolean collides = true;
+ public boolean canPickUpLoot;
++ public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event
+
+ @Override
+ public float getBukkitYaw() {
+@@ -970,13 +971,17 @@ public abstract class EntityLiving extends Entity {
+
+ if (this.getHealth() <= 0.0F) {
+ if (!this.e(damagesource)) {
+- SoundEffect soundeffect = this.cf();
++ // Paper start - moved into CraftEventFactory event caller for cancellable death event
++ //SoundEffect soundeffect = this.cf();
+
+- if (flag1 && soundeffect != null) {
+- this.a(soundeffect, this.cq(), this.cr());
+- }
++ //if (flag1 && soundeffect != null) {
++ // this.a(soundeffect, this.cq(), this.cr());
++ //}
++ this.silentDeath = !flag1; // mark entity as dying silently
++ // Paper end
+
+ this.die(damagesource);
++ this.silentDeath = false; // Paper - cancellable death event - reset to default
+ }
+ } else if (flag1) {
+ this.c(damagesource);
+@@ -1114,16 +1119,20 @@ public abstract class EntityLiving extends Entity {
+ Entity entity = damagesource.getEntity();
+ EntityLiving entityliving = this.ci();
+
+- if (this.bb >= 0 && entityliving != null) {
+- entityliving.a(this, this.bb, damagesource);
+- }
++ // Paper start - move down to make death event cancellable
++ //if (this.bb >= 0 && entityliving != null) {
++ // entityliving.a(this, this.bb, damagesource);
++ //}
+
+- if (entity != null) {
+- entity.b(this);
+- }
++ //if (entity != null) {
++ // entity.b(this);
++ //}
+
+- this.aU = true;
+- this.getCombatTracker().g();
++ //this.aU = true;
++ //this.getCombatTracker().g();
++
++ org.bukkit.event.entity.EntityDeathEvent deathEvent = null;
++ //Paper end
+ if (!this.world.isClientSide) {
+ int i = 0;
+
+@@ -1136,15 +1145,32 @@ public abstract class EntityLiving extends Entity {
+
+ this.a(flag, i, damagesource);
+ // CraftBukkit start - Call death event
+- CraftEventFactory.callEntityDeathEvent(this, this.drops);
++ deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops); // Paper - cancellable death event
+ this.drops = new ArrayList<org.bukkit.inventory.ItemStack>();
+ } else {
+- CraftEventFactory.callEntityDeathEvent(this);
++ deathEvent = CraftEventFactory.callEntityDeathEvent(this); // Paper - cancellable death event
+ // CraftBukkit end
+ }
+ }
+
+- this.world.broadcastEntityEffect(this, (byte) 3);
++ // Paper start - cancellable death event
++ if (deathEvent == null || !deathEvent.isCancelled()) {
++ // triggers and stats got moved down
++ if (this.getKillCount() >= 0 && entityliving != null) {
++ entityliving.runKillTrigger(this, this.getKillCount(), damagesource);
++ }
++
++ if (entity != null) {
++ entity.onKill(this);
++ }
++
++ this.getCombatTracker().reset();
++ this.setDying(true);
++ this.world.broadcastEntityEffect(this, (byte) 3);
++ } else {
++ this.setHealth((float) deathEvent.getReviveHealth());
++ }
++ // Paper end
+ }
+ }
+
+@@ -1198,6 +1224,7 @@ public abstract class EntityLiving extends Entity {
+ return SoundEffects.bX;
+ }
+
++ @Nullable public SoundEffect getDeathSoundEffect() { return cf();} // Paper - OBFHELPER
+ @Nullable
+ protected SoundEffect cf() {
+ return SoundEffects.bS;
+@@ -1583,10 +1610,12 @@ public abstract class EntityLiving extends Entity {
+
+ }
+
++ public float getDeathSoundVolume() { return cq();} // Paper - OBFHELPER
+ protected float cq() {
+ return 1.0F;
+ }
+
++ public float getDeathSoundPitch() { return cr();} // Paper - OBFHELPER
+ protected float cr() {
+ return this.isBaby() ? (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.5F : (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F;
+ }
+diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
+index 4ff505cfa..6afb6cf7b 100644
+--- a/src/main/java/net/minecraft/server/EntityPlayer.java
++++ b/src/main/java/net/minecraft/server/EntityPlayer.java
+@@ -79,6 +79,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
+ }
+ // Paper end
+ private int containerUpdateDelay; // Paper
++ // Paper start - cancellable death event
++ public boolean queueHealthUpdatePacket = false;
++ public net.minecraft.server.PacketPlayOutUpdateHealth queuedHealthUpdatePacket;
++ // Paper end
+
+ // CraftBukkit start
+ public String displayName;
+@@ -436,9 +440,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
+ public void die(DamageSource damagesource) {
+ boolean flag = this.world.getGameRules().getBoolean("showDeathMessages");
+
+- this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.getCombatTracker(), PacketPlayOutCombatEvent.EnumCombatEventType.ENTITY_DIED, flag));
++ //this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.getCombatTracker(), PacketPlayOutCombatEvent.EnumCombatEventType.ENTITY_DIED, flag)); // Paper - moved down for cancellable death event
+ // CraftBukkit start - fire PlayerDeathEvent
+ if (this.dead) {
++ this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.getCombatTracker(), PacketPlayOutCombatEvent.EnumCombatEventType.ENTITY_DIED, flag)); // Paper - moved down for cancellable death event
+ return;
+ }
+ java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<org.bukkit.inventory.ItemStack>(this.inventory.getSize());
+@@ -456,6 +461,16 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
+
+ String deathmessage = chatmessage.toPlainText();
+ org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, deathmessage, keepInventory);
++ // Paper start - cancellable death event
++ if (event.isCancelled()) {
++ // make compatible with plugins that might have already set the health in an event listener
++ if (this.getHealth() <= 0) {
++ this.setHealth((float) event.getReviveHealth());
++ }
++ return;
++ }
++ this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.getCombatTracker(), PacketPlayOutCombatEvent.EnumCombatEventType.ENTITY_DIED, flag));
++ // Paper end
+
+ String deathMessage = event.getDeathMessage();
+
+@@ -608,8 +623,17 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
+ }
+ }
+ }
+-
+- return super.damageEntity(damagesource, f);
++ // Paper start - cancellable death events
++ //return super.damageEntity(damagesource, f);
++ this.queueHealthUpdatePacket = true;
++ boolean damaged = super.damageEntity(damagesource, f);
++ this.queueHealthUpdatePacket = false;
++ if (this.queuedHealthUpdatePacket != null) {
++ this.playerConnection.sendPacket(this.queuedHealthUpdatePacket);
++ this.queuedHealthUpdatePacket = null;
++ }
++ return damaged;
++ // Paper end
+ }
+ }
+ }
+diff --git a/src/main/java/net/minecraft/server/RegistryMaterials.java b/src/main/java/net/minecraft/server/RegistryMaterials.java
+index d26abb419..aaedbc3b7 100644
+--- a/src/main/java/net/minecraft/server/RegistryMaterials.java
++++ b/src/main/java/net/minecraft/server/RegistryMaterials.java
+@@ -29,6 +29,7 @@ public class RegistryMaterials<K, V> extends RegistrySimple<K, V> implements Reg
+ return super.get(k0);
+ }
+
++ @Nullable public K getByValue(V value) { return this.b(value); } // Paper - OBFHELPER
+ @Nullable
+ public K b(V v0) {
+ return this.b.get(v0);
+diff --git a/src/main/java/net/minecraft/server/SoundEffect.java b/src/main/java/net/minecraft/server/SoundEffect.java
+index ec37e237f..8e0da7bd7 100644
+--- a/src/main/java/net/minecraft/server/SoundEffect.java
++++ b/src/main/java/net/minecraft/server/SoundEffect.java
+@@ -2,7 +2,7 @@ package net.minecraft.server;
+
+ public class SoundEffect {
+
+- public static final RegistryMaterials<MinecraftKey, SoundEffect> a = new RegistryMaterials();
++ public static final RegistryMaterials<MinecraftKey, SoundEffect> a = new RegistryMaterials(); public static RegistryMaterials<MinecraftKey, SoundEffect> getRegistry() { return a; }// Paper - OBFHELPER
+ private final MinecraftKey b;
+ private static int c;
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftSound.java b/src/main/java/org/bukkit/craftbukkit/CraftSound.java
+index 8871c6f3a..84f4cb91e 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftSound.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftSound.java
+@@ -560,6 +560,22 @@ public enum CraftSound {
+ WEATHER_RAIN_ABOVE("weather.rain.above");
+ private final String minecraftKey;
+
++ // Paper start - cancellable death event
++ public static CraftSound getBySoundEffect(final SoundEffect effect) {
++ MinecraftKey key = SoundEffect.getRegistry().getByValue(effect);
++ Preconditions.checkArgument(key != null, "Key for sound effect %s not found?", effect.toString());
++
++ return valueOf(key.getKey().replace('.', '_').toUpperCase(java.util.Locale.ENGLISH));
++ }
++
++ public static Sound getSoundByEffect(final SoundEffect effect) {
++ return Sound.valueOf(getBySoundEffect(effect).name());
++ }
++
++ public static SoundEffect getSoundEffect(final Sound sound) {
++ return getSoundEffect(getSound(sound));
++ }
++ // Paper end
+ CraftSound(String minecraftKey) {
+ this.minecraftKey = minecraftKey;
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+index 5f480ac06..d59d86efc 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+@@ -1612,7 +1612,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+ }
+
+ public void sendHealthUpdate() {
+- getHandle().playerConnection.sendPacket(new PacketPlayOutUpdateHealth(getScaledHealth(), getHandle().getFoodData().getFoodLevel(), getHandle().getFoodData().getSaturationLevel()));
++ // Paper start - cancellable death event
++ //getHandle().playerConnection.sendPacket(new PacketPlayOutUpdateHealth(getScaledHealth(), getHandle().getFoodData().getFoodLevel(), getHandle().getFoodData().getSaturationLevel()));
++ PacketPlayOutUpdateHealth packet = new PacketPlayOutUpdateHealth(getScaledHealth(), getHandle().getFoodData().getFoodLevel(), getHandle().getFoodData().getSaturationLevel());
++ if (this.getHandle().queueHealthUpdatePacket) {
++ this.getHandle().queuedHealthUpdatePacket = packet;
++ } else {
++ this.getHandle().playerConnection.sendPacket(packet);
++ }
++ // Paper end
+ }
+
+ public void injectScaledMaxHealth(Collection<AttributeInstance> collection, boolean force) {
+diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+index cce4acc0b..f1a3ca950 100644
+--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+@@ -392,9 +392,16 @@ public class CraftEventFactory {
+ public static EntityDeathEvent callEntityDeathEvent(EntityLiving victim, List<org.bukkit.inventory.ItemStack> drops) {
+ CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
+ EntityDeathEvent event = new EntityDeathEvent(entity, drops, victim.getExpReward());
++ populateFields(victim, event); // Paper - make cancellable
+ CraftWorld world = (CraftWorld) entity.getWorld();
+ 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()) {
+@@ -410,8 +417,15 @@ public class CraftEventFactory {
+ CraftPlayer entity = victim.getBukkitEntity();
+ PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage);
+ event.setKeepInventory(keepInventory);
++ populateFields(victim, event); // Paper - make cancellable
+ org.bukkit.World world = entity.getWorld();
+ 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();
+@@ -432,6 +446,31 @@ public class CraftEventFactory {
+ return event;
+ }
+
++ // Paper start - helper methods for making death event cancellable
++ // Add information to death event
++ private static void populateFields(EntityLiving victim, EntityDeathEvent event) {
++ event.setReviveHealth(event.getEntity().getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).getValue());
++ event.setShouldPlayDeathSound(!victim.silentDeath && !victim.isSilent());
++ SoundEffect soundEffect = victim.getDeathSoundEffect();
++ event.setDeathSound(soundEffect != null ? org.bukkit.craftbukkit.CraftSound.getSoundByEffect(soundEffect) : null);
++ event.setDeathSoundCategory(org.bukkit.SoundCategory.valueOf(victim.getDeathSoundCategory().name()));
++ event.setDeathSoundVolume(victim.getDeathSoundVolume());
++ event.setDeathSoundPitch(victim.getDeathSoundPitch());
++ }
++
++ // Play death sound manually
++ private static void playDeathSound(EntityLiving victim, EntityDeathEvent event) {
++ if (event.shouldPlayDeathSound() && event.getDeathSound() != null && event.getDeathSoundCategory() != null) {
++ EntityHuman source = victim instanceof EntityHuman ? (EntityHuman) victim : null;
++ double x = event.getEntity().getLocation().getX();
++ double y = event.getEntity().getLocation().getY();
++ double z = event.getEntity().getLocation().getZ();
++ SoundEffect soundEffect = org.bukkit.craftbukkit.CraftSound.getSoundEffect(event.getDeathSound());
++ SoundCategory soundCategory = SoundCategory.valueOf(event.getDeathSoundCategory().name());
++ victim.world.sendSoundEffect(source, x, y, z, soundEffect, soundCategory, event.getDeathSoundVolume(), event.getDeathSoundPitch());
++ }
++ }
++ // Paper end
+ /**
+ * Server methods
+ */
+--
+2.18.0.windows.1
+