Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ public enum Cause {
* Knockback caused by an attacking entity.
*/
ENTITY_ATTACK,
/**
* Knockback caused by the sprint bonus applied during an entity attack.
*/
ENTITY_SPRINT_ATTACK,
/**
* Knockback caused by an explosion.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ public enum KnockbackCause {
* Knockback caused by an attacking entity.
*/
ENTITY_ATTACK,
/**
* Knockback caused by the sprint bonus applied during an entity attack.
*/
ENTITY_SPRINT_ATTACK,
/**
* Knockback caused by an explosion.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@
if (success) {
this.lastDamageSource = source;
this.lastDamageStamp = this.level().getGameTime();
@@ -1300,13 +_,28 @@
@@ -1300,13 +_,37 @@
zd = source.getSourcePosition().z() - this.getZ();
}

Expand All @@ -609,9 +609,18 @@
+ if (Math.abs(zd) > 200) {
+ zd = Math.random() - Math.random();
+ }
+ // Paper end - Check distance in entity interactions
+
+ this.knockback(0.4F, xd, zd, source, damage, source.getDirectEntity(), source.getDirectEntity() == null ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events
+ // Paper start - knockback events
+ io.papermc.paper.event.entity.EntityKnockbackEvent.Cause cause;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the contrib guide; it needs start/end comments. You can't just add a block of code and then only comment a singular line in there

+ if (source.getDirectEntity() instanceof LivingEntity living && living.isSprinting()) {
+ cause = io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_SPRINT_ATTACK;
+ } else if (source.getDirectEntity() == null) {
+ cause = io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE;
+ } else {
+ cause = io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK;
+ }
+ this.knockback(0.4F, xd, zd, source, damage, source.getDirectEntity(), cause);
+ // Paper end - knockback events
if (!blocked) {
this.indicateDamage(xd, zd);
}
Expand Down Expand Up @@ -902,7 +911,7 @@
Vec3 deltaMovement = this.getDeltaMovement();

while (xd * xd + zd * zd < 1.0E-5F) {
@@ -1651,16 +_,32 @@
@@ -1651,16 +_,33 @@
}

Vec3 deltaVector = new Vec3(xd, 0.0, zd).normalize().scale(power);
Expand All @@ -914,13 +923,14 @@
);
+ // Paper start - knockback events
+ Vec3 knockback = targetMovement.subtract(deltaMovement);
+ io.papermc.paper.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) this.getBukkitEntity(), attacker, attacker, eventCause, power, knockback);
+ if (event.isCancelled()) {
+ return;
+ if (!comesFromEffect) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tis boolean looks somewhat concerning, what does this signify? This looks like double firing is actually intended as in many cases this is additional knockback over the entity?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That boolean distinguishes the base attack knockback from the extra knockback added by attributes/enchantments. The double movement application (base + extra) is vanilla behavior, but firing the Paper event twice for a single hit isn't desirable — that's what caused #11622 (event firing twice on sprint attacks). This boolean lets the event fire only once (on the base call), while both movement increments still get applied.

+ io.papermc.paper.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) this.getBukkitEntity(), attacker, attacker, eventCause, power, knockback);
+ if (event.isCancelled()) {
+ return;
+ }
+ }
+
+ this.needsSync = true;
+ this.setDeltaMovement(deltaMovement.add(event.getKnockback().getX(), event.getKnockback().getY(), event.getKnockback().getZ()));
+ this.setDeltaMovement(deltaMovement.add(knockback.x, knockback.y, knockback.z));
+ // Paper end - knockback events
}
}
Expand Down Expand Up @@ -1271,15 +1281,22 @@
}

private Vec3 updateFallFlyingMovement(Vec3 movement) {
@@ -2749,7 +_,7 @@
@@ -2748,9 +_,14 @@
final Entity target, final float knockback, final Vec3 oldMovement, final DamageSource damageSource, final float damage, final boolean comesFromEffect
) {
if (knockback > 0.0F && target instanceof LivingEntity livingTarget) {
+ // Paper start - knockback events
+ io.papermc.paper.event.entity.EntityKnockbackEvent.Cause cause = this.isSprinting()
+ ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_SPRINT_ATTACK
+ : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK;
livingTarget.knockback(
- knockback, Mth.sin(this.getYRot() * Mth.DEG_TO_RAD), -Mth.cos(this.getYRot() * Mth.DEG_TO_RAD), damageSource, damage, comesFromEffect
+ knockback, Mth.sin(this.getYRot() * Mth.DEG_TO_RAD), -Mth.cos(this.getYRot() * Mth.DEG_TO_RAD), damageSource, damage, comesFromEffect, this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK // Paper - knockback events
+ knockback, Mth.sin(this.getYRot() * Mth.DEG_TO_RAD), -Mth.cos(this.getYRot() * Mth.DEG_TO_RAD), damageSource, damage, comesFromEffect, this, cause
);
+ // Paper end - knockback events
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6, 1.0, 0.6));
}
}
@@ -2826,37 +_,15 @@
profiler.pop();
profiler.push("rangeChecks");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,13 @@
return true;
} else {
return false;
@@ -1127,20 +_,41 @@
@@ -1127,20 +_,42 @@
if (knockbackAmount > 0.0F) {
if (entity instanceof LivingEntity livingTarget) {
livingTarget.knockback(
- knockbackAmount, Mth.sin(this.getYRot() * Mth.DEG_TO_RAD), -Mth.cos(this.getYRot() * Mth.DEG_TO_RAD), damageSource, damage, comesFromEffect
+ knockbackAmount, Mth.sin(this.getYRot() * Mth.DEG_TO_RAD), -Mth.cos(this.getYRot() * Mth.DEG_TO_RAD), damageSource, damage, comesFromEffect, this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK // Paper - knockback events
+ knockbackAmount, Mth.sin(this.getYRot() * Mth.DEG_TO_RAD), -Mth.cos(this.getYRot() * Mth.DEG_TO_RAD), damageSource, damage, comesFromEffect, this,
+ livingTarget.isSprinting() ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_SPRINT_ATTACK : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK // Paper - knockback events
);
} else {
- entity.push(-Mth.sin(this.getYRot() * Mth.DEG_TO_RAD) * knockbackAmount, 0.1, Mth.cos(this.getYRot() * Mth.DEG_TO_RAD) * knockbackAmount);
Expand Down