Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-12-15 11:00:06 +01:00
426 Zeilen
21 KiB
Diff
426 Zeilen
21 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/level/EntityPlayer.java b/src/main/java/net/minecraft/server/level/EntityPlayer.java
|
||
|
index b581a6d3ec06498a4c6db92eb50c5d2b28038131..ae9e0f55ddc194aaef1e57e81863569d9bc7b8f3 100644
|
||
|
--- a/src/main/java/net/minecraft/server/level/EntityPlayer.java
|
||
|
+++ b/src/main/java/net/minecraft/server/level/EntityPlayer.java
|
||
|
@@ -214,6 +214,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.network.protocol.game.PacketPlayOutUpdateHealth queuedHealthUpdatePacket;
|
||
|
+ // Paper end
|
||
|
|
||
|
// CraftBukkit start
|
||
|
public String displayName;
|
||
|
@@ -717,6 +721,15 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
||
|
IChatBaseComponent defaultMessage = this.getCombatTracker().getDeathMessage();
|
||
|
|
||
|
org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, PaperAdventure.asAdventure(defaultMessage), defaultMessage.getString(), keepInventory); // Paper - Adventure
|
||
|
+ // 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) {
|
||
|
@@ -863,8 +876,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/world/damagesource/CombatTracker.java b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java
|
||
|
index f6f79ed9c38206cc6a4feb5504e854a476868aec..7d2b947b3c2b255c01241f2c4a6d7377a0a7c671 100644
|
||
|
--- a/src/main/java/net/minecraft/world/damagesource/CombatTracker.java
|
||
|
+++ b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java
|
||
|
@@ -203,6 +203,7 @@ public class CombatTracker {
|
||
|
this.h = null;
|
||
|
}
|
||
|
|
||
|
+ public final void reset() { this.g(); } // Paper - OBFHELPER
|
||
|
public void g() {
|
||
|
int i = this.f ? 300 : 100;
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||
|
index 37497d7ff04b84d4758997970dbdbf88b40d0493..28390d3830ed9f3f5d97ab38913e6c40f9943a70 100644
|
||
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||
|
@@ -1538,6 +1538,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
|
||
|
}
|
||
|
// CraftBukkit end
|
||
|
|
||
|
+ public final 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);
|
||
|
@@ -2442,6 +2443,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
|
||
|
this.fallDistance = 0.0F;
|
||
|
}
|
||
|
|
||
|
+ public final void onKill(WorldServer worldserver, EntityLiving entityLiving) { this.a(worldserver, entityLiving); } // Paper - OBFHELPER
|
||
|
public void a(WorldServer worldserver, EntityLiving entityliving) {}
|
||
|
|
||
|
protected void l(double d0, double d1, double d2) {
|
||
|
diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
||
|
index bfbfdeffe668ac3363ffdab2c5cb7b19217f55ea..e20acbd904f12e9036cb0565d6aa9a3f63008d43 100644
|
||
|
--- a/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
||
|
+++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
||
|
@@ -189,7 +189,7 @@ public abstract class EntityLiving extends Entity {
|
||
|
protected float aL;
|
||
|
protected float aM;
|
||
|
protected float aN;
|
||
|
- protected int aO;
|
||
|
+ protected int aO;protected int getKillCount() { return this.aO; } // Paper - OBFHELPER
|
||
|
public float lastDamage;
|
||
|
protected boolean jumping;
|
||
|
public float aR;
|
||
|
@@ -233,6 +233,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() {
|
||
|
@@ -1348,13 +1349,17 @@ public abstract class EntityLiving extends Entity {
|
||
|
if (knockbackCancelled) this.world.broadcastEntityEffect(this, (byte) 2); // Paper - Disable explosion knockback
|
||
|
if (this.dl()) {
|
||
|
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.dH());
|
||
|
- }
|
||
|
+// if (flag1 && soundeffect != null) {
|
||
|
+// this.playSound(soundeffect, this.getSoundVolume(), this.dH());
|
||
|
+// }
|
||
|
+ 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);
|
||
|
@@ -1493,6 +1498,7 @@ public abstract class EntityLiving extends Entity {
|
||
|
Entity entity = damagesource.getEntity();
|
||
|
EntityLiving entityliving = this.getKillingEntity();
|
||
|
|
||
|
+ /* // Paper - move down to make death event cancellable - this is the runKillTrigger below
|
||
|
if (this.aO >= 0 && entityliving != null) {
|
||
|
entityliving.a(this, this.aO, damagesource);
|
||
|
}
|
||
|
@@ -1500,20 +1506,40 @@ public abstract class EntityLiving extends Entity {
|
||
|
if (this.isSleeping()) {
|
||
|
this.entityWakeup();
|
||
|
}
|
||
|
+ */ // Paper
|
||
|
|
||
|
this.killed = true;
|
||
|
- this.getCombatTracker().g();
|
||
|
+ // this.getCombatTracker().g(); // Paper - moved into if below as .reset()
|
||
|
if (this.world instanceof WorldServer) {
|
||
|
if (entity != null) {
|
||
|
- entity.a((WorldServer) this.world, this);
|
||
|
+ // entity.a((WorldServer) this.world, this); // Paper - move below into if for onKill
|
||
|
}
|
||
|
|
||
|
- this.d(damagesource);
|
||
|
+ // Paper start
|
||
|
+ 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 (this.isSleeping()) {
|
||
|
+ this.entityWakeup();
|
||
|
+ }
|
||
|
+ this.getCombatTracker().reset();
|
||
|
+ if (entity != null) {
|
||
|
+ entity.onKill((WorldServer) this.world, this);
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ this.killed = false;
|
||
|
+ this.setHealth((float) deathEvent.getReviveHealth());
|
||
|
+ }
|
||
|
+ // Paper end
|
||
|
this.f(entityliving);
|
||
|
}
|
||
|
|
||
|
+ if (this.killed) { // Paper
|
||
|
this.world.broadcastEntityEffect(this, (byte) 3);
|
||
|
this.setPose(EntityPose.DYING);
|
||
|
+ } // Paper
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -1521,7 +1547,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();
|
||
|
@@ -1549,7 +1575,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;
|
||
|
|
||
|
@@ -1567,15 +1594,18 @@ public abstract class EntityLiving extends Entity {
|
||
|
this.dropDeathLoot(damagesource, i, flag);
|
||
|
}
|
||
|
// CraftBukkit start - Call death event
|
||
|
- CraftEventFactory.callEntityDeathEvent(this, this.drops);
|
||
|
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops); // Paper
|
||
|
+ this.postDeathDropItems(deathEvent); // Paper
|
||
|
this.drops = new ArrayList<>();
|
||
|
// CraftBukkit end
|
||
|
|
||
|
// 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() {
|
||
|
@@ -1660,6 +1690,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;
|
||
|
@@ -2196,10 +2227,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 dH();} // Paper - OBFHELPER
|
||
|
protected float dH() {
|
||
|
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/world/entity/animal/EntityFox.java b/src/main/java/net/minecraft/world/entity/animal/EntityFox.java
|
||
|
index 77de0706aaa32b565cb1e14754e93a1c4a6e15bd..b7fa24318ef43918b6b10ff4ea8acb960527296e 100644
|
||
|
--- a/src/main/java/net/minecraft/world/entity/animal/EntityFox.java
|
||
|
+++ b/src/main/java/net/minecraft/world/entity/animal/EntityFox.java
|
||
|
@@ -647,15 +647,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/world/entity/animal/horse/EntityHorseChestedAbstract.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseChestedAbstract.java
|
||
|
index aa12a0c9f30cd2b8a6de75ff9822843da808ae64..3daa1780a332128bd472fa80039112f3ca9bc4e9 100644
|
||
|
--- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseChestedAbstract.java
|
||
|
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseChestedAbstract.java
|
||
|
@@ -68,11 +68,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/world/entity/decoration/EntityArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java
|
||
|
index 8d35240405d7f7245f3c7b0b611973d58fa4384f..69361caebf0d3caa5195b519a16691705ac5e16a 100644
|
||
|
--- a/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java
|
||
|
+++ b/src/main/java/net/minecraft/world/entity/decoration/EntityArmorStand.java
|
||
|
@@ -746,7 +746,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/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||
|
index a13867ff6d188e7633a91f1e1600116286ac0cd4..6c5075ef2420131aa21b403623a5dfa485ee73e5 100644
|
||
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||
|
@@ -1839,7 +1839,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 338b319910d12cf62ab9c5977257ad1ccec5544a..b7ebd2e3e919d09ee99997f2358cc0c399d5041b 100644
|
||
|
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||
|
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||
|
@@ -18,6 +18,8 @@ import net.minecraft.network.protocol.game.PacketPlayInCloseWindow;
|
||
|
import net.minecraft.resources.MinecraftKey;
|
||
|
import net.minecraft.server.level.EntityPlayer;
|
||
|
import net.minecraft.server.level.WorldServer;
|
||
|
+import net.minecraft.sounds.SoundCategory;
|
||
|
+import net.minecraft.sounds.SoundEffect;
|
||
|
import net.minecraft.util.Unit;
|
||
|
import net.minecraft.world.EnumHand;
|
||
|
import net.minecraft.world.IInventory;
|
||
|
@@ -805,9 +807,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()) {
|
||
|
@@ -823,8 +832,15 @@ public class CraftEventFactory {
|
||
|
CraftPlayer entity = victim.getBukkitEntity();
|
||
|
PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage, stringDeathMessage); // Paper - Adventure
|
||
|
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();
|
||
|
@@ -841,6 +857,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.getBukkit(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();
|
||
|
+ SoundEffect soundEffect = org.bukkit.craftbukkit.CraftSound.getSoundEffect(event.getDeathSound());
|
||
|
+ SoundCategory soundCategory = SoundCategory.valueOf(event.getDeathSoundCategory().name());
|
||
|
+ victim.world.playSound(source, x, y, z, soundEffect, soundCategory, event.getDeathSoundVolume(), event.getDeathSoundPitch());
|
||
|
+ }
|
||
|
+ }
|
||
|
+ // Paper end
|
||
|
/**
|
||
|
* Server methods
|
||
|
*/
|