aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0202-Add-EntityKnockbackByEntityEvent-and-EntityPushedByE.patch
blob: 30c6ae6bebd22a27ae8d2d78ae3bf141cd305529 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brokkonaut <hannos17@gmx.de>
Date: Mon, 18 Jun 2018 15:46:23 +0200
Subject: [PATCH] Add EntityKnockbackByEntityEvent and
 EntityPushedByEntityAttackEvent

Co-authored-by: aerulion <aerulion@gmail.com>

This event is called when an entity receives knockback by another entity.

diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0cc82ffdcebbdd92fa953e7c52a20911f46a503c..165cc45e2ae99e606533e5e5294e431ed5e3a2dd 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -1868,9 +1868,23 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
         }
     }
 
-    public void push(double deltaX, double deltaY, double deltaZ) {
-        this.setDeltaMovement(this.getDeltaMovement().add(deltaX, deltaY, deltaZ));
+    public final void push(double deltaX, double deltaY, double deltaZ) { // Paper - override the added overload below
+        // Paper start - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
+        this.push(deltaX, deltaY, deltaZ, null);
+    }
+
+    public void push(double deltaX, double deltaY, double deltaZ, @org.jetbrains.annotations.Nullable Entity pushingEntity) {
+        org.bukkit.util.Vector delta = new org.bukkit.util.Vector(deltaX, deltaY, deltaZ);
+        if (pushingEntity != null) {
+            io.papermc.paper.event.entity.EntityPushedByEntityAttackEvent event = new io.papermc.paper.event.entity.EntityPushedByEntityAttackEvent(getBukkitEntity(), pushingEntity.getBukkitEntity(), delta);
+            if (!event.callEvent()) {
+                return;
+            }
+            delta = event.getAcceleration();
+        }
+        this.setDeltaMovement(this.getDeltaMovement().add(delta.getX(), delta.getY(), delta.getZ()));
         this.hasImpulse = true;
+        // Paper end - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
     }
 
     protected void markHurt() {
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index e3dfef027fb7f6aedd3e3411af6457671b5507a7..88af8a11dfc3b645c5a2b5fb629a73fc1e2b2f80 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1569,7 +1569,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
     }
 
     protected void blockedByShield(LivingEntity target) {
-        target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ(), null, EntityKnockbackEvent.KnockbackCause.SHIELD_BLOCK); // CraftBukkit
+        target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ(), this, EntityKnockbackEvent.KnockbackCause.SHIELD_BLOCK); // CraftBukkit // Paper - fix attacker
     }
 
     private boolean checkTotemDeathProtection(DamageSource source) {
@@ -1832,7 +1832,7 @@ 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
@@ -1844,8 +1844,22 @@ public abstract class LivingEntity extends Entity implements Attackable {
                 return;
             }
 
+            // Paper start - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
+            final org.bukkit.util.Vector currentMovement = this.getBukkitEntity().getVelocity();
+            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(this.getBukkitLivingEntity(), attacker.getBukkitEntity(), (float) event.getForce(), deltaMovement);
+                if (!knockbackEvent.callEvent()) {
+                    return;
+                }
+
+                // Back from delta to the absolute vector
+                resultingMovement = currentMovement.add(knockbackEvent.getAcceleration());
+            }
             this.hasImpulse = true;
