From 592a7edb86bb48f3e35733a6a2ff73ff73109bae Mon Sep 17 00:00:00 2001 From: Doc Date: Sat, 28 Feb 2026 10:11:50 -0300 Subject: [PATCH] Support for Kill damageable entities --- .../java/org/bukkit/entity/Damageable.java | 30 +++++++++++++++---- .../entity/CraftEnderDragonPart.java | 5 ++++ .../craftbukkit/entity/CraftLivingEntity.java | 14 +++++++-- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/entity/Damageable.java b/paper-api/src/main/java/org/bukkit/entity/Damageable.java index a2ceb14de6fe..ac87af640d97 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Damageable.java +++ b/paper-api/src/main/java/org/bukkit/entity/Damageable.java @@ -2,12 +2,15 @@ import org.bukkit.attribute.Attribute; import org.bukkit.damage.DamageSource; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.bukkit.damage.DamageType; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * Represents an {@link Entity} that has health and can take damage. */ +@NullMarked public interface Damageable extends Entity { /** * Deals the given amount of damage to this entity. @@ -32,7 +35,24 @@ public interface Damageable extends Entity { * @param amount amount of damage to deal * @param damageSource source to which the damage should be attributed */ - void damage(double amount, @NotNull DamageSource damageSource); + void damage(double amount, DamageSource damageSource); + + /** + * Sets the entity's health to 0 and kill the entity with a generic DamageSource. + * + * @throws IllegalStateException if is used in world generation + */ + default void kill() { + this.kill(DamageSource.builder(DamageType.GENERIC_KILL).build()); + } + + /** + * Sets the entity's health to 0 and kill the entity with the specified DamageSource. + * + * @param damageSource the DamageSource to use for the kill + * @throws IllegalStateException if is used in world generation + */ + void kill(DamageSource damageSource); /** * Gets the entity's health from 0 to {@link #getMaxHealth()}, where 0 is dead. @@ -57,7 +77,7 @@ public interface Damageable extends Entity { * @param amount heal amount */ default void heal(final double amount) { - this.heal(amount, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.CUSTOM); + this.heal(amount, EntityRegainHealthEvent.RegainReason.CUSTOM); } /** @@ -66,7 +86,7 @@ default void heal(final double amount) { * @param amount heal amount * @param reason heal reason */ - void heal(double amount, @NotNull org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason reason); + void heal(double amount, EntityRegainHealthEvent.RegainReason reason); /** * Gets the entity's absorption amount. diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java index 25e9b002df1f..8c4746a37b01 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java @@ -31,6 +31,11 @@ public void damage(double amount, Entity source) { this.getParent().damage(amount, source); } + @Override + public void kill(DamageSource damageSource) { + this.getParent().kill(damageSource); + } + @Override public double getHealth() { return this.getParent().getHealth(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java index b0987314d263..50bff6056684 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -90,6 +90,7 @@ import org.bukkit.entity.WitherSkull; import org.bukkit.entity.memory.MemoryKey; import org.bukkit.event.entity.EntityPotionEffectEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; @@ -145,12 +146,10 @@ public void setHealth(double health) { } } - // Paper start - entity heal API @Override - public void heal(final double amount, final org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason reason) { + public void heal(final double amount, final EntityRegainHealthEvent.RegainReason reason) { this.getHandle().heal((float) amount, reason); } - // Paper end - entity heal API @Override public double getAbsorptionAmount() { @@ -400,6 +399,15 @@ public void setBeeStingersInBody(int count) { this.getHandle().setStingerCount(count); } + @Override + public void kill(org.bukkit.damage.DamageSource damageSource) { + Preconditions.checkState(!this.getHandle().generation, "Cannot kill entity during world generation"); + Preconditions.checkArgument(damageSource != null, "damageSource cannot be null"); + + this.getHandle().setHealth(0); + this.getHandle().die(((CraftDamageSource) damageSource).getHandle()); + } + @Override public void damage(double amount) { this.damage(amount, this.getHandle().damageSources().generic());