Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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 +_,36 @@
zd = source.getSourcePosition().z() - this.getZ();
}

Expand All @@ -611,7 +611,15 @@
+ }
+ // 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
+ 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); // CraftBukkit // Paper - knockback events
if (!blocked) {
this.indicateDamage(xd, zd);
}
Expand Down Expand Up @@ -902,7 +910,7 @@
Vec3 deltaMovement = this.getDeltaMovement();

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

Vec3 deltaVector = new Vec3(xd, 0.0, zd).normalize().scale(power);
Expand All @@ -914,13 +922,15 @@
);
+ // 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.needsSync = true;
+ }
+ this.setDeltaMovement(deltaMovement.add(knockback.x, knockback.y, knockback.z));
+ // Paper end - knockback events
}
}
Expand Down Expand Up @@ -1271,15 +1281,26 @@
}

private Vec3 updateFallFlyingMovement(Vec3 movement) {
@@ -2749,7 +_,7 @@
@@ -2748,9 +_,16 @@
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) {
livingTarget.knockback(
- 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
);
- );

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.

same as above

+ if (this.isSprinting()) {
+ livingTarget.knockback(
+ 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_SPRINT_ATTACK // Paper - knockback events
+ );
+ }
+ else {
+ livingTarget.knockback(
+ 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
+ );
+ }
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,13 +290,22 @@
return true;
} else {
return false;
@@ -1127,20 +_,41 @@
@@ -1126,21 +_,48 @@
) {
if (knockbackAmount > 0.0F) {
if (entity instanceof LivingEntity livingTarget) {
livingTarget.knockback(
- 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
);
- );

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.

if the only difference here is the cause then that should just be deduced as a oneliner and passed in, no need for an entire code block to be added (which doesn't follow the commenting guidelines anyways)

+ if (livingTarget.isSprinting()) {
+ livingTarget.knockback(
+ 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_SPRINT_ATTACK // Paper - knockback events
+ );
+ } else {
+ livingTarget.knockback(
+ 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
+ );
+ }
} else {
- entity.push(-Mth.sin(this.getYRot() * Mth.DEG_TO_RAD) * knockbackAmount, 0.1, Mth.cos(this.getYRot() * Mth.DEG_TO_RAD) * knockbackAmount);
+ entity.push(-Mth.sin(this.getYRot() * Mth.DEG_TO_RAD) * knockbackAmount, 0.1, Mth.cos(this.getYRot() * Mth.DEG_TO_RAD) * knockbackAmount, this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
Expand Down
Loading