-            this.setDeltaMovement(event.getFinalKnockback().getX(), event.getFinalKnockback().getY(), event.getFinalKnockback().getZ());
+            this.setDeltaMovement(resultingMovement.getX(), resultingMovement.getY(), resultingMovement.getZ());
+            // Paper end - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
             // CraftBukkit end
         }
     }
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
index a93212d3cbf18a8cf392515fd466475264bba5ef..347986ef559ebcecdb67e2f5d31a31049acc48f5 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
@@ -83,7 +83,7 @@ public class RamTarget extends Behavior<Goat> {
             float f = 0.25F * (i - j);
             float g = Mth.clamp(entity.getSpeed() * 1.65F, 0.2F, 3.0F) + f;
             float h = livingEntity.isDamageSourceBlocked(world.damageSources().mobAttack(entity)) ? 0.5F : 1.0F;
-            livingEntity.knockback(h * g * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z());
+            livingEntity.knockback(h * g * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z(), entity, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
             this.finishRam(world, entity);
             world.playSound(null, entity, this.getImpactSound.apply(entity), SoundSource.NEUTRAL, 1.0F, 1.0F);
         } else if (this.hasRammedHornBreakingBlock(world, entity)) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java b/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
index ce329b00fa25e9defabead0e594d734b8ed6724e..fe9c5afadd9041ab32d9e03fe6dab2a2d00262f2 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
@@ -81,7 +81,7 @@ public class SonicBoom extends Behavior<Warden> {
                     target.hurt(world.damageSources().sonicBoom(entity), 10.0F);
                     double d = 0.5 * (1.0 - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
                     double e = 2.5 * (1.0 - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
-                    target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e);
+                    target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e, entity); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
                 });
         }
     }
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
index 9ab60fb1b7f9c8a342d9116e99f7f0a1e463a626..0d84f1fb53384a827d7418c322a32e3286f4081a 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
@@ -459,7 +459,7 @@ public class EnderDragon extends Mob implements Enemy {
                 double d3 = entity.getZ() - d1;
                 double d4 = Math.max(d2 * d2 + d3 * d3, 0.1D);
 
-                entity.push(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D);
+                entity.push(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D, this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
                 if (!this.phaseManager.getCurrentPhase().isSitting() && ((LivingEntity) entity).getLastHurtByMobTimestamp() < entity.tickCount - 2) {
                     entity.hurt(this.damageSources().mobAttack(this), 5.0F);
                     this.doEnchantDamageEffects(this, entity);
diff --git a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java
index b3d05578f38af41f242f6634864ce1d2ecac14f8..aaa579ba04445aa350a439610d460a2415320cfc 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java
@@ -250,7 +250,7 @@ public abstract class HangingEntity extends Entity {
     }
 
     @Override
-    public void push(double deltaX, double deltaY, double deltaZ) {
+    public void push(double deltaX, double deltaY, double deltaZ, @org.jetbrains.annotations.Nullable Entity pushingEntity) { // Paper - add push source entity param
         if (false && !this.level().isClientSide && !this.isRemoved() && deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ > 0.0D) { // CraftBukkit - not needed
             this.kill();
             this.dropItem((Entity) null);
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
index 78a3c87b74218a0d5792801c07e3a263c15fcd5b..f90878e0449f39f66ae3a7036a65c374b36b7dbc 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
@@ -159,9 +159,9 @@ public class ItemFrame extends HangingEntity {
     }
 
     @Override
-    public void push(double deltaX, double deltaY, double deltaZ) {
+    public void push(double deltaX, double deltaY, double deltaZ, @org.jetbrains.annotations.Nullable Entity pushingEntity) { // Paper - add push source entity param
         if (!this.fixed) {
-            super.push(deltaX, deltaY, deltaZ);
+            super.push(deltaX, deltaY, deltaZ, pushingEntity); // Paper - add push source entity param
         }
 
     }
diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
index 041f1650b853138e4286fe83a08d79d276054ce7..aba20a4352d8983b01ab5d329187588f68d3e405 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
@@ -265,7 +265,7 @@ public class Ravager extends Raider {
         double d1 = entity.getZ() - this.getZ();
         double d2 = Math.max(d0 * d0 + d1 * d1, 0.001D);
 
-        entity.push(d0 / d2 * 4.0D, 0.2D, d1 / d2 * 4.0D);
+        entity.push(d0 / d2 * 4.0D, 0.2D, d1 / d2 * 4.0D, this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
index 889dca53d7a113f0b70791c75885de1c66fecdff..06cb2a4a941ccdd7371f05f7c3c6951dc6c66b04 100644
--- a/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
@@ -40,7 +40,7 @@ public interface HoglinBase {
             double j = f * (attacker.level().random.nextFloat() * 0.5F + 0.2F);
             Vec3 vec3 = new Vec3(g, 0.0, h).normalize().scale(j).yRot(i);
             double k = f * attacker.level().random.nextFloat() * 0.5;
-            target.push(vec3.x, k, vec3.z);
+            target.push(vec3.x, k, vec3.z, attacker); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
             target.hurtMarked = true;
         }
     }
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 0bff92eeade590852b9b37105a18df35f587559b..c934c7614281f77376858909c86d9a1a73c8e174 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1279,7 +1279,7 @@ public abstract class Player extends LivingEntity {
                             if (target instanceof LivingEntity) {
                                 ((LivingEntity) target).knockback((double) ((float) i * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // CraftBukkit
                             } else {
-                                target.push((double) (-Mth.sin(this.getYRot() * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (Mth.cos(this.getYRot() * 0.017453292F) * (float) i * 0.5F));
+                                target.push((double) (-Mth.sin(this.getYRot() * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (Mth.cos(this.getYRot() * 0.017453292F) * (float) i * 0.5F), this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
                             }
 
                             this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
index c210ae3795b1bbaefbe84a6f62b9d3dd75d642a4..f1d7f202b99b8ae4c16d10956d68d74efae8445b 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -410,7 +410,7 @@ public abstract class AbstractArrow extends Projectile {
                     Vec3 vec3d = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D).normalize().scale((double) this.knockback * 0.6D * d0);
 
                     if (vec3d.lengthSqr() > 0.0D) {
-                        entityliving.push(vec3d.x, 0.1D, vec3d.z);
+                        entityliving.push(vec3d.x, 0.1D, vec3d.z, this); // Paper
                     }
                 }
 
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
index 00cfa26783ce0772c75166266ead258a415097bc..ade10a9fd93f4c0f04cd56ce5e1da06af4a05060 100644
--- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -298,7 +298,17 @@ 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));