Cancelling ProjectileHitEvent for entity collisions should not prevent block collisions.
Observed/Actual behavior
Cancelling a ProjectileHitEvent fired for hitting an entity can cause arrows to phase through blocks.
Steps/models to reproduce
Shoot an arrow at an entity on the edge of its bounding box, towards the ground. If positioned correctly, the arrow will phase into a block. If the ground is thin enough, it will continue travelling after phasing into the block. Otherwise, it will be lodged within the ground.
Example image of lining up a shot:
Plugin and Datapack List
Only a test plugin, with the following listener to cancel ProjectileHitEvent:
public class TestListener implements Listener {
@EventHandler
public void onHit(ProjectileHitEvent event) {
if (event.getHitEntity() != null) event.setCancelled(true);
}
}
Paper version
This server is running Paper version 1.21.1-119-master@7cd4f2c (2024-10-03T15:19:34Z) (Implementing API version 1.21.1-R0.1-SNAPSHOT)
You are running the latest version
Previous version: 1.21.1-85-c5a1066 (MC: 1.21.1)
Other
This seems to be a result of the logic in AbstractArrow#tick and Projectile#preHitTargetOrDeflectSelf. Arrows first ray trace to determine any block collisions, and then does another ray trace to find hit entities. If an entity that can be hit is found, the hit result is passed to Projectile#preHitTargetOrDeflectSelf. As such, the block collision is never considered, including when the ProjectileHitEvent is cancelled.
Expected behavior
Cancelling
ProjectileHitEvent
for entity collisions should not prevent block collisions.Observed/Actual behavior
Cancelling a
ProjectileHitEvent
fired for hitting an entity can cause arrows to phase through blocks.Steps/models to reproduce
Shoot an arrow at an entity on the edge of its bounding box, towards the ground. If positioned correctly, the arrow will phase into a block. If the ground is thin enough, it will continue travelling after phasing into the block. Otherwise, it will be lodged within the ground. Example image of lining up a shot:
Plugin and Datapack List
Only a test plugin, with the following listener to cancel
ProjectileHitEvent
:Paper version
This server is running Paper version 1.21.1-119-master@7cd4f2c (2024-10-03T15:19:34Z) (Implementing API version 1.21.1-R0.1-SNAPSHOT) You are running the latest version Previous version: 1.21.1-85-c5a1066 (MC: 1.21.1)
Other
This seems to be a result of the logic in
AbstractArrow#tick
andProjectile#preHitTargetOrDeflectSelf
. Arrows first ray trace to determine any block collisions, and then does another ray trace to find hit entities. If an entity that can be hit is found, the hit result is passed toProjectile#preHitTargetOrDeflectSelf
. As such, the block collision is never considered, including when theProjectileHitEvent
is cancelled.