From 5503829533257822c351c98b03d8d75ea7baadda Mon Sep 17 00:00:00 2001 From: Doc Date: Wed, 8 Oct 2025 12:39:07 -0300 Subject: [PATCH 1/2] Kill entity and not remove for negative healing Took 1 hour 29 minutes --- .../minecraft/world/effect/HealOrHarmMobEffect.java.patch | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch b/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch index 274a719765de..e770df209ab3 100644 --- a/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch @@ -9,7 +9,7 @@ } else { entity.hurtServer(level, entity.damageSources().magic(), 6 << amplifier); } -@@ -28,9 +_,10 @@ +@@ -28,9 +_,16 @@ public void applyInstantenousEffect( ServerLevel level, @Nullable Entity source, @Nullable Entity indirectSource, LivingEntity entity, int amplifier, double health ) { @@ -17,6 +17,12 @@ if (this.isHarm == entity.isInvertedHealAndHarm()) { int i = (int)(health * (4 << amplifier) + 0.5); - entity.heal(i); ++ // Paper start - handle negative health ++ if (i < 0) { ++ entity.hurtServer(level, entity.damageSources().generic(), Math.abs(i)); ++ return; ++ } ++ // Paper end + entity.heal(i, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC); // CraftBukkit } else { int i = (int)(health * (6 << amplifier) + 0.5); From c6ba20c3e523e32d28fcce590b31fe6ccc22579b Mon Sep 17 00:00:00 2001 From: Doc Date: Wed, 8 Oct 2025 14:34:37 -0300 Subject: [PATCH 2/2] Cat wanna DamageType but sure this needs more talk and possible conflict merge later Took 42 minutes --- .../features/0005-Entity-Activation-Range-2.0.patch | 4 ++-- .../minecraft/world/effect/HealOrHarmMobEffect.java.patch | 8 +------- .../net/minecraft/world/entity/LivingEntity.java.patch | 8 +++++++- .../paper/data/paper/damage_type/healing_magic.json | 5 +++++ .../paper/tags/damage_type/bypasses_invulnerability.json | 6 ++++++ .../paper/data/paper/tags/damage_type/no_knockback.json | 6 ++++++ 6 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/damage_type/healing_magic.json create mode 100644 paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/tags/damage_type/bypasses_invulnerability.json create mode 100644 paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/tags/damage_type/no_knockback.json diff --git a/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch b/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch index fb160a079872..eb7148e1bf06 100644 --- a/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch +++ b/paper-server/patches/features/0005-Entity-Activation-Range-2.0.patch @@ -523,10 +523,10 @@ index 2cae59fbc6a279e70c388ea7cc6f6f5f749f46a1..8dcd36b3d29c3d9913675c918fa509d7 movement = this.maybeBackOffFromEdge(movement, type); Vec3 vec3 = this.collide(movement); diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index d5e304c9431bf3d7ad151e68e955b113d3c599ef..90483699b3f2efe9945c849adfdd38422e3a3458 100644 +index b49d5e2089ab7ae024cb8e5d9c040060e90a678a..2d4cd4c74921da4b91b96d1cbfc729e845a25a38 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -3246,6 +3246,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin +@@ -3252,6 +3252,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin return false; } diff --git a/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch b/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch index e770df209ab3..274a719765de 100644 --- a/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch @@ -9,7 +9,7 @@ } else { entity.hurtServer(level, entity.damageSources().magic(), 6 << amplifier); } -@@ -28,9 +_,16 @@ +@@ -28,9 +_,10 @@ public void applyInstantenousEffect( ServerLevel level, @Nullable Entity source, @Nullable Entity indirectSource, LivingEntity entity, int amplifier, double health ) { @@ -17,12 +17,6 @@ if (this.isHarm == entity.isInvertedHealAndHarm()) { int i = (int)(health * (4 << amplifier) + 0.5); - entity.heal(i); -+ // Paper start - handle negative health -+ if (i < 0) { -+ entity.hurtServer(level, entity.damageSources().generic(), Math.abs(i)); -+ return; -+ } -+ // Paper end + entity.heal(i, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC); // CraftBukkit } else { int i = (int)(health * (6 << amplifier) + 0.5); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch index f4c78f683045..19b0098e69ac 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -435,7 +435,7 @@ if (mobEffectInstance != null) { this.onEffectsRemoved(List.of(mobEffectInstance)); return true; -@@ -1131,17 +_,62 @@ +@@ -1131,17 +_,68 @@ } public void heal(float healAmount) { @@ -460,6 +460,12 @@ + } + + if (!event.isCancelled()) { ++ // Paper start - handle negative health ++ if (event.getAmount() < 0) { ++ this.hurtServer(((net.minecraft.server.level.ServerLevel) this.level()), new DamageSource(this.level().registryAccess().getOrThrow(ResourceKey.create(net.minecraft.core.registries.Registries.DAMAGE_TYPE, ResourceLocation.fromNamespaceAndPath("paper", "healing_magic")))), (float) Math.abs(event.getAmount())); ++ return; ++ } ++ // Paper end + this.setHealth((float) (this.getHealth() + event.getAmount())); + } + // CraftBukkit end diff --git a/paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/damage_type/healing_magic.json b/paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/damage_type/healing_magic.json new file mode 100644 index 000000000000..716de636c789 --- /dev/null +++ b/paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/damage_type/healing_magic.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.0, + "message_id": "generic", + "scaling": "when_caused_by_living_non_player" +} diff --git a/paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/tags/damage_type/bypasses_invulnerability.json b/paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/tags/damage_type/bypasses_invulnerability.json new file mode 100644 index 000000000000..1cb7b5d4562a --- /dev/null +++ b/paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/tags/damage_type/bypasses_invulnerability.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "paper:healing_magic" + ] +} diff --git a/paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/tags/damage_type/no_knockback.json b/paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/tags/damage_type/no_knockback.json new file mode 100644 index 000000000000..1cb7b5d4562a --- /dev/null +++ b/paper-server/src/main/resources/data/minecraft/datapacks/paper/data/paper/tags/damage_type/no_knockback.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "paper:healing_magic" + ] +}