--- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java
+++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java
@@ -10,10 +10,12 @@
 import net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity;
 import net.minecraft.world.level.block.state.BlockState;
 import net.minecraft.world.phys.BlockHitResult;
+import net.minecraft.world.phys.EntityHitResult;
 import net.minecraft.world.phys.HitResult;
 import net.minecraft.world.phys.Vec3;
 
 public abstract class ThrowableProjectile extends Projectile {
+
     protected ThrowableProjectile(EntityType<? extends ThrowableProjectile> type, Level world) {
         super(type, world);
     }
@@ -24,71 +26,89 @@
     }
 
     protected ThrowableProjectile(EntityType<? extends ThrowableProjectile> type, LivingEntity owner, Level world) {
-        this(type, owner.getX(), owner.getEyeY() - (double)0.1F, owner.getZ(), world);
+        this(type, owner.getX(), owner.getEyeY() - 0.10000000149011612D, owner.getZ(), world);
         this.setOwner(owner);
     }
 
     @Override
     public boolean shouldRenderAtSqrDistance(double distance) {
-        double d = this.getBoundingBox().getSize() * 4.0D;
-        if (Double.isNaN(d)) {
-            d = 4.0D;
+        double d1 = this.getBoundingBox().getSize() * 4.0D;
+
+        if (Double.isNaN(d1)) {
+            d1 = 4.0D;
         }
 
-        d *= 64.0D;
-        return distance < d * d;
+        d1 *= 64.0D;
+        return distance < d1 * d1;
     }
 
     @Override
     public void tick() {
         super.tick();
-        HitResult hitResult = ProjectileUtil.getHitResult(this, this::canHitEntity);
-        boolean bl = false;
-        if (hitResult.getType() == HitResult.Type.BLOCK) {
-            BlockPos blockPos = ((BlockHitResult)hitResult).getBlockPos();
-            BlockState blockState = this.level.getBlockState(blockPos);
-            if (blockState.is(Blocks.NETHER_PORTAL)) {
-                this.handleInsidePortal(blockPos);
-                bl = true;
-            } else if (blockState.is(Blocks.END_GATEWAY)) {
-                BlockEntity blockEntity = this.level.getBlockEntity(blockPos);
-                if (blockEntity instanceof TheEndGatewayBlockEntity && TheEndGatewayBlockEntity.canEntityTeleport(this)) {
-                    TheEndGatewayBlockEntity.teleportEntity(this.level, blockPos, blockState, this, (TheEndGatewayBlockEntity)blockEntity);
+        HitResult movingobjectposition = ProjectileUtil.getHitResult(this, this::canHitEntity);
+        boolean flag = false;
+
+        if (movingobjectposition.getType() == HitResult.Type.BLOCK) {
+            BlockPos blockposition = ((BlockHitResult) movingobjectposition).getBlockPos();
+            BlockState iblockdata = this.level.getBlockState(blockposition);
+
+            if (iblockdata.is(Blocks.NETHER_PORTAL)) {
+                this.handleInsidePortal(blockposition);
+                flag = true;
+            } else if (iblockdata.is(Blocks.END_GATEWAY)) {
+                BlockEntity tileentity = this.level.getBlockEntity(blockposition);
+
+                if (tileentity instanceof TheEndGatewayBlockEntity && TheEndGatewayBlockEntity.canEntityTeleport(this)) {
+                    TheEndGatewayBlockEntity.teleportEntity(this.level, blockposition, iblockdata, this, (TheEndGatewayBlockEntity) tileentity);
                 }
 
-                bl = true;
+                flag = true;
             }
         }
 
-        if (hitResult.getType() != HitResult.Type.MISS && !bl) {
-            this.onHit(hitResult);
+        if (movingobjectposition.getType() != HitResult.Type.MISS && !flag) {
+            // Paper start - Call ProjectileCollideEvent
+            if (movingobjectposition instanceof EntityHitResult) {
+                com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.v1_19_R1.event.CraftEventFactory.callProjectileCollideEvent(this, (EntityHitResult)movingobjectposition);
+                if (event.isCancelled()) {
+                    movingobjectposition = null;
+                }
+            }
+            if (movingobjectposition != null) {
+            // Paper end
+            this.preOnHit(movingobjectposition); // CraftBukkit - projectile hit event
+            } // Paper
         }
 
         this.checkInsideBlocks();
-        Vec3 vec3 = this.getDeltaMovement();
-        double d = this.getX() + vec3.x;
-        double e = this.getY() + vec3.y;
-        double f = this.getZ() + vec3.z;
+        Vec3 vec3d = this.getDeltaMovement();
+        double d0 = this.getX() + vec3d.x;
+        double d1 = this.getY() + vec3d.y;
+        double d2 = this.getZ() + vec3d.z;
+
         this.updateRotation();
-        float h;
+        float f;
+
         if (this.isInWater()) {
-            for(int i = 0; i < 4; ++i) {
-                float g = 0.25F;
-                this.level.addParticle(ParticleTypes.BUBBLE, d - vec3.x * 0.25D, e - vec3.y * 0.25D, f - vec3.z * 0.25D, vec3.x, vec3.y, vec3.z);
+            for (int i = 0; i < 4; ++i) {
+                float f1 = 0.25F;
+
+                this.level.addParticle(ParticleTypes.BUBBLE, d0 - vec3d.x * 0.25D, d1 - vec3d.y * 0.25D, d2 - vec3d.z * 0.25D, vec3d.x, vec3d.y, vec3d.z);
             }
 
-            h = 0.8F;
+            f = 0.8F;
         } else {
-            h = 0.99F;
+            f = 0.99F;
         }
 
-        this.setDeltaMovement(vec3.scale((double)h));
+        this.setDeltaMovement(vec3d.scale((double) f));
         if (!this.isNoGravity()) {
-            Vec3 vec32 = this.getDeltaMovement();
-            this.setDeltaMovement(vec32.x, vec32.y - (double)this.getGravity(), vec32.z);
+            Vec3 vec3d1 = this.getDeltaMovement();
+
+            this.setDeltaMovement(vec3d1.x, vec3d1.y - (double) this.getGravity(), vec3d1.z);
         }
 
-        this.setPos(d, e, f);
+        this.setPos(d0, d1, d2);
     }
 
     protected float getGravity() {
