--- a/net/minecraft/world/entity/projectile/EyeOfEnder.java
+++ b/net/minecraft/world/entity/projectile/EyeOfEnder.java
@@ -15,8 +15,12 @@
 import net.minecraft.world.item.Items;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.phys.Vec3;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityRemoveEvent;
+// CraftBukkit end
 
 public class EyeOfEnder extends Entity implements ItemSupplier {
+
     private static final EntityDataAccessor<ItemStack> DATA_ITEM_STACK = SynchedEntityData.defineId(EyeOfEnder.class, EntityDataSerializers.ITEM_STACK);
     public double tx;
     public double ty;
@@ -33,119 +37,126 @@
         this.setPos(x, y, z);
     }
 
-    public void setItem(ItemStack itemStack) {
-        if (itemStack.isEmpty()) {
-            this.getEntityData().set(DATA_ITEM_STACK, this.getDefaultItem());
+    public void setItem(ItemStack itemstack) {
+        if (itemstack.isEmpty()) {
+            this.getEntityData().set(EyeOfEnder.DATA_ITEM_STACK, this.getDefaultItem());
         } else {
-            this.getEntityData().set(DATA_ITEM_STACK, itemStack.copyWithCount(1));
+            this.getEntityData().set(EyeOfEnder.DATA_ITEM_STACK, itemstack.copyWithCount(1));
         }
+
     }
 
     @Override
     public ItemStack getItem() {
-        return this.getEntityData().get(DATA_ITEM_STACK);
+        return (ItemStack) this.getEntityData().get(EyeOfEnder.DATA_ITEM_STACK);
     }
 
     @Override
     protected void defineSynchedData(SynchedEntityData.Builder builder) {
-        builder.define(DATA_ITEM_STACK, this.getDefaultItem());
+        builder.define(EyeOfEnder.DATA_ITEM_STACK, this.getDefaultItem());
     }
 
     @Override
     public boolean shouldRenderAtSqrDistance(double distance) {
-        double d = this.getBoundingBox().getSize() * 4.0;
-        if (Double.isNaN(d)) {
-            d = 4.0;
+        double d1 = this.getBoundingBox().getSize() * 4.0D;
+
+        if (Double.isNaN(d1)) {
+            d1 = 4.0D;
         }
 
-        d *= 64.0;
-        return distance < d * d;
+        d1 *= 64.0D;
+        return distance < d1 * d1;
     }
 
     public void signalTo(BlockPos pos) {
-        double d = (double)pos.getX();
+        // Paper start - Change EnderEye target without changing other things
+        this.signalTo(pos, true);
+    }
+    public void signalTo(BlockPos pos, boolean update) {
+        // Paper end - Change EnderEye target without changing other things
+        double d0 = (double) pos.getX();
         int i = pos.getY();
-        double e = (double)pos.getZ();
-        double f = d - this.getX();
-        double g = e - this.getZ();
-        double h = Math.sqrt(f * f + g * g);
-        if (h > 12.0) {
-            this.tx = this.getX() + f / h * 12.0;
-            this.tz = this.getZ() + g / h * 12.0;
-            this.ty = this.getY() + 8.0;
+        double d1 = (double) pos.getZ();
+        double d2 = d0 - this.getX();
+        double d3 = d1 - this.getZ();
+        double d4 = Math.sqrt(d2 * d2 + d3 * d3);
+
+        if (d4 > 12.0D) {
+            this.tx = this.getX() + d2 / d4 * 12.0D;
+            this.tz = this.getZ() + d3 / d4 * 12.0D;
+            this.ty = this.getY() + 8.0D;
         } else {
-            this.tx = d;
-            this.ty = (double)i;
-            this.tz = e;
+            this.tx = d0;
+            this.ty = (double) i;
+            this.tz = d1;
         }
 
+        if (update) { // Paper - Change EnderEye target without changing other things
         this.life = 0;
         this.surviveAfterDeath = this.random.nextInt(5) > 0;
+        } // Paper - Change EnderEye target without changing other things
     }
 
     @Override
     public void lerpMotion(double x, double y, double z) {
         this.setDeltaMovement(x, y, z);
         if (this.xRotO == 0.0F && this.yRotO == 0.0F) {
-            double d = Math.sqrt(x * x + z * z);
-            this.setYRot((float)(Mth.atan2(x, z) * 180.0F / (float)Math.PI));
-            this.setXRot((float)(Mth.atan2(y, d) * 180.0F / (float)Math.PI));
+            double d3 = Math.sqrt(x * x + z * z);
+
+            this.setYRot((float) (Mth.atan2(x, z) * 57.2957763671875D));
+            this.setXRot((float) (Mth.atan2(y, d3) * 57.2957763671875D));
             this.yRotO = this.getYRot();
             this.xRotO = this.getXRot();
         }
+
     }
 
     @Override
     public void tick() {
         super.tick();
-        Vec3 vec3 = this.getDeltaMovement();
-        double d = this.getX() + vec3.x;
-        double e = this.getY() + vec3.y;
-        double f = this.getZ() + vec3.z;
-        double g = vec3.horizontalDistance();
-        this.setXRot(Projectile.lerpRotation(this.xRotO, (float)(Mth.atan2(vec3.y, g) * 180.0F / (float)Math.PI)));
-        this.setYRot(Projectile.lerpRotation(this.yRotO, (float)(Mth.atan2(vec3.x, vec3.z) * 180.0F / (float)Math.PI)));
+        Vec3 vec3d = this.getDeltaMovement();
+        double d0 = this.getX() + vec3d.x;
+        double d1 = this.getY() + vec3d.y;
+        double d2 = this.getZ() + vec3d.z;
+        double d3 = vec3d.horizontalDistance();
+
+        this.setXRot(Projectile.lerpRotation(this.xRotO, (float) (Mth.atan2(vec3d.y, d3) * 57.2957763671875D)));
+        this.setYRot(Projectile.lerpRotation(this.yRotO, (float) (Mth.atan2(vec3d.x, vec3d.z) * 57.2957763671875D)));
         if (!this.level().isClientSide) {
-            double h = this.tx - d;
-            double i = this.tz - f;
-            float j = (float)Math.sqrt(h * h + i * i);
-            float k = (float)Mth.atan2(i, h);
-            double l = Mth.lerp(0.0025, g, (double)j);
-            double m = vec3.y;
-            if (j < 1.0F) {
-                l *= 0.8;
-                m *= 0.8;
+            double d4 = this.tx - d0;
+            double d5 = this.tz - d2;
+            float f = (float) Math.sqrt(d4 * d4 + d5 * d5);
+            float f1 = (float) Mth.atan2(d5, d4);
+            double d6 = Mth.lerp(0.0025D, d3, (double) f);
+            double d7 = vec3d.y;
+
+            if (f < 1.0F) {
+                d6 *= 0.8D;
+                d7 *= 0.8D;
             }
 
-            int n = this.getY() < this.ty ? 1 : -1;
-            vec3 = new Vec3(Math.cos((double)k) * l, m + ((double)n - m) * 0.015F, Math.sin((double)k) * l);
-            this.setDeltaMovement(vec3);
+            int i = this.getY() < this.ty ? 1 : -1;
+
+            vec3d = new Vec3(Math.cos((double) f1) * d6, d7 + ((double) i - d7) * 0.014999999664723873D, Math.sin((double) f1) * d6);
+            this.setDeltaMovement(vec3d);
         }
 
-        float o = 0.25F;
+        float f2 = 0.25F;
+
         if (this.isInWater()) {
-            for (int p = 0; p < 4; p++) {
-                this.level().addParticle(ParticleTypes.BUBBLE, d - vec3.x * 0.25, e - vec3.y * 0.25, f - vec3.z * 0.25, vec3.x, vec3.y, vec3.z);
+            for (int j = 0; j < 4; ++j) {
+                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);
             }
         } else {
-            this.level()
-                .addParticle(
-                    ParticleTypes.PORTAL,
-                    d - vec3.x * 0.25 + this.random.nextDouble() * 0.6 - 0.3,
-                    e - vec3.y * 0.25 - 0.5,
-                    f - vec3.z * 0.25 + this.random.nextDouble() * 0.6 - 0.3,
-                    vec3.x,
-                    vec3.y,
-                    vec3.z
-                );
+            this.level().addParticle(ParticleTypes.PORTAL, d0 - vec3d.x * 0.25D + this.random.nextDouble() * 0.6D - 0.3D, d1 - vec3d.y * 0.25D - 0.5D, d2 - vec3d.z * 0.25D + this.random.nextDouble() * 0.6D - 0.3D, vec3d.x, vec3d.y, vec3d.z);
         }
 
         if (!this.level().isClientSide) {
-            this.setPos(d, e, f);
-            this.life++;
+            this.setPos(d0, d1, d2);
+            ++this.life;
             if (this.life > 80 && !this.level().isClientSide) {
                 this.playSound(SoundEvents.ENDER_EYE_DEATH, 1.0F, 1.0F);
-                this.discard();
+                this.discard(this.surviveAfterDeath ? EntityRemoveEvent.Cause.DROP : EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
                 if (this.surviveAfterDeath) {
                     this.level().addFreshEntity(new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), this.getItem()));
                 } else {
@@ -153,8 +164,9 @@
                 }
             }
         } else {
-            this.setPosRaw(d, e, f);
+            this.setPosRaw(d0, d1, d2);
         }
+
     }
 
     @Override
@@ -165,10 +177,16 @@
     @Override
     public void readAdditionalSaveData(CompoundTag nbt) {
         if (nbt.contains("Item", 10)) {
-            this.setItem(ItemStack.parse(this.registryAccess(), nbt.getCompound("Item")).orElse(this.getDefaultItem()));
+            // CraftBukkit start - SPIGOT-6103 summon, see also SPIGOT-5474
+            ItemStack itemstack = (ItemStack) ItemStack.parse(this.registryAccess(), nbt.getCompound("Item")).orElse(this.getDefaultItem());
+            if (!itemstack.isEmpty()) {
+                this.setItem(itemstack);
+            }
+            // CraftBukkit end
         } else {
             this.setItem(this.getDefaultItem());
         }
+
     }
 
     private ItemStack getDefaultItem() {
