From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Mon, 18 Jan 2021 14:02:22 -0800
Subject: [PATCH] Properly handle cancellation of projectile hit event

Subclasses override and run logic. Some of this logic destroys
the projectile as well, which wouldn't be fitting for cancellation.

diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityArrow.java b/src/main/java/net/minecraft/world/entity/projectile/EntityArrow.java
index 2f8b3587f527620152609d5be342b328a7621e0f..01679d76405625223869f3fdcb29ffba49f7b69a 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntityArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityArrow.java
@@ -211,7 +211,9 @@ public abstract class EntityArrow extends IProjectile {
                 // Paper end
 
                 if (object != null && !flag) {
+                    if (org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, (MovingObjectPosition) object)) { // CraftBukkit - Call event // Paper - make cancellable // Tuinity - implement cancellation properly
                     this.a((MovingObjectPosition) object);
+                    } // Tuinity - implement cancellation properly
                     this.impulse = true;
                 }
 
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityFireball.java b/src/main/java/net/minecraft/world/entity/projectile/EntityFireball.java
index b9680f6f2e30ec9397d6a9c83e79563d9253aff6..546de0ec2b624a781480ac95f65b2cbfbb5dcf2e 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntityFireball.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityFireball.java
@@ -83,7 +83,9 @@ public abstract class EntityFireball extends IProjectile {
             // Paper end
 
             if (movingobjectposition != null && movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { // Paper - add null check in case cancelled
+                if (org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // CraftBukkit - Call event // Paper - make cancellable // Tuinity - implement cancellation properly
                 this.a(movingobjectposition);
+                } // Tuinity - implement cancellation properly
 
                 // CraftBukkit start - Fire ProjectileHitEvent
                 if (this.dead) {
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityFireworks.java b/src/main/java/net/minecraft/world/entity/projectile/EntityFireworks.java
index 9cc59439ae2c4e758c44b2a92b78bc328efdfa1b..f9a355c847d778a9aad1987882fc816af92450ba 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntityFireworks.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityFireworks.java
@@ -149,7 +149,9 @@ public class EntityFireworks extends IProjectile {
         MovingObjectPosition movingobjectposition = ProjectileHelper.a((Entity) this, this::a);
 
         if (!this.noclip) {
+            if (org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // CraftBukkit - Call event // Paper - make cancellable // Tuinity - implement cancellation properly
             this.a(movingobjectposition);
+            } // Tuinity - implement cancellation properly
             this.impulse = true;
         }
 
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityFishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/EntityFishingHook.java
index addea9c1309a308b76c93ee71e839c915bc773e8..dc6d279766ccc83a8f450028a09491b1c88f524c 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntityFishingHook.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityFishingHook.java
@@ -265,7 +265,9 @@ public class EntityFishingHook extends IProjectile {
     private void m() {
         MovingObjectPosition movingobjectposition = ProjectileHelper.a((Entity) this, this::a);
 
+        if (org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // CraftBukkit - Call event // Paper - make cancellable // Tuinity - implement cancellation properly
         this.a(movingobjectposition);
+        } // Tuinity - implement cancellation properly
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityLlamaSpit.java b/src/main/java/net/minecraft/world/entity/projectile/EntityLlamaSpit.java
index 39b34e619cf7ac3ad308f98551c796ac47073484..8aef834a6e8fcf5d44986745affb8f27bc3dfd6b 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntityLlamaSpit.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityLlamaSpit.java
@@ -34,7 +34,9 @@ public class EntityLlamaSpit extends IProjectile {
         MovingObjectPosition movingobjectposition = ProjectileHelper.a((Entity) this, this::a);
 
         if (movingobjectposition != null) {
+            if (org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // CraftBukkit - Call event // Paper - make cancellable // Tuinity - implement cancellation properly
             this.a(movingobjectposition);
+            } // Tuinity - implement cancellation properly
         }
 
         double d0 = this.locX() + vec3d.x;
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityProjectile.java b/src/main/java/net/minecraft/world/entity/projectile/EntityProjectile.java
index 3b379e83b79bd9b46dbdd4a48ac3842abc4dfbb8..e55061b6c04b4bde92404a6ef58ba9a52cd99c1d 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntityProjectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityProjectile.java
@@ -65,7 +65,7 @@ public abstract class EntityProjectile extends IProjectile {
                     movingobjectposition = null;
                 }
             }
-            if (movingobjectposition != null) {
+            if (movingobjectposition != null && org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // Tuinity - implement cancellation properly
             // Paper end
             this.a(movingobjectposition);
             } // Paper
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityShulkerBullet.java b/src/main/java/net/minecraft/world/entity/projectile/EntityShulkerBullet.java
index c3dcebad0706386e52ef2d28f2074cb6aed9f9e4..1ae528ccd09a6536b3aac320e6218f03c274d6a9 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntityShulkerBullet.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityShulkerBullet.java
@@ -230,7 +230,7 @@ public class EntityShulkerBullet extends IProjectile {
 
             MovingObjectPosition movingobjectposition = ProjectileHelper.a((Entity) this, this::a);
 
-            if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) {
+            if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS && org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // Tuinity - implement cancellation properly
                 this.a(movingobjectposition);
             }
         }
diff --git a/src/main/java/net/minecraft/world/entity/projectile/IProjectile.java b/src/main/java/net/minecraft/world/entity/projectile/IProjectile.java
index 9f2e7d345d98f50e6d47cbf4bb35714852fa42da..2e2e4ee98619cfbeaecffa1ebae78ccc1d7666ca 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/IProjectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/IProjectile.java
@@ -130,7 +130,7 @@ public abstract class IProjectile extends Entity {
     }
 
     protected void a(MovingObjectPosition movingobjectposition) {
-        if (!org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) return; // CraftBukkit - Call event // Paper - make cancellable
+        // Tuinity - proper cancellation requires moving this into the caller (see method overrides) - TODO this unfortunately means we need to manually inspect each call on update
         MovingObjectPosition.EnumMovingObjectType movingobjectposition_enummovingobjecttype = movingobjectposition.getType();
 
         if (movingobjectposition_enummovingobjecttype == MovingObjectPosition.EnumMovingObjectType.ENTITY) {
