Improve death events (#1362)
* Improve death events This adds the ability to cancel the events and to specify the sound.
Dieser Commit ist enthalten in:
Ursprung
2d45ec855f
Commit
4e30b91d4e
177
Spigot-API-Patches/0130-Improve-death-events.patch
Normale Datei
177
Spigot-API-Patches/0130-Improve-death-events.patch
Normale Datei
@ -0,0 +1,177 @@
|
||||
From b86fe574c68b575d7b24b8f893b3b472d6369fd0 Mon Sep 17 00:00:00 2001
|
||||
From: Phoenix616 <mail@moep.tv>
|
||||
Date: Tue, 21 Aug 2018 01:32:28 +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/org/bukkit/event/entity/EntityDeathEvent.java b/src/main/java/org/bukkit/event/entity/EntityDeathEvent.java
|
||||
index ab9e81fd..a7b8f869 100644
|
||||
--- a/src/main/java/org/bukkit/event/entity/EntityDeathEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/entity/EntityDeathEvent.java
|
||||
@@ -8,10 +8,19 @@ import org.bukkit.inventory.ItemStack;
|
||||
/**
|
||||
* Thrown whenever a LivingEntity dies
|
||||
*/
|
||||
-public class EntityDeathEvent extends EntityEvent {
|
||||
+public class EntityDeathEvent extends EntityEvent implements org.bukkit.event.Cancellable { // Paper - make cancellable
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final List<ItemStack> drops;
|
||||
private int dropExp = 0;
|
||||
+ // Paper start - make cancellable
|
||||
+ private boolean cancelled;
|
||||
+ private double reviveHealth = 0;
|
||||
+ private boolean shouldPlayDeathSound;
|
||||
+ private org.bukkit.Sound deathSound;
|
||||
+ private org.bukkit.SoundCategory deathSoundCategory;
|
||||
+ private float deathSoundVolume;
|
||||
+ private float deathSoundPitch;
|
||||
+ // Paper end
|
||||
|
||||
public EntityDeathEvent(final LivingEntity entity, final List<ItemStack> drops) {
|
||||
this(entity, drops, 0);
|
||||
@@ -69,4 +78,132 @@ public class EntityDeathEvent extends EntityEvent {
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
+
|
||||
+ // Paper start - make cancellable
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the amount of health that the entity should revive with after cancelling the event.
|
||||
+ * Set to the entity's max health by default.
|
||||
+ *
|
||||
+ * @return The amount of health
|
||||
+ */
|
||||
+ public double getReviveHealth() {
|
||||
+ return reviveHealth;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set the amount of health that the entity should revive with after cancelling the event.
|
||||
+ * Revive health value must be between 0 (exclusive) and the entity's max health (inclusive).
|
||||
+ *
|
||||
+ * @param reviveHealth The amount of health
|
||||
+ * @throws IllegalArgumentException Thrown if the health is {@literal <= 0 or >} max health
|
||||
+ */
|
||||
+ public void setReviveHealth(double reviveHealth) throws IllegalArgumentException {
|
||||
+ double maxHealth = ((LivingEntity) entity).getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).getValue();
|
||||
+ if ((reviveHealth <= 0) || (reviveHealth > maxHealth)) {
|
||||
+ throw new IllegalArgumentException("Health must be between 0 (exclusive) and " + maxHealth + " (inclusive), but was " + reviveHealth);
|
||||
+ }
|
||||
+ this.reviveHealth = reviveHealth;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /**
|
||||
+ * Whether or not the death sound should play when the entity dies. If the event is cancelled it does not play!
|
||||
+ *
|
||||
+ * @return Whether or not the death sound should play. Event is called with this set to false if the entity is silent.
|
||||
+ */
|
||||
+ public boolean shouldPlayDeathSound() {
|
||||
+ return shouldPlayDeathSound;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set whether or not the death sound should play when the entity dies. If the event is cancelled it does not play!
|
||||
+ *
|
||||
+ * @param playDeathSound Enable or disable the death sound
|
||||
+ */
|
||||
+ public void setShouldPlayDeathSound(boolean playDeathSound) {
|
||||
+ this.shouldPlayDeathSound = playDeathSound;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the sound that the entity makes when dying
|
||||
+ *
|
||||
+ * @return The sound that the entity makes
|
||||
+ */
|
||||
+ public org.bukkit.Sound getDeathSound() {
|
||||
+ return deathSound;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set the sound that the entity makes when dying
|
||||
+ *
|
||||
+ * @param sound The sound that the entity should make when dying
|
||||
+ */
|
||||
+ public void setDeathSound(org.bukkit.Sound sound) {
|
||||
+ deathSound = sound;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the sound category that the death sound should play in
|
||||
+ *
|
||||
+ * @return The sound category
|
||||
+ */
|
||||
+ public org.bukkit.SoundCategory getDeathSoundCategory() {
|
||||
+ return deathSoundCategory;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set the sound category that the death sound should play in.
|
||||
+ *
|
||||
+ * @param soundCategory The sound category
|
||||
+ */
|
||||
+ public void setDeathSoundCategory(org.bukkit.SoundCategory soundCategory) {
|
||||
+ this.deathSoundCategory = soundCategory;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the volume that the death sound will play at.
|
||||
+ *
|
||||
+ * @return The volume the death sound will play at
|
||||
+ */
|
||||
+ public float getDeathSoundVolume() {
|
||||
+ return deathSoundVolume;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set the volume the death sound should play at. If the event is cancelled this will not play the sound!
|
||||
+ *
|
||||
+ * @param volume The volume the death sound should play at
|
||||
+ */
|
||||
+ public void setDeathSoundVolume(float volume) {
|
||||
+ this.deathSoundVolume = volume;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the pitch that the death sound will play with.
|
||||
+ *
|
||||
+ * @return The pitch the death sound will play with
|
||||
+ */
|
||||
+ public float getDeathSoundPitch() {
|
||||
+ return deathSoundPitch;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * GSetet the pitch that the death sound should play with.
|
||||
+ *
|
||||
+ * @param pitch The pitch the death sound should play with
|
||||
+ */
|
||||
+ public void setDeathSoundPitch(float pitch) {
|
||||
+ this.deathSoundPitch = pitch;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
--
|
||||
2.18.0.windows.1
|
||||
|
@ -1,4 +1,4 @@
|
||||
From f4214b8d94c5a9690fa2e41f7b547545dec26549 Mon Sep 17 00:00:00 2001
|
||||
From 00d132db37f8d96814d5ce793d584937c0a0f896 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
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
|
||||
|
||||
|
416
Spigot-Server-Patches/0356-Improve-death-events.patch
Normale Datei
416
Spigot-Server-Patches/0356-Improve-death-events.patch
Normale Datei
@ -0,0 +1,416 @@
|
||||
From b8c6e5d80cd3b21db5b3d9a031439d37143eb467 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 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
|
||||
|
@ -56,6 +56,7 @@ import ChunkCoordIntPair
|
||||
import ChunkProviderFlat
|
||||
import ChunkProviderGenerate
|
||||
import ChunkProviderHell
|
||||
import CombatTracker
|
||||
import CommandAbstract
|
||||
import CommandScoreboard
|
||||
import CommandWhitelist
|
||||
@ -103,10 +104,13 @@ import PersistentScoreboard
|
||||
import PersistentVillage
|
||||
import PlayerConnectionUtils
|
||||
import RegionFile
|
||||
import Registry
|
||||
import RegistryBlockID
|
||||
import RegistryMaterials
|
||||
import RemoteControlListener
|
||||
import RecipeBookServer
|
||||
import ServerPing
|
||||
import SoundEffect
|
||||
import StructureBoundingBox
|
||||
import StructurePiece
|
||||
import StructureStart
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren