From 1f16b25f9ea3cb7d936984e20a0afafd0830dd55 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 16 Feb 2024 15:44:43 -0800
Subject: [PATCH] Fire entity knockback event for ownerless tnt (#7171)

---
 ...ackByEntityEvent-and-EntityPushedByE.patch | 34 ++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/patches/server/Add-EntityKnockbackByEntityEvent-and-EntityPushedByE.patch b/patches/server/Add-EntityKnockbackByEntityEvent-and-EntityPushedByE.patch
index 2b1fb2e0ce..3744834bf7 100644
--- a/patches/server/Add-EntityKnockbackByEntityEvent-and-EntityPushedByE.patch
+++ b/patches/server/Add-EntityKnockbackByEntityEvent-and-EntityPushedByE.patch
@@ -49,6 +49,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
      private boolean checkTotemDeathProtection(DamageSource source) {
+@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
+         this.knockback(strength, x, z, null, EntityKnockbackEvent.KnockbackCause.UNKNOWN);
+     }
+ 
+-    public void knockback(double d0, double d1, double d2, Entity attacker, EntityKnockbackEvent.KnockbackCause cause) {
++    public void knockback(double d0, double d1, double d2, @Nullable Entity attacker, EntityKnockbackEvent.KnockbackCause cause) { // Paper - add nullable to attacker param
+         d0 *= 1.0D - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
+         if (true || d0 > 0.0D) { // CraftBukkit - Call event even when force is 0
+             //this.hasImpulse = true; // CraftBukkit - Move down
 @@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
                  return;
              }
@@ -58,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            org.bukkit.util.Vector resultingMovement = event.getFinalKnockback();
 +            final org.bukkit.util.Vector deltaMovement = resultingMovement.clone().subtract(currentMovement);
 +            if (attacker != null) {
-+                final com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent knockbackEvent = new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent((org.bukkit.entity.LivingEntity) getBukkitEntity(), attacker.getBukkitEntity(), (float) event.getForce(), deltaMovement);
++                final com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent knockbackEvent = new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent(this.getBukkitLivingEntity(), attacker.getBukkitEntity(), (float) event.getForce(), deltaMovement);
 +                if (!knockbackEvent.callEvent()) {
 +                    return;
 +                }
@@ -164,3 +173,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                      }
                  }
  
+diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/level/Explosion.java
++++ b/src/main/java/net/minecraft/world/level/Explosion.java
+@@ -0,0 +0,0 @@ public class Explosion {
+                             Vec3 result = entity.getDeltaMovement().add(vec3d1);
+                             org.bukkit.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity.getBukkitEntity(), this.source, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.EXPLOSION, d13, vec3d1, result.x, result.y, result.z);
+ 
+-                            vec3d1 = (event.isCancelled()) ? Vec3.ZERO : new Vec3(event.getFinalKnockback().getX(), event.getFinalKnockback().getY(), event.getFinalKnockback().getZ());
++                            // Paper start - call EntityKnockbackByEntityEvent for explosions
++                            vec3d1 = (event.isCancelled()) ? Vec3.ZERO : new Vec3(event.getFinalKnockback().getX(), event.getFinalKnockback().getY(), event.getFinalKnockback().getZ()).subtract(entity.getDeltaMovement()); // changes on this line fix a bug where vec3d1 wasn't reassigned with the "change", but instead the final deltaMovement
++                            if (this.damageSource.getEntity() != null || this.source != null) {
++                                final org.bukkit.entity.Entity hitBy = this.damageSource.getEntity() != null ? this.damageSource.getEntity().getBukkitEntity() : this.source.getBukkitEntity();
++                                com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent paperEvent = new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent(((LivingEntity) entity).getBukkitLivingEntity(), hitBy, (float) event.getForce(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(vec3d1));
++                                if (!paperEvent.callEvent()) {
++                                    continue;
++                                }
++                                vec3d1 = org.bukkit.craftbukkit.util.CraftVector.toNMS(paperEvent.getAcceleration());
++                            }
++                            // Paper end - call EntityKnockbackByEntityEvent for explosions
+                         }
+                         // CraftBukkit end
+                         entity.setDeltaMovement(entity.getDeltaMovement().add(vec3d1));