mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-27 04:55:47 +01:00
b3f265d1b1
Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 0ca45a21 #503: Add PlayerHarvestBlockEvent dfa80a52 SPIGOT-5930: Add PlayerRespawnEvent#isAnchorSpawn CraftBukkit Changes:145921e2
#676: Add PlayerHarvestBlockEvent47abffa2
SPIGOT-5929: Angered zombified piglins do not inherit killed_by_player status7f6b4f58
SPIGOT-5930: Add PlayerRespawnEvent#isAnchorSpawn94eff632
SPIGOT-5867, MC-193339: NPE during shutdown when rcon enabled with no password068618eb
SPIGOT-5927: Some items NBT data disappears Spigot Changes: beb7d47c Rebuild patches Fixes #3738
449 lines
22 KiB
Diff
449 lines
22 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Phoenix616 <mail@moep.tv>
|
|
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 6281f7900afab3ef1c9ba3c034b91cbfa1900f50..3c2f8407906879c8dca07b538f59f4bbd31b278f 100644
|
|
--- a/src/main/java/net/minecraft/server/CombatTracker.java
|
|
+++ b/src/main/java/net/minecraft/server/CombatTracker.java
|
|
@@ -192,6 +192,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 55f8863f823836065f4de8240bfeb490bd391a55..a9664f03b8b7d2c12565b8c08891c7021aa5482b 100644
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
@@ -1460,6 +1460,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
}
|
|
// CraftBukkit end
|
|
|
|
+ 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);
|
|
@@ -2349,6 +2350,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
this.fallDistance = 0.0F;
|
|
}
|
|
|
|
+ public void onKill(EntityLiving entityLiving) { this.a_(entityLiving); } // Paper - OBFHELPER
|
|
public void a_(EntityLiving entityliving) {}
|
|
|
|
protected void k(double d0, double d1, double d2) {
|
|
diff --git a/src/main/java/net/minecraft/server/EntityArmorStand.java b/src/main/java/net/minecraft/server/EntityArmorStand.java
|
|
index d5c09152acc93b25d626284071599afdbd76b709..51e9f4a6e09474a7489d2872a800308ee3f02e46 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityArmorStand.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityArmorStand.java
|
|
@@ -701,7 +701,8 @@ public class EntityArmorStand extends EntityLiving {
|
|
|
|
@Override
|
|
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/EntityFox.java b/src/main/java/net/minecraft/server/EntityFox.java
|
|
index 95874526516291607a44ae2213d4d6d65edfe18d..e6275a9fe6cd988fe4661966fd48149c3e73408c 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityFox.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityFox.java
|
|
@@ -576,15 +576,25 @@ public class EntityFox extends EntityAnimal {
|
|
}
|
|
|
|
@Override
|
|
- protected void d(DamageSource damagesource) {
|
|
- ItemStack itemstack = this.getEquipment(EnumItemSlot.MAINHAND);
|
|
+ protected org.bukkit.event.entity.EntityDeathEvent d(DamageSource damagesource) { // Paper
|
|
+ ItemStack itemstack = this.getEquipment(EnumItemSlot.MAINHAND).cloneItemStack(); // Paper
|
|
+
|
|
+ // Paper start - Cancellable death event
|
|
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = super.d(damagesource);
|
|
+
|
|
+ // Below is code to drop
|
|
+
|
|
+ if (deathEvent == null || deathEvent.isCancelled()) {
|
|
+ return deathEvent;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
if (!itemstack.isEmpty()) {
|
|
this.a(itemstack);
|
|
this.setSlot(EnumItemSlot.MAINHAND, ItemStack.b);
|
|
}
|
|
|
|
- super.d(damagesource);
|
|
+ return deathEvent; // Paper
|
|
}
|
|
|
|
public static boolean a(EntityFox entityfox, EntityLiving entityliving) {
|
|
diff --git a/src/main/java/net/minecraft/server/EntityHorseChestedAbstract.java b/src/main/java/net/minecraft/server/EntityHorseChestedAbstract.java
|
|
index c2a3bd8f25e91f79723074d93f6a646a8ce76d8c..4934e71225fe1242615660a379e797e212040ed3 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityHorseChestedAbstract.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityHorseChestedAbstract.java
|
|
@@ -50,11 +50,19 @@ public abstract class EntityHorseChestedAbstract extends EntityHorseAbstract {
|
|
this.a((IMaterial) Blocks.CHEST);
|
|
}
|
|
|
|
- this.setCarryingChest(false);
|
|
+ //this.setCarryingChest(false); // Paper - moved to post death logic
|
|
}
|
|
|
|
}
|
|
|
|
+ // Paper start
|
|
+ protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {
|
|
+ if (this.isCarryingChest() && (event == null || !event.isCancelled())) {
|
|
+ this.setCarryingChest(false);
|
|
+ }
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
@Override
|
|
public void saveData(NBTTagCompound nbttagcompound) {
|
|
super.saveData(nbttagcompound);
|
|
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
|
|
index 4b249a644c680a7cc64b0d31cf453f94ff2b6a0c..d6a98bb7fc107649c179cded2d37c06a41146a89 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
|
@@ -95,7 +95,7 @@ public abstract class EntityLiving extends Entity {
|
|
protected float aS;
|
|
protected float aT;
|
|
protected float aU;
|
|
- protected int aV;
|
|
+ protected int aV; protected int getKillCount() { return this.aV; } // Paper - OBFHELPER
|
|
public float lastDamage;
|
|
protected boolean jumping;
|
|
public float aY;
|
|
@@ -139,6 +139,7 @@ public abstract class EntityLiving extends Entity {
|
|
public Set<UUID> collidableExemptions = new HashSet<>();
|
|
public boolean canPickUpLoot;
|
|
public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper
|
|
+ public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event
|
|
|
|
@Override
|
|
public float getBukkitYaw() {
|
|
@@ -1248,13 +1249,17 @@ public abstract class EntityLiving extends Entity {
|
|
if (knockbackCancelled) this.world.broadcastEntityEffect(this, (byte) 2); // Paper - Disable explosion knockback
|
|
if (this.dk()) {
|
|
if (!this.f(damagesource)) {
|
|
- SoundEffect soundeffect = this.getSoundDeath();
|
|
+ // Paper start - moved into CraftEventFactory event caller for cancellable death event
|
|
+ //SoundEffect soundeffect = this.getSoundDeath();
|
|
|
|
- if (flag1 && soundeffect != null) {
|
|
- this.playSound(soundeffect, this.getSoundVolume(), this.dG());
|
|
- }
|
|
+// if (flag1 && soundeffect != null) {
|
|
+// this.playSound(soundeffect, this.getSoundVolume(), this.dG());
|
|
+// }
|
|
+ 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);
|
|
@@ -1392,6 +1397,7 @@ public abstract class EntityLiving extends Entity {
|
|
Entity entity = damagesource.getEntity();
|
|
EntityLiving entityliving = this.getKillingEntity();
|
|
|
|
+ /* // Paper - move down to make death event cancellable
|
|
if (this.aV >= 0 && entityliving != null) {
|
|
entityliving.a(this, this.aV, damagesource);
|
|
}
|
|
@@ -1403,16 +1409,36 @@ public abstract class EntityLiving extends Entity {
|
|
if (this.isSleeping()) {
|
|
this.entityWakeup();
|
|
}
|
|
+ */ // Paper
|
|
|
|
this.killed = true;
|
|
- this.getCombatTracker().g();
|
|
+ //this.getCombatTracker().g(); // Paper
|
|
if (!this.world.isClientSide) {
|
|
- this.d(damagesource);
|
|
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = this.d(damagesource);
|
|
+ if (deathEvent == null || !deathEvent.isCancelled()) {
|
|
+ if (this.getKillCount() >= 0 && entityliving != null) {
|
|
+ entityliving.runKillTrigger(this, this.getKillCount(), damagesource);
|
|
+ }
|
|
+ if (entity != null) {
|
|
+ entity.onKill(this);
|
|
+ }
|
|
+ if (this.isSleeping()) {
|
|
+ this.entityWakeup();
|
|
+ }
|
|
+ this.getCombatTracker().reset();
|
|
+ } else {
|
|
+ this.killed = false;
|
|
+ this.setHealth((float) deathEvent.getReviveHealth());
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
this.g(entityliving);
|
|
}
|
|
|
|
+ if (this.killed) { // Paper
|
|
this.world.broadcastEntityEffect(this, (byte) 3);
|
|
this.setPose(EntityPose.DYING);
|
|
+ } // Paper
|
|
}
|
|
}
|
|
|
|
@@ -1420,7 +1446,7 @@ public abstract class EntityLiving extends Entity {
|
|
if (!this.world.isClientSide) {
|
|
boolean flag = false;
|
|
|
|
- if (entityliving instanceof EntityWither) {
|
|
+ if (this.killed && entityliving instanceof EntityWither) { // Paper
|
|
if (this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) {
|
|
BlockPosition blockposition = this.getChunkCoordinates();
|
|
IBlockData iblockdata = Blocks.WITHER_ROSE.getBlockData();
|
|
@@ -1441,7 +1467,8 @@ public abstract class EntityLiving extends Entity {
|
|
}
|
|
}
|
|
|
|
- protected void d(DamageSource damagesource) {
|
|
+ protected org.bukkit.event.entity.EntityDeathEvent processDeath(DamageSource damagesource) { return d(damagesource); } // Paper - OBFHELPER
|
|
+ protected org.bukkit.event.entity.EntityDeathEvent d(DamageSource damagesource) { // Paper
|
|
Entity entity = damagesource.getEntity();
|
|
int i;
|
|
|
|
@@ -1454,22 +1481,26 @@ public abstract class EntityLiving extends Entity {
|
|
boolean flag = this.lastDamageByPlayerTime > 0;
|
|
|
|
this.dropInventory(); // CraftBukkit - from below
|
|
+ org.bukkit.event.entity.EntityDeathEvent deathEvent; // Paper
|
|
if (this.cV() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) {
|
|
this.a(damagesource, flag);
|
|
this.dropDeathLoot(damagesource, i, flag);
|
|
// CraftBukkit start - Call death event
|
|
- CraftEventFactory.callEntityDeathEvent(this, this.drops);
|
|
- this.drops = new ArrayList<org.bukkit.inventory.ItemStack>();
|
|
+ deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops); // Paper
|
|
} else {
|
|
- CraftEventFactory.callEntityDeathEvent(this);
|
|
+ deathEvent = CraftEventFactory.callEntityDeathEvent(this); // Paper
|
|
// CraftBukkit end
|
|
}
|
|
+ this.postDeathDropItems(deathEvent); // Paper
|
|
+ this.drops = new ArrayList<>(); // Paper
|
|
|
|
// this.dropInventory();// CraftBukkit - moved up
|
|
this.dropExperience();
|
|
+ return deathEvent; // Paper
|
|
}
|
|
|
|
protected void dropInventory() {}
|
|
+ protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {} // Paper - method for post death logic that cannot be ran before the event is potentially cancelled
|
|
|
|
// CraftBukkit start
|
|
public int getExpReward() {
|
|
@@ -1554,6 +1585,7 @@ public abstract class EntityLiving extends Entity {
|
|
return SoundEffects.ENTITY_GENERIC_HURT;
|
|
}
|
|
|
|
+ public final SoundEffect getDeathSoundEffect() { return this.getSoundDeath(); } // Paper - OBFHELPER
|
|
@Nullable
|
|
protected SoundEffect getSoundDeath() {
|
|
return SoundEffects.ENTITY_GENERIC_DEATH;
|
|
@@ -2073,10 +2105,12 @@ public abstract class EntityLiving extends Entity {
|
|
|
|
}
|
|
|
|
+ public final float getDeathSoundVolume() { return this.getSoundVolume(); } // Paper - OBFHELPER
|
|
protected float getSoundVolume() {
|
|
return 1.0F;
|
|
}
|
|
|
|
+ public float getSoundPitch() { return dG();} // Paper - OBFHELPER
|
|
protected float dG() {
|
|
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 dc8f88d102c06d8fb28ffd66de36f32efec54ff2..650579eb1bb73416b629229fce897d2941bd3b0d 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
@@ -80,6 +80,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
|
public int ping;
|
|
public boolean viewingCredits;
|
|
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;
|
|
@@ -579,6 +583,15 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
|
|
|
String deathmessage = defaultMessage.getString();
|
|
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;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
// SPIGOT-943 - only call if they have an inventory open
|
|
if (this.activeContainer != this.defaultContainer) {
|
|
@@ -730,8 +743,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/org/bukkit/craftbukkit/CraftSound.java b/src/main/java/org/bukkit/craftbukkit/CraftSound.java
|
|
index 7b565ddfffd0b9c78392ee115ef9c20ab89a3380..d78b9fd608da691220f1edeff506b36e3a88f515 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftSound.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftSound.java
|
|
@@ -996,6 +996,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 = IRegistry.SOUND_EVENT.getKey(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 21aa19081ca3d9c20ea8e401c2a4b830ba667a51..1398d911456b6e685bf7292687c5f5a4dcea5b7e 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -1762,7 +1762,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<AttributeModifiable> 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 f6c8c371e22272983f80268dab8009ee029bed2a..37f6fdf1be6d0f8a4ec4b9998fa710876b5515c9 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
@@ -783,9 +783,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()) {
|
|
@@ -801,8 +808,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();
|
|
@@ -819,6 +833,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());
|
|
+ net.minecraft.server.SoundEffect soundEffect = victim.getDeathSoundEffect();
|
|
+ event.setDeathSound(soundEffect != null ? org.bukkit.craftbukkit.CraftSound.getSoundByEffect(soundEffect) : null);
|
|
+ event.setDeathSoundCategory(org.bukkit.SoundCategory.valueOf(victim.getSoundCategory().name()));
|
|
+ event.setDeathSoundVolume(victim.getDeathSoundVolume());
|
|
+ event.setDeathSoundPitch(victim.getSoundPitch());
|
|
+ }
|
|
+
|
|
+ // 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();
|
|
+ net.minecraft.server.SoundEffect soundEffect = org.bukkit.craftbukkit.CraftSound.getSoundEffect(event.getDeathSound());
|
|
+ net.minecraft.server.SoundCategory soundCategory = net.minecraft.server.SoundCategory.valueOf(event.getDeathSoundCategory().name());
|
|
+ victim.world.sendSoundEffect(source, x, y, z, soundEffect, soundCategory, event.getDeathSoundVolume(), event.getDeathSoundPitch());
|
|
+ }
|
|
+ }
|
|
+ // Paper end
|
|
/**
|
|
* Server methods
|
|
*/
|