--- a/net/minecraft/world/entity/monster/Phantom.java
+++ b/net/minecraft/world/entity/monster/Phantom.java
@@ -2,6 +2,7 @@
 
 import java.util.Comparator;
 import java.util.EnumSet;
+import java.util.Iterator;
 import java.util.List;
 import javax.annotation.Nullable;
 import net.minecraft.core.BlockPos;
@@ -40,23 +41,27 @@
 import net.minecraft.world.phys.Vec3;
 
 public class Phantom extends FlyingMob implements Enemy {
+
     public static final float FLAP_DEGREES_PER_TICK = 7.448451F;
     public static final int TICKS_PER_FLAP = Mth.ceil(24.166098F);
     private static final EntityDataAccessor<Integer> ID_SIZE = SynchedEntityData.defineId(Phantom.class, EntityDataSerializers.INT);
-    Vec3 moveTargetPoint = Vec3.ZERO;
-    public BlockPos anchorPoint = BlockPos.ZERO;
-    Phantom.AttackPhase attackPhase = Phantom.AttackPhase.CIRCLE;
+    Vec3 moveTargetPoint;
+    public BlockPos anchorPoint;
+    Phantom.AttackPhase attackPhase;
 
     public Phantom(EntityType<? extends Phantom> type, Level world) {
         super(type, world);
+        this.moveTargetPoint = Vec3.ZERO;
+        this.anchorPoint = BlockPos.ZERO;
+        this.attackPhase = Phantom.AttackPhase.CIRCLE;
         this.xpReward = 5;
         this.moveControl = new Phantom.PhantomMoveControl(this);
-        this.lookControl = new Phantom.PhantomLookControl(this);
+        this.lookControl = new Phantom.PhantomLookControl(this, this);
     }
 
     @Override
     public boolean isFlapping() {
-        return (this.getUniqueFlapTickOffset() + this.tickCount) % TICKS_PER_FLAP == 0;
+        return (this.getUniqueFlapTickOffset() + this.tickCount) % Phantom.TICKS_PER_FLAP == 0;
     }
 
     @Override
@@ -75,25 +80,25 @@
     @Override
     protected void defineSynchedData(SynchedEntityData.Builder builder) {
         super.defineSynchedData(builder);
-        builder.define(ID_SIZE, 0);
+        builder.define(Phantom.ID_SIZE, 0);
     }
 
     public void setPhantomSize(int size) {
-        this.entityData.set(ID_SIZE, Mth.clamp(size, 0, 64));
+        this.entityData.set(Phantom.ID_SIZE, Mth.clamp(size, 0, 64));
     }
 
     private void updatePhantomSizeInfo() {
         this.refreshDimensions();
-        this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue((double)(6 + this.getPhantomSize()));
+        this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue((double) (6 + this.getPhantomSize()));
     }
 
     public int getPhantomSize() {
-        return this.entityData.get(ID_SIZE);
+        return (Integer) this.entityData.get(Phantom.ID_SIZE);
     }
 
     @Override
     public void onSyncedDataUpdated(EntityDataAccessor<?> data) {
-        if (ID_SIZE.equals(data)) {
+        if (Phantom.ID_SIZE.equals(data)) {
             this.updatePhantomSizeInfo();
         }
 
@@ -113,34 +118,27 @@
     public void tick() {
         super.tick();
         if (this.level().isClientSide) {
-            float f = Mth.cos((float)(this.getUniqueFlapTickOffset() + this.tickCount) * 7.448451F * (float) (Math.PI / 180.0) + (float) Math.PI);
-            float g = Mth.cos((float)(this.getUniqueFlapTickOffset() + this.tickCount + 1) * 7.448451F * (float) (Math.PI / 180.0) + (float) Math.PI);
-            if (f > 0.0F && g <= 0.0F) {
-                this.level()
-                    .playLocalSound(
-                        this.getX(),
-                        this.getY(),
-                        this.getZ(),
-                        SoundEvents.PHANTOM_FLAP,
-                        this.getSoundSource(),
-                        0.95F + this.random.nextFloat() * 0.05F,
-                        0.95F + this.random.nextFloat() * 0.05F,
-                        false
-                    );
+            float f = Mth.cos((float) (this.getUniqueFlapTickOffset() + this.tickCount) * 7.448451F * 0.017453292F + 3.1415927F);
+            float f1 = Mth.cos((float) (this.getUniqueFlapTickOffset() + this.tickCount + 1) * 7.448451F * 0.017453292F + 3.1415927F);
+
+            if (f > 0.0F && f1 <= 0.0F) {
+                this.level().playLocalSound(this.getX(), this.getY(), this.getZ(), SoundEvents.PHANTOM_FLAP, this.getSoundSource(), 0.95F + this.random.nextFloat() * 0.05F, 0.95F + this.random.nextFloat() * 0.05F, false);
             }
 
-            float h = this.getBbWidth() * 1.48F;
-            float i = Mth.cos(this.getYRot() * (float) (Math.PI / 180.0)) * h;
-            float j = Mth.sin(this.getYRot() * (float) (Math.PI / 180.0)) * h;
-            float k = (0.3F + f * 0.45F) * this.getBbHeight() * 2.5F;
-            this.level().addParticle(ParticleTypes.MYCELIUM, this.getX() + (double)i, this.getY() + (double)k, this.getZ() + (double)j, 0.0, 0.0, 0.0);
-            this.level().addParticle(ParticleTypes.MYCELIUM, this.getX() - (double)i, this.getY() + (double)k, this.getZ() - (double)j, 0.0, 0.0, 0.0);
+            float f2 = this.getBbWidth() * 1.48F;
+            float f3 = Mth.cos(this.getYRot() * 0.017453292F) * f2;
+            float f4 = Mth.sin(this.getYRot() * 0.017453292F) * f2;
+            float f5 = (0.3F + f * 0.45F) * this.getBbHeight() * 2.5F;
+
+            this.level().addParticle(ParticleTypes.MYCELIUM, this.getX() + (double) f3, this.getY() + (double) f5, this.getZ() + (double) f4, 0.0D, 0.0D, 0.0D);
+            this.level().addParticle(ParticleTypes.MYCELIUM, this.getX() - (double) f3, this.getY() + (double) f5, this.getZ() - (double) f4, 0.0D, 0.0D, 0.0D);
         }
+
     }
 
     @Override
     public void aiStep() {
-        if (this.isAlive() && this.isSunBurnTick()) {
+        if (this.isAlive() && this.shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API
             this.igniteForSeconds(8.0F);
         }
 
@@ -167,6 +165,14 @@
         }
 
         this.setPhantomSize(nbt.getInt("Size"));
+        // Paper start
+        if (nbt.hasUUID("Paper.SpawningEntity")) {
+            this.spawningEntity = nbt.getUUID("Paper.SpawningEntity");
+        }
+        if (nbt.contains("Paper.ShouldBurnInDay")) {
+            this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay");
+        }
+        // Paper end
     }
 
     @Override
@@ -176,6 +182,12 @@
         nbt.putInt("AY", this.anchorPoint.getY());
         nbt.putInt("AZ", this.anchorPoint.getZ());
         nbt.putInt("Size", this.getPhantomSize());
+        // Paper start
+        if (this.spawningEntity != null) {
+            nbt.putUUID("Paper.SpawningEntity", this.spawningEntity);
+        }
+        nbt.putBoolean("Paper.ShouldBurnInDay", shouldBurnInDay);
+        // Paper end
     }
 
     @Override
@@ -216,57 +228,121 @@
     @Override
     public EntityDimensions getDefaultDimensions(Pose pose) {
         int i = this.getPhantomSize();
-        EntityDimensions entityDimensions = super.getDefaultDimensions(pose);
-        return entityDimensions.scale(1.0F + 0.15F * (float)i);
+        EntityDimensions entitysize = super.getDefaultDimensions(pose);
+
+        return entitysize.scale(1.0F + 0.15F * (float) i);
     }
 
-    static enum AttackPhase {
-        CIRCLE,
-        SWOOP;
+    // Paper start
+    @Nullable
+    java.util.UUID spawningEntity;
+
+    @Nullable
+    public java.util.UUID getSpawningEntity() {
+        return this.spawningEntity;
     }
+    public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; }
+    private boolean shouldBurnInDay = true;
+    public boolean shouldBurnInDay() { return shouldBurnInDay; }
+    public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; }
+    // Paper end
 
-    class PhantomAttackPlayerTargetGoal extends Goal {
-        private final TargetingConditions attackTargeting = TargetingConditions.forCombat().range(64.0);
-        private int nextScanTick = reducedTickDelay(20);
+    private static enum AttackPhase {
+
+        CIRCLE, SWOOP;
+
+        private AttackPhase() {}
+    }
+
+    private class PhantomMoveControl extends MoveControl {
+
+        private float speed = 0.1F;
+
+        public PhantomMoveControl(final Mob entity) {
+            super(entity);
+        }
 
         @Override
-        public boolean canUse() {
-            if (this.nextScanTick > 0) {
-                this.nextScanTick--;
-                return false;
-            } else {
-                this.nextScanTick = reducedTickDelay(60);
-                List<Player> list = Phantom.this.level()
-                    .getNearbyPlayers(this.attackTargeting, Phantom.this, Phantom.this.getBoundingBox().inflate(16.0, 64.0, 16.0));
-                if (!list.isEmpty()) {
-                    list.sort(Comparator.<Player, Double>comparing(Entity::getY).reversed());
+        public void tick() {
+            if (Phantom.this.horizontalCollision) {
+                Phantom.this.setYRot(Phantom.this.getYRot() + 180.0F);
+                this.speed = 0.1F;
+            }
 
-                    for (Player player : list) {
-                        if (Phantom.this.canAttack(player, TargetingConditions.DEFAULT)) {
-                            Phantom.this.setTarget(player);
-                            return true;
-                        }
-                    }
+            double d0 = Phantom.this.moveTargetPoint.x - Phantom.this.getX();
+            double d1 = Phantom.this.moveTargetPoint.y - Phantom.this.getY();
+            double d2 = Phantom.this.moveTargetPoint.z - Phantom.this.getZ();
+            double d3 = Math.sqrt(d0 * d0 + d2 * d2);
+
+            if (Math.abs(d3) > 9.999999747378752E-6D) {
+                double d4 = 1.0D - Math.abs(d1 * 0.699999988079071D) / d3;
+
+                d0 *= d4;
+                d2 *= d4;
+                d3 = Math.sqrt(d0 * d0 + d2 * d2);
+                double d5 = Math.sqrt(d0 * d0 + d2 * d2 + d1 * d1);
+                float f = Phantom.this.getYRot();
+                float f1 = (float) Mth.atan2(d2, d0);
+                float f2 = Mth.wrapDegrees(Phantom.this.getYRot() + 90.0F);
+                float f3 = Mth.wrapDegrees(f1 * 57.295776F);
+
+                Phantom.this.setYRot(Mth.approachDegrees(f2, f3, 4.0F) - 90.0F);
+                Phantom.this.yBodyRot = Phantom.this.getYRot();
+                if (Mth.degreesDifferenceAbs(f, Phantom.this.getYRot()) < 3.0F) {
+                    this.speed = Mth.approach(this.speed, 1.8F, 0.005F * (1.8F / this.speed));
+                } else {
+                    this.speed = Mth.approach(this.speed, 0.2F, 0.025F);
                 }
 
-                return false;
+                float f4 = (float) (-(Mth.atan2(-d1, d3) * 57.2957763671875D));
+
+                Phantom.this.setXRot(f4);
+                float f5 = Phantom.this.getYRot() + 90.0F;
+                double d6 = (double) (this.speed * Mth.cos(f5 * 0.017453292F)) * Math.abs(d0 / d5);
+                double d7 = (double) (this.speed * Mth.sin(f5 * 0.017453292F)) * Math.abs(d2 / d5);
+                double d8 = (double) (this.speed * Mth.sin(f4 * 0.017453292F)) * Math.abs(d1 / d5);
+                Vec3 vec3d = Phantom.this.getDeltaMovement();
+
+                Phantom.this.setDeltaMovement(vec3d.add((new Vec3(d6, d8, d7)).subtract(vec3d).scale(0.2D)));
             }
+
+        }
+    }
+
+    private class PhantomLookControl extends LookControl {
+
+        public PhantomLookControl(final Phantom entity, final Mob phantom) {
+            super(phantom);
         }
 
         @Override
-        public boolean canContinueToUse() {
-            LivingEntity livingEntity = Phantom.this.getTarget();
-            return livingEntity != null && Phantom.this.canAttack(livingEntity, TargetingConditions.DEFAULT);
+        public void tick() {}
+    }
+
+    private class PhantomBodyRotationControl extends BodyRotationControl {
+
+        public PhantomBodyRotationControl(final Mob entity) {
+            super(entity);
+        }
+
+        @Override
+        public void clientTick() {
+            Phantom.this.yHeadRot = Phantom.this.yBodyRot;
+            Phantom.this.yBodyRot = Phantom.this.getYRot();
         }
     }
 
-    class PhantomAttackStrategyGoal extends Goal {
+    private class PhantomAttackStrategyGoal extends Goal {
+
         private int nextSweepTick;
 
+        PhantomAttackStrategyGoal() {}
+
         @Override
         public boolean canUse() {
-            LivingEntity livingEntity = Phantom.this.getTarget();
-            return livingEntity != null && Phantom.this.canAttack(livingEntity, TargetingConditions.DEFAULT);
+            LivingEntity entityliving = Phantom.this.getTarget();
+
+            return entityliving != null ? Phantom.this.canAttack(entityliving, TargetingConditions.DEFAULT) : false;
         }
 
         @Override
@@ -278,15 +354,13 @@
 
         @Override
         public void stop() {
-            Phantom.this.anchorPoint = Phantom.this.level()
-                .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, Phantom.this.anchorPoint)
-                .above(10 + Phantom.this.random.nextInt(20));
+            Phantom.this.anchorPoint = Phantom.this.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, Phantom.this.anchorPoint).above(10 + Phantom.this.random.nextInt(20));
         }
 
         @Override
         public void tick() {
             if (Phantom.this.attackPhase == Phantom.AttackPhase.CIRCLE) {
-                this.nextSweepTick--;
+                --this.nextSweepTick;
                 if (this.nextSweepTick <= 0) {
                     Phantom.this.attackPhase = Phantom.AttackPhase.SWOOP;
                     this.setAnchorAboveTarget();
@@ -294,36 +368,112 @@
                     Phantom.this.playSound(SoundEvents.PHANTOM_SWOOP, 10.0F, 0.95F + Phantom.this.random.nextFloat() * 0.1F);
                 }
             }
+
         }
 
         private void setAnchorAboveTarget() {
             Phantom.this.anchorPoint = Phantom.this.getTarget().blockPosition().above(20 + Phantom.this.random.nextInt(20));
             if (Phantom.this.anchorPoint.getY() < Phantom.this.level().getSeaLevel()) {
-                Phantom.this.anchorPoint = new BlockPos(
-                    Phantom.this.anchorPoint.getX(), Phantom.this.level().getSeaLevel() + 1, Phantom.this.anchorPoint.getZ()
-                );
+                Phantom.this.anchorPoint = new BlockPos(Phantom.this.anchorPoint.getX(), Phantom.this.level().getSeaLevel() + 1, Phantom.this.anchorPoint.getZ());
             }
+
         }
     }
 
-    class PhantomBodyRotationControl extends BodyRotationControl {
-        public PhantomBodyRotationControl(final Mob entity) {
-            super(entity);
+    private class PhantomSweepAttackGoal extends Phantom.PhantomMoveTargetGoal {
+
+        private static final int CAT_SEARCH_TICK_DELAY = 20;
+        private boolean isScaredOfCat;
+        private int catSearchTick;
+
+        PhantomSweepAttackGoal() {
+            super();
         }
 
         @Override
-        public void clientTick() {
-            Phantom.this.yHeadRot = Phantom.this.yBodyRot;
-            Phantom.this.yBodyRot = Phantom.this.getYRot();
+        public boolean canUse() {
+            return Phantom.this.getTarget() != null && Phantom.this.attackPhase == Phantom.AttackPhase.SWOOP;
+        }
+
+        @Override
+        public boolean canContinueToUse() {
+            LivingEntity entityliving = Phantom.this.getTarget();
+
+            if (entityliving == null) {
+                return false;
+            } else if (!entityliving.isAlive()) {
+                return false;
+            } else {
+                if (entityliving instanceof Player) {
+                    Player entityhuman = (Player) entityliving;
+
+                    if (entityliving.isSpectator() || entityhuman.isCreative()) {
+                        return false;
+                    }
+                }
+
+                if (!this.canUse()) {
+                    return false;
+                } else {
+                    if (Phantom.this.tickCount > this.catSearchTick) {
+                        this.catSearchTick = Phantom.this.tickCount + 20;
+                        List<Cat> list = Phantom.this.level().getEntitiesOfClass(Cat.class, Phantom.this.getBoundingBox().inflate(16.0D), EntitySelector.ENTITY_STILL_ALIVE);
+                        Iterator iterator = list.iterator();
+
+                        while (iterator.hasNext()) {
+                            Cat entitycat = (Cat) iterator.next();
+
+                            entitycat.hiss();
+                        }
+
+                        this.isScaredOfCat = !list.isEmpty();
+                    }
+
+                    return !this.isScaredOfCat;
+                }
+            }
+        }
+
+        @Override
+        public void start() {}
+
+        @Override
+        public void stop() {
+            Phantom.this.setTarget((LivingEntity) null);
+            Phantom.this.attackPhase = Phantom.AttackPhase.CIRCLE;
+        }
+
+        @Override
+        public void tick() {
+            LivingEntity entityliving = Phantom.this.getTarget();
+
+            if (entityliving != null) {
+                Phantom.this.moveTargetPoint = new Vec3(entityliving.getX(), entityliving.getY(0.5D), entityliving.getZ());
+                if (Phantom.this.getBoundingBox().inflate(0.20000000298023224D).intersects(entityliving.getBoundingBox())) {
+                    Phantom.this.doHurtTarget(entityliving);
+                    Phantom.this.attackPhase = Phantom.AttackPhase.CIRCLE;
+                    if (!Phantom.this.isSilent()) {
+                        Phantom.this.level().levelEvent(1039, Phantom.this.blockPosition(), 0);
+                    }
+                } else if (Phantom.this.horizontalCollision || Phantom.this.hurtTime > 0) {
+                    Phantom.this.attackPhase = Phantom.AttackPhase.CIRCLE;
+                }
+
+            }
         }
     }
 
-    class PhantomCircleAroundAnchorGoal extends Phantom.PhantomMoveTargetGoal {
+    private class PhantomCircleAroundAnchorGoal extends Phantom.PhantomMoveTargetGoal {
+
         private float angle;
         private float distance;
         private float height;
         private float clockwise;
 
+        PhantomCircleAroundAnchorGoal() {
+            super();
+        }
+
         @Override
         public boolean canUse() {
             return Phantom.this.getTarget() == null || Phantom.this.attackPhase == Phantom.AttackPhase.CIRCLE;
@@ -344,7 +494,7 @@
             }
 
             if (Phantom.this.random.nextInt(this.adjustedTickDelay(250)) == 0) {
-                this.distance++;
+                ++this.distance;
                 if (this.distance > 15.0F) {
                     this.distance = 5.0F;
                     this.clockwise = -this.clockwise;
@@ -352,7 +502,7 @@
             }
 
             if (Phantom.this.random.nextInt(this.adjustedTickDelay(450)) == 0) {
-                this.angle = Phantom.this.random.nextFloat() * 2.0F * (float) Math.PI;
+                this.angle = Phantom.this.random.nextFloat() * 2.0F * 3.1415927F;
                 this.selectNext();
             }
 
@@ -369,6 +519,7 @@
                 this.height = Math.min(-1.0F, this.height);
                 this.selectNext();
             }
+
         }
 
         private void selectNext() {
@@ -376,147 +527,62 @@
                 Phantom.this.anchorPoint = Phantom.this.blockPosition();
             }
 
-            this.angle = this.angle + this.clockwise * 15.0F * (float) (Math.PI / 180.0);
-            Phantom.this.moveTargetPoint = Vec3.atLowerCornerOf(Phantom.this.anchorPoint)
-                .add((double)(this.distance * Mth.cos(this.angle)), (double)(-4.0F + this.height), (double)(this.distance * Mth.sin(this.angle)));
-        }
-    }
-
-    class PhantomLookControl extends LookControl {
-        public PhantomLookControl(final Mob entity) {
-            super(entity);
-        }
-
-        @Override
-        public void tick() {
-        }
-    }
-
-    class PhantomMoveControl extends MoveControl {
-        private float speed = 0.1F;
-
-        public PhantomMoveControl(final Mob owner) {
-            super(owner);
-        }
-
-        @Override
-        public void tick() {
-            if (Phantom.this.horizontalCollision) {
-                Phantom.this.setYRot(Phantom.this.getYRot() + 180.0F);
-                this.speed = 0.1F;
-            }
-
-            double d = Phantom.this.moveTargetPoint.x - Phantom.this.getX();
-            double e = Phantom.this.moveTargetPoint.y - Phantom.this.getY();
-            double f = Phantom.this.moveTargetPoint.z - Phantom.this.getZ();
-            double g = Math.sqrt(d * d + f * f);
-            if (Math.abs(g) > 1.0E-5F) {
-                double h = 1.0 - Math.abs(e * 0.7F) / g;
-                d *= h;
-                f *= h;
-                g = Math.sqrt(d * d + f * f);
-                double i = Math.sqrt(d * d + f * f + e * e);
-                float j = Phantom.this.getYRot();
-                float k = (float)Mth.atan2(f, d);
-                float l = Mth.wrapDegrees(Phantom.this.getYRot() + 90.0F);
-                float m = Mth.wrapDegrees(k * (180.0F / (float)Math.PI));
-                Phantom.this.setYRot(Mth.approachDegrees(l, m, 4.0F) - 90.0F);
-                Phantom.this.yBodyRot = Phantom.this.getYRot();
-                if (Mth.degreesDifferenceAbs(j, Phantom.this.getYRot()) < 3.0F) {
-                    this.speed = Mth.approach(this.speed, 1.8F, 0.005F * (1.8F / this.speed));
-                } else {
-                    this.speed = Mth.approach(this.speed, 0.2F, 0.025F);
-                }
-
-                float n = (float)(-(Mth.atan2(-e, g) * 180.0F / (float)Math.PI));
-                Phantom.this.setXRot(n);
-                float o = Phantom.this.getYRot() + 90.0F;
-                double p = (double)(this.speed * Mth.cos(o * (float) (Math.PI / 180.0))) * Math.abs(d / i);
-                double q = (double)(this.speed * Mth.sin(o * (float) (Math.PI / 180.0))) * Math.abs(f / i);
-                double r = (double)(this.speed * Mth.sin(n * (float) (Math.PI / 180.0))) * Math.abs(e / i);
-                Vec3 vec3 = Phantom.this.getDeltaMovement();
-                Phantom.this.setDeltaMovement(vec3.add(new Vec3(p, r, q).subtract(vec3).scale(0.2)));
-            }
+            this.angle += this.clockwise * 15.0F * 0.017453292F;
+            Phantom.this.moveTargetPoint = Vec3.atLowerCornerOf(Phantom.this.anchorPoint).add((double) (this.distance * Mth.cos(this.angle)), (double) (-4.0F + this.height), (double) (this.distance * Mth.sin(this.angle)));
         }
     }
 
-    abstract class PhantomMoveTargetGoal extends Goal {
-        public PhantomMoveTargetGoal() {
-            this.setFlags(EnumSet.of(Goal.Flag.MOVE));
-        }
+    private class PhantomAttackPlayerTargetGoal extends Goal {
 
-        protected boolean touchingTarget() {
-            return Phantom.this.moveTargetPoint.distanceToSqr(Phantom.this.getX(), Phantom.this.getY(), Phantom.this.getZ()) < 4.0;
-        }
-    }
+        private final TargetingConditions attackTargeting = TargetingConditions.forCombat().range(64.0D);
+        private int nextScanTick = reducedTickDelay(20);
 
-    class PhantomSweepAttackGoal extends Phantom.PhantomMoveTargetGoal {
-        private static final int CAT_SEARCH_TICK_DELAY = 20;
-        private boolean isScaredOfCat;
-        private int catSearchTick;
+        PhantomAttackPlayerTargetGoal() {}
 
         @Override
         public boolean canUse() {
-            return Phantom.this.getTarget() != null && Phantom.this.attackPhase == Phantom.AttackPhase.SWOOP;
-        }
-
-        @Override
-        public boolean canContinueToUse() {
-            LivingEntity livingEntity = Phantom.this.getTarget();
-            if (livingEntity == null) {
-                return false;
-            } else if (!livingEntity.isAlive()) {
+            if (this.nextScanTick > 0) {
+                --this.nextScanTick;
                 return false;
             } else {
-                if (livingEntity instanceof Player player && (livingEntity.isSpectator() || player.isCreative())) {
-                    return false;
-                }
+                this.nextScanTick = reducedTickDelay(60);
+                List<Player> list = Phantom.this.level().getNearbyPlayers(this.attackTargeting, Phantom.this, Phantom.this.getBoundingBox().inflate(16.0D, 64.0D, 16.0D));
 
-                if (!this.canUse()) {
-                    return false;
-                } else {
-                    if (Phantom.this.tickCount > this.catSearchTick) {
-                        this.catSearchTick = Phantom.this.tickCount + 20;
-                        List<Cat> list = Phantom.this.level()
-                            .getEntitiesOfClass(Cat.class, Phantom.this.getBoundingBox().inflate(16.0), EntitySelector.ENTITY_STILL_ALIVE);
+                if (!list.isEmpty()) {
+                    list.sort(Comparator.comparing((Entity e) -> { return e.getY(); }).reversed()); // CraftBukkit - decompile error
+                    Iterator iterator = list.iterator();
 
-                        for (Cat cat : list) {
-                            cat.hiss();
-                        }
+                    while (iterator.hasNext()) {
+                        Player entityhuman = (Player) iterator.next();
 
-                        this.isScaredOfCat = !list.isEmpty();
+                        if (Phantom.this.canAttack(entityhuman, TargetingConditions.DEFAULT)) {
+                            if (!level().paperConfig().entities.behavior.phantomsOnlyAttackInsomniacs || EntitySelector.IS_INSOMNIAC.test(entityhuman)) // Paper - Add phantom creative and insomniac controls
+                            Phantom.this.setTarget(entityhuman, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit - reason
+                            return true;
+                        }
                     }
-
-                    return !this.isScaredOfCat;
                 }
+
+                return false;
             }
         }
 
         @Override
-        public void start() {
+        public boolean canContinueToUse() {
+            LivingEntity entityliving = Phantom.this.getTarget();
+
+            return entityliving != null ? Phantom.this.canAttack(entityliving, TargetingConditions.DEFAULT) : false;
         }
+    }
 
-        @Override
-        public void stop() {
-            Phantom.this.setTarget(null);
-            Phantom.this.attackPhase = Phantom.AttackPhase.CIRCLE;
+    private abstract class PhantomMoveTargetGoal extends Goal {
+
+        public PhantomMoveTargetGoal() {
+            this.setFlags(EnumSet.of(Goal.Flag.MOVE));
         }
 
-        @Override
-        public void tick() {
-            LivingEntity livingEntity = Phantom.this.getTarget();
-            if (livingEntity != null) {
-                Phantom.this.moveTargetPoint = new Vec3(livingEntity.getX(), livingEntity.getY(0.5), livingEntity.getZ());
-                if (Phantom.this.getBoundingBox().inflate(0.2F).intersects(livingEntity.getBoundingBox())) {
-                    Phantom.this.doHurtTarget(livingEntity);
-                    Phantom.this.attackPhase = Phantom.AttackPhase.CIRCLE;
-                    if (!Phantom.this.isSilent()) {
-                        Phantom.this.level().levelEvent(1039, Phantom.this.blockPosition(), 0);
-                    }
-                } else if (Phantom.this.horizontalCollision || Phantom.this.hurtTime > 0) {
-                    Phantom.this.attackPhase = Phantom.AttackPhase.CIRCLE;
-                }
-            }
+        protected boolean touchingTarget() {
+            return Phantom.this.moveTargetPoint.distanceToSqr(Phantom.this.getX(), Phantom.this.getY(), Phantom.this.getZ()) < 4.0D;
         }
     }
 }
