--- a/net/minecraft/world/entity/monster/Shulker.java
+++ b/net/minecraft/world/entity/monster/Shulker.java
@@ -1,11 +1,14 @@
 package net.minecraft.world.entity.monster;
 
 import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Optional;
 import javax.annotation.Nullable;
 import net.minecraft.Util;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
+import net.minecraft.core.Holder;
 import net.minecraft.core.Vec3i;
 import net.minecraft.nbt.CompoundTag;
 import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
@@ -49,16 +52,22 @@
 import net.minecraft.world.level.ServerLevelAccessor;
 import net.minecraft.world.level.block.Blocks;
 import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.entity.EntityTypeTest;
 import net.minecraft.world.level.gameevent.GameEvent;
 import net.minecraft.world.phys.AABB;
 import net.minecraft.world.phys.Vec3;
 import org.joml.Vector3f;
 
+// CraftBukkit start
+import org.bukkit.craftbukkit.util.CraftLocation;
+import org.bukkit.event.entity.EntityTeleportEvent;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
+
 public class Shulker extends AbstractGolem implements VariantHolder<Optional<DyeColor>>, Enemy {
+
     private static final ResourceLocation COVERED_ARMOR_MODIFIER_ID = ResourceLocation.withDefaultNamespace("covered");
-    private static final AttributeModifier COVERED_ARMOR_MODIFIER = new AttributeModifier(
-        COVERED_ARMOR_MODIFIER_ID, 20.0, AttributeModifier.Operation.ADD_VALUE
-    );
+    private static final AttributeModifier COVERED_ARMOR_MODIFIER = new AttributeModifier(Shulker.COVERED_ARMOR_MODIFIER_ID, 20.0D, AttributeModifier.Operation.ADD_VALUE);
     protected static final EntityDataAccessor<Direction> DATA_ATTACH_FACE_ID = SynchedEntityData.defineId(Shulker.class, EntityDataSerializers.DIRECTION);
     protected static final EntityDataAccessor<Byte> DATA_PEEK_ID = SynchedEntityData.defineId(Shulker.class, EntityDataSerializers.BYTE);
     public static final EntityDataAccessor<Byte> DATA_COLOR_ID = SynchedEntityData.defineId(Shulker.class, EntityDataSerializers.BYTE);
@@ -69,9 +78,10 @@
     private static final int OTHER_SHULKER_SCAN_RADIUS = 8;
     private static final int OTHER_SHULKER_LIMIT = 5;
     private static final float PEEK_PER_TICK = 0.05F;
-    static final Vector3f FORWARD = Util.make(() -> {
-        Vec3i vec3i = Direction.SOUTH.getNormal();
-        return new Vector3f((float)vec3i.getX(), (float)vec3i.getY(), (float)vec3i.getZ());
+    static final Vector3f FORWARD = (Vector3f) Util.make(() -> {
+        Vec3i baseblockposition = Direction.SOUTH.getNormal();
+
+        return new Vector3f((float) baseblockposition.getX(), (float) baseblockposition.getY(), (float) baseblockposition.getZ());
     });
     private static final float MAX_SCALE = 3.0F;
     private float currentPeekAmountO;
@@ -93,7 +103,7 @@
         this.goalSelector.addGoal(4, new Shulker.ShulkerAttackGoal());
         this.goalSelector.addGoal(7, new Shulker.ShulkerPeekGoal());
         this.goalSelector.addGoal(8, new RandomLookAroundGoal(this));
-        this.targetSelector.addGoal(1, new HurtByTargetGoal(this, this.getClass()).setAlertOthers());
+        this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{this.getClass()})).setAlertOthers());
         this.targetSelector.addGoal(2, new Shulker.ShulkerNearestAttackGoal(this));
         this.targetSelector.addGoal(3, new Shulker.ShulkerDefenseAttackGoal(this));
     }
@@ -118,6 +128,7 @@
         if (!this.isClosed()) {
             super.playAmbientSound();
         }
+
     }
 
     @Override
@@ -133,13 +144,13 @@
     @Override
     protected void defineSynchedData(SynchedEntityData.Builder builder) {
         super.defineSynchedData(builder);
-        builder.define(DATA_ATTACH_FACE_ID, Direction.DOWN);
-        builder.define(DATA_PEEK_ID, (byte)0);
-        builder.define(DATA_COLOR_ID, (byte)16);
+        builder.define(Shulker.DATA_ATTACH_FACE_ID, Direction.DOWN);
+        builder.define(Shulker.DATA_PEEK_ID, (byte) 0);
+        builder.define(Shulker.DATA_COLOR_ID, (byte) 16);
     }
 
     public static AttributeSupplier.Builder createAttributes() {
-        return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 30.0);
+        return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 30.0D);
     }
 
     @Override
@@ -151,18 +162,19 @@
     public void readAdditionalSaveData(CompoundTag nbt) {
         super.readAdditionalSaveData(nbt);
         this.setAttachFace(Direction.from3DDataValue(nbt.getByte("AttachFace")));
-        this.entityData.set(DATA_PEEK_ID, nbt.getByte("Peek"));
+        this.entityData.set(Shulker.DATA_PEEK_ID, nbt.getByte("Peek"));
         if (nbt.contains("Color", 99)) {
-            this.entityData.set(DATA_COLOR_ID, nbt.getByte("Color"));
+            this.entityData.set(Shulker.DATA_COLOR_ID, nbt.getByte("Color"));
         }
+
     }
 
     @Override
     public void addAdditionalSaveData(CompoundTag nbt) {
         super.addAdditionalSaveData(nbt);
-        nbt.putByte("AttachFace", (byte)this.getAttachFace().get3DDataValue());
-        nbt.putByte("Peek", this.entityData.get(DATA_PEEK_ID));
-        nbt.putByte("Color", this.entityData.get(DATA_COLOR_ID));
+        nbt.putByte("AttachFace", (byte) this.getAttachFace().get3DDataValue());
+        nbt.putByte("Peek", (Byte) this.entityData.get(Shulker.DATA_PEEK_ID));
+        nbt.putByte("Color", (Byte) this.entityData.get(Shulker.DATA_COLOR_ID));
     }
 
     @Override
@@ -178,37 +190,42 @@
 
         if (this.level().isClientSide) {
             if (this.clientSideTeleportInterpolation > 0) {
-                this.clientSideTeleportInterpolation--;
+                --this.clientSideTeleportInterpolation;
             } else {
                 this.clientOldAttachPosition = null;
             }
         }
+
     }
 
     private void findNewAttachment() {
-        Direction direction = this.findAttachableSurface(this.blockPosition());
-        if (direction != null) {
-            this.setAttachFace(direction);
+        Direction enumdirection = this.findAttachableSurface(this.blockPosition());
+
+        if (enumdirection != null) {
+            this.setAttachFace(enumdirection);
         } else {
             this.teleportSomewhere();
         }
+
     }
 
     @Override
     protected AABB makeBoundingBox() {
-        float f = getPhysicalPeek(this.currentPeekAmount);
-        Direction direction = this.getAttachFace().getOpposite();
-        float g = this.getBbWidth() / 2.0F;
-        return getProgressAabb(this.getScale(), direction, f).move(this.getX() - (double)g, this.getY(), this.getZ() - (double)g);
+        float f = Shulker.getPhysicalPeek(this.currentPeekAmount);
+        Direction enumdirection = this.getAttachFace().getOpposite();
+        float f1 = this.getBbWidth() / 2.0F;
+
+        return Shulker.getProgressAabb(this.getScale(), enumdirection, f).move(this.getX() - (double) f1, this.getY(), this.getZ() - (double) f1);
     }
 
     private static float getPhysicalPeek(float openProgress) {
-        return 0.5F - Mth.sin((0.5F + openProgress) * (float) Math.PI) * 0.5F;
+        return 0.5F - Mth.sin((0.5F + openProgress) * 3.1415927F) * 0.5F;
     }
 
     private boolean updatePeekAmount() {
         this.currentPeekAmountO = this.currentPeekAmount;
-        float f = (float)this.getRawPeekAmount() * 0.01F;
+        float f = (float) this.getRawPeekAmount() * 0.01F;
+
         if (this.currentPeekAmount == f) {
             return false;
         } else {
@@ -224,45 +241,38 @@
 
     private void onPeekAmountChange() {
         this.reapplyPosition();
-        float f = getPhysicalPeek(this.currentPeekAmount);
-        float g = getPhysicalPeek(this.currentPeekAmountO);
-        Direction direction = this.getAttachFace().getOpposite();
-        float h = (f - g) * this.getScale();
-        if (!(h <= 0.0F)) {
-            for (Entity entity : this.level()
-                .getEntities(
-                    this,
-                    getProgressDeltaAabb(this.getScale(), direction, g, f).move(this.getX() - 0.5, this.getY(), this.getZ() - 0.5),
-                    EntitySelector.NO_SPECTATORS.and(entityx -> !entityx.isPassengerOfSameVehicle(this))
-                )) {
+        float f = Shulker.getPhysicalPeek(this.currentPeekAmount);
+        float f1 = Shulker.getPhysicalPeek(this.currentPeekAmountO);
+        Direction enumdirection = this.getAttachFace().getOpposite();
+        float f2 = (f - f1) * this.getScale();
+
+        if (f2 > 0.0F) {
+            List<Entity> list = this.level().getEntities((Entity) this, Shulker.getProgressDeltaAabb(this.getScale(), enumdirection, f1, f).move(this.getX() - 0.5D, this.getY(), this.getZ() - 0.5D), EntitySelector.NO_SPECTATORS.and((entity) -> {
+                return !entity.isPassengerOfSameVehicle(this);
+            }));
+            Iterator iterator = list.iterator();
+
+            while (iterator.hasNext()) {
+                Entity entity = (Entity) iterator.next();
+
                 if (!(entity instanceof Shulker) && !entity.noPhysics) {
-                    entity.move(
-                        MoverType.SHULKER,
-                        new Vec3(
-                            (double)(h * (float)direction.getStepX()), (double)(h * (float)direction.getStepY()), (double)(h * (float)direction.getStepZ())
-                        )
-                    );
+                    entity.move(MoverType.SHULKER, new Vec3((double) (f2 * (float) enumdirection.getStepX()), (double) (f2 * (float) enumdirection.getStepY()), (double) (f2 * (float) enumdirection.getStepZ())));
                 }
             }
+
         }
     }
 
     public static AABB getProgressAabb(float scale, Direction facing, float extraLength) {
-        return getProgressDeltaAabb(scale, facing, -1.0F, extraLength);
+        return Shulker.getProgressDeltaAabb(scale, facing, -1.0F, extraLength);
     }
 
     public static AABB getProgressDeltaAabb(float scale, Direction facing, float prevExtraLength, float extraLength) {
-        AABB aABB = new AABB(0.0, 0.0, 0.0, (double)scale, (double)scale, (double)scale);
-        double d = (double)Math.max(prevExtraLength, extraLength);
-        double e = (double)Math.min(prevExtraLength, extraLength);
-        return aABB.expandTowards(
-                (double)facing.getStepX() * d * (double)scale, (double)facing.getStepY() * d * (double)scale, (double)facing.getStepZ() * d * (double)scale
-            )
-            .contract(
-                (double)(-facing.getStepX()) * (1.0 + e) * (double)scale,
-                (double)(-facing.getStepY()) * (1.0 + e) * (double)scale,
-                (double)(-facing.getStepZ()) * (1.0 + e) * (double)scale
-            );
+        AABB axisalignedbb = new AABB(0.0D, 0.0D, 0.0D, (double) scale, (double) scale, (double) scale);
+        double d0 = (double) Math.max(prevExtraLength, extraLength);
+        double d1 = (double) Math.min(prevExtraLength, extraLength);
+
+        return axisalignedbb.expandTowards((double) facing.getStepX() * d0 * (double) scale, (double) facing.getStepY() * d0 * (double) scale, (double) facing.getStepZ() * d0 * (double) scale).contract((double) (-facing.getStepX()) * (1.0D + d1) * (double) scale, (double) (-facing.getStepY()) * (1.0D + d1) * (double) scale, (double) (-facing.getStepZ()) * (1.0D + d1) * (double) scale);
     }
 
     @Override
@@ -278,7 +288,13 @@
 
     @Override
     public void stopRiding() {
-        super.stopRiding();
+        // Paper start - Force entity dismount during teleportation
+        this.stopRiding(false);
+    }
+    @Override
+    public void stopRiding(boolean suppressCancellation) {
+        super.stopRiding(suppressCancellation);
+        // Paper end - Force entity dismount during teleportation
         if (this.level().isClientSide) {
             this.clientOldAttachPosition = this.blockPosition();
         }
@@ -303,6 +319,7 @@
         } else {
             super.move(movementType, movement);
         }
+
     }
 
     @Override
@@ -311,39 +328,46 @@
     }
 
     @Override
-    public void setDeltaMovement(Vec3 velocity) {
-    }
+    public void setDeltaMovement(Vec3 velocity) {}
 
     @Override
     public void setPos(double x, double y, double z) {
-        BlockPos blockPos = this.blockPosition();
+        BlockPos blockposition = this.blockPosition();
+
         if (this.isPassenger()) {
             super.setPos(x, y, z);
         } else {
-            super.setPos((double)Mth.floor(x) + 0.5, (double)Mth.floor(y + 0.5), (double)Mth.floor(z) + 0.5);
+            super.setPos((double) Mth.floor(x) + 0.5D, (double) Mth.floor(y + 0.5D), (double) Mth.floor(z) + 0.5D);
         }
 
         if (this.tickCount != 0) {
-            BlockPos blockPos2 = this.blockPosition();
-            if (!blockPos2.equals(blockPos)) {
-                this.entityData.set(DATA_PEEK_ID, (byte)0);
+            BlockPos blockposition1 = this.blockPosition();
+
+            if (!blockposition1.equals(blockposition)) {
+                this.entityData.set(Shulker.DATA_PEEK_ID, (byte) 0);
                 this.hasImpulse = true;
-                if (this.level().isClientSide && !this.isPassenger() && !blockPos2.equals(this.clientOldAttachPosition)) {
-                    this.clientOldAttachPosition = blockPos;
+                if (this.level().isClientSide && !this.isPassenger() && !blockposition1.equals(this.clientOldAttachPosition)) {
+                    this.clientOldAttachPosition = blockposition;
                     this.clientSideTeleportInterpolation = 6;
                     this.xOld = this.getX();
                     this.yOld = this.getY();
                     this.zOld = this.getZ();
                 }
             }
+
         }
     }
 
     @Nullable
     protected Direction findAttachableSurface(BlockPos pos) {
-        for (Direction direction : Direction.values()) {
-            if (this.canStayAt(pos, direction)) {
-                return direction;
+        Direction[] aenumdirection = Direction.values();
+        int i = aenumdirection.length;
+
+        for (int j = 0; j < i; ++j) {
+            Direction enumdirection = aenumdirection[j];
+
+            if (this.canStayAt(pos, enumdirection)) {
+                return enumdirection;
             }
         }
 
@@ -354,49 +378,56 @@
         if (this.isPositionBlocked(pos)) {
             return false;
         } else {
-            Direction direction2 = direction.getOpposite();
-            if (!this.level().loadedAndEntityCanStandOnFace(pos.relative(direction), this, direction2)) {
+            Direction enumdirection1 = direction.getOpposite();
+
+            if (!this.level().loadedAndEntityCanStandOnFace(pos.relative(direction), this, enumdirection1)) {
                 return false;
             } else {
-                AABB aABB = getProgressAabb(this.getScale(), direction2, 1.0F).move(pos).deflate(1.0E-6);
-                return this.level().noCollision(this, aABB);
+                AABB axisalignedbb = Shulker.getProgressAabb(this.getScale(), enumdirection1, 1.0F).move(pos).deflate(1.0E-6D);
+
+                return this.level().noCollision(this, axisalignedbb);
             }
         }
     }
 
     private boolean isPositionBlocked(BlockPos pos) {
-        BlockState blockState = this.level().getBlockState(pos);
-        if (blockState.isAir()) {
+        BlockState iblockdata = this.level().getBlockState(pos);
+
+        if (iblockdata.isAir()) {
             return false;
         } else {
-            boolean bl = blockState.is(Blocks.MOVING_PISTON) && pos.equals(this.blockPosition());
-            return !bl;
+            boolean flag = iblockdata.is(Blocks.MOVING_PISTON) && pos.equals(this.blockPosition());
+
+            return !flag;
         }
     }
 
     protected boolean teleportSomewhere() {
         if (!this.isNoAi() && this.isAlive()) {
-            BlockPos blockPos = this.blockPosition();
+            BlockPos blockposition = this.blockPosition();
 
-            for (int i = 0; i < 5; i++) {
-                BlockPos blockPos2 = blockPos.offset(
-                    Mth.randomBetweenInclusive(this.random, -8, 8),
-                    Mth.randomBetweenInclusive(this.random, -8, 8),
-                    Mth.randomBetweenInclusive(this.random, -8, 8)
-                );
-                if (blockPos2.getY() > this.level().getMinBuildHeight()
-                    && this.level().isEmptyBlock(blockPos2)
-                    && this.level().getWorldBorder().isWithinBounds(blockPos2)
-                    && this.level().noCollision(this, new AABB(blockPos2).deflate(1.0E-6))) {
-                    Direction direction = this.findAttachableSurface(blockPos2);
-                    if (direction != null) {
+            for (int i = 0; i < 5; ++i) {
+                BlockPos blockposition1 = blockposition.offset(Mth.randomBetweenInclusive(this.random, -8, 8), Mth.randomBetweenInclusive(this.random, -8, 8), Mth.randomBetweenInclusive(this.random, -8, 8));
+
+                if (blockposition1.getY() > this.level().getMinBuildHeight() && this.level().isEmptyBlock(blockposition1) && this.level().getWorldBorder().isWithinBounds(blockposition1) && this.level().noCollision(this, (new AABB(blockposition1)).deflate(1.0E-6D))) {
+                    Direction enumdirection = this.findAttachableSurface(blockposition1);
+
+                    if (enumdirection != null) {
+                        // CraftBukkit start
+                        EntityTeleportEvent teleportEvent = CraftEventFactory.callEntityTeleportEvent(this, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ());
+                        if (teleportEvent.isCancelled() || teleportEvent.getTo() == null) { // Paper
+                            return false;
+                        } else {
+                            blockposition1 = CraftLocation.toBlockPosition(teleportEvent.getTo());
+                        }
+                        // CraftBukkit end
                         this.unRide();
-                        this.setAttachFace(direction);
+                        this.setAttachFace(enumdirection);
                         this.playSound(SoundEvents.SHULKER_TELEPORT, 1.0F, 1.0F);
-                        this.setPos((double)blockPos2.getX() + 0.5, (double)blockPos2.getY(), (double)blockPos2.getZ() + 0.5);
-                        this.level().gameEvent(GameEvent.TELEPORT, blockPos, GameEvent.Context.of(this));
-                        this.entityData.set(DATA_PEEK_ID, (byte)0);
-                        this.setTarget(null);
+                        this.setPos((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY(), (double) blockposition1.getZ() + 0.5D);
+                        this.level().gameEvent((Holder) GameEvent.TELEPORT, blockposition, GameEvent.Context.of((Entity) this));
+                        this.entityData.set(Shulker.DATA_PEEK_ID, (byte) 0);
+                        this.setTarget((LivingEntity) null);
                         return true;
                     }
                 }
@@ -417,8 +448,10 @@
 
     @Override
     public boolean hurt(DamageSource source, float amount) {
+        Entity entity;
+
         if (this.isClosed()) {
-            Entity entity = source.getDirectEntity();
+            entity = source.getDirectEntity();
             if (entity instanceof AbstractArrow) {
                 return false;
             }
@@ -427,11 +460,11 @@
         if (!super.hurt(source, amount)) {
             return false;
         } else {
-            if ((double)this.getHealth() < (double)this.getMaxHealth() * 0.5 && this.random.nextInt(4) == 0) {
+            if ((double) this.getHealth() < (double) this.getMaxHealth() * 0.5D && this.random.nextInt(4) == 0) {
                 this.teleportSomewhere();
             } else if (source.is(DamageTypeTags.IS_PROJECTILE)) {
-                Entity entity2 = source.getDirectEntity();
-                if (entity2 != null && entity2.getType() == EntityType.SHULKER_BULLET) {
+                entity = source.getDirectEntity();
+                if (entity != null && entity.getType() == EntityType.SHULKER_BULLET) {
                     this.hitByShulkerBullet();
                 }
             }
@@ -445,18 +478,27 @@
     }
 
     private void hitByShulkerBullet() {
-        Vec3 vec3 = this.position();
-        AABB aABB = this.getBoundingBox();
+        Vec3 vec3d = this.position();
+        AABB axisalignedbb = this.getBoundingBox();
+
         if (!this.isClosed() && this.teleportSomewhere()) {
-            int i = this.level().getEntities(EntityType.SHULKER, aABB.inflate(8.0), Entity::isAlive).size();
-            float f = (float)(i - 1) / 5.0F;
-            if (!(this.level().random.nextFloat() < f)) {
-                Shulker shulker = EntityType.SHULKER.create(this.level());
-                if (shulker != null) {
-                    shulker.setVariant(this.getVariant());
-                    shulker.moveTo(vec3);
-                    this.level().addFreshEntity(shulker);
+            int i = this.level().getEntities((EntityTypeTest) EntityType.SHULKER, axisalignedbb.inflate(8.0D), Entity::isAlive).size();
+            float f = (float) (i - 1) / 5.0F;
+
+            if (this.level().random.nextFloat() >= f) {
+                Shulker entityshulker = (Shulker) EntityType.SHULKER.create(this.level());
+
+                if (entityshulker != null) {
+                    entityshulker.setVariant(this.getVariant());
+                    entityshulker.moveTo(vec3d);
+                    // Paper start - Shulker duplicate event
+                    if (!new io.papermc.paper.event.entity.ShulkerDuplicateEvent((org.bukkit.entity.Shulker) entityshulker.getBukkitEntity(), (org.bukkit.entity.Shulker) this.getBukkitEntity()).callEvent()) {
+                        return;
+                    }
+                    // Paper end - Shulker duplicate event
+                    this.level().addFreshEntity(entityshulker, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - the mysteries of life
                 }
+
             }
         }
     }
@@ -467,16 +509,16 @@
     }
 
     public Direction getAttachFace() {
-        return this.entityData.get(DATA_ATTACH_FACE_ID);
+        return (Direction) this.entityData.get(Shulker.DATA_ATTACH_FACE_ID);
     }
 
     public void setAttachFace(Direction face) {
-        this.entityData.set(DATA_ATTACH_FACE_ID, face);
+        this.entityData.set(Shulker.DATA_ATTACH_FACE_ID, face);
     }
 
     @Override
     public void onSyncedDataUpdated(EntityDataAccessor<?> data) {
-        if (DATA_ATTACH_FACE_ID.equals(data)) {
+        if (Shulker.DATA_ATTACH_FACE_ID.equals(data)) {
             this.setBoundingBox(this.makeBoundingBox());
         }
 
@@ -484,14 +526,14 @@
     }
 
     public int getRawPeekAmount() {
-        return this.entityData.get(DATA_PEEK_ID);
+        return (Byte) this.entityData.get(Shulker.DATA_PEEK_ID);
     }
 
     public void setRawPeekAmount(int peekAmount) {
         if (!this.level().isClientSide) {
-            this.getAttribute(Attributes.ARMOR).removeModifier(COVERED_ARMOR_MODIFIER_ID);
+            this.getAttribute(Attributes.ARMOR).removeModifier(Shulker.COVERED_ARMOR_MODIFIER_ID);
             if (peekAmount == 0) {
-                this.getAttribute(Attributes.ARMOR).addPermanentModifier(COVERED_ARMOR_MODIFIER);
+                this.getAttribute(Attributes.ARMOR).addPermanentModifier(Shulker.COVERED_ARMOR_MODIFIER);
                 this.playSound(SoundEvents.SHULKER_CLOSE, 1.0F, 1.0F);
                 this.gameEvent(GameEvent.CONTAINER_CLOSE);
             } else {
@@ -500,7 +542,7 @@
             }
         }
 
-        this.entityData.set(DATA_PEEK_ID, (byte)peekAmount);
+        this.entityData.set(Shulker.DATA_PEEK_ID, (byte) peekAmount);
     }
 
     public float getClientPeekAmount(float delta) {
@@ -525,18 +567,19 @@
     }
 
     @Override
-    public void push(Entity entity) {
-    }
+    public void push(Entity entity) {}
 
     public Optional<Vec3> getRenderPosition(float tickDelta) {
         if (this.clientOldAttachPosition != null && this.clientSideTeleportInterpolation > 0) {
-            double d = (double)((float)this.clientSideTeleportInterpolation - tickDelta) / 6.0;
-            d *= d;
-            BlockPos blockPos = this.blockPosition();
-            double e = (double)(blockPos.getX() - this.clientOldAttachPosition.getX()) * d;
-            double f = (double)(blockPos.getY() - this.clientOldAttachPosition.getY()) * d;
-            double g = (double)(blockPos.getZ() - this.clientOldAttachPosition.getZ()) * d;
-            return Optional.of(new Vec3(-e, -f, -g));
+            double d0 = (double) ((float) this.clientSideTeleportInterpolation - tickDelta) / 6.0D;
+
+            d0 *= d0;
+            BlockPos blockposition = this.blockPosition();
+            double d1 = (double) (blockposition.getX() - this.clientOldAttachPosition.getX()) * d0;
+            double d2 = (double) (blockposition.getY() - this.clientOldAttachPosition.getY()) * d0;
+            double d3 = (double) (blockposition.getZ() - this.clientOldAttachPosition.getZ()) * d0;
+
+            return Optional.of(new Vec3(-d1, -d2, -d3));
         } else {
             return Optional.empty();
         }
@@ -547,9 +590,10 @@
         return Math.min(scale, 3.0F);
     }
 
-    @Override
     public void setVariant(Optional<DyeColor> variant) {
-        this.entityData.set(DATA_COLOR_ID, variant.<Byte>map(color -> (byte)color.getId()).orElse((byte)16));
+        this.entityData.set(Shulker.DATA_COLOR_ID, (Byte) variant.map((enumcolor) -> {
+            return (byte) enumcolor.getId();
+        }).orElse((byte) 16));
     }
 
     @Override
@@ -559,11 +603,46 @@
 
     @Nullable
     public DyeColor getColor() {
-        byte b = this.entityData.get(DATA_COLOR_ID);
-        return b != 16 && b <= 15 ? DyeColor.byId(b) : null;
+        byte b0 = (Byte) this.entityData.get(Shulker.DATA_COLOR_ID);
+
+        return b0 != 16 && b0 <= 15 ? DyeColor.byId(b0) : null;
     }
 
-    class ShulkerAttackGoal extends Goal {
+    private class ShulkerLookControl extends LookControl {
+
+        public ShulkerLookControl(final Mob entity) {
+            super(entity);
+        }
+
+        @Override
+        protected void clampHeadRotationToBody() {}
+
+        @Override
+        protected Optional<Float> getYRotD() {
+            Direction enumdirection = Shulker.this.getAttachFace().getOpposite();
+            Vector3f vector3f = enumdirection.getRotation().transform(new Vector3f(Shulker.FORWARD));
+            Vec3i baseblockposition = enumdirection.getNormal();
+            Vector3f vector3f1 = new Vector3f((float) baseblockposition.getX(), (float) baseblockposition.getY(), (float) baseblockposition.getZ());
+
+            vector3f1.cross(vector3f);
+            double d0 = this.wantedX - this.mob.getX();
+            double d1 = this.wantedY - this.mob.getEyeY();
+            double d2 = this.wantedZ - this.mob.getZ();
+            Vector3f vector3f2 = new Vector3f((float) d0, (float) d1, (float) d2);
+            float f = vector3f1.dot(vector3f2);
+            float f1 = vector3f.dot(vector3f2);
+
+            return Math.abs(f) <= 1.0E-5F && Math.abs(f1) <= 1.0E-5F ? Optional.empty() : Optional.of((float) (Mth.atan2((double) (-f), (double) f1) * 57.2957763671875D));
+        }
+
+        @Override
+        protected Optional<Float> getXRotD() {
+            return Optional.of(0.0F);
+        }
+    }
+
+    private class ShulkerAttackGoal extends Goal {
+
         private int attackTime;
 
         public ShulkerAttackGoal() {
@@ -572,8 +651,9 @@
 
         @Override
         public boolean canUse() {
-            LivingEntity livingEntity = Shulker.this.getTarget();
-            return livingEntity != null && livingEntity.isAlive() && Shulker.this.level().getDifficulty() != Difficulty.PEACEFUL;
+            LivingEntity entityliving = Shulker.this.getTarget();
+
+            return entityliving != null && entityliving.isAlive() ? Shulker.this.level().getDifficulty() != Difficulty.PEACEFUL : false;
         }
 
         @Override
@@ -595,22 +675,21 @@
         @Override
         public void tick() {
             if (Shulker.this.level().getDifficulty() != Difficulty.PEACEFUL) {
-                this.attackTime--;
-                LivingEntity livingEntity = Shulker.this.getTarget();
-                if (livingEntity != null) {
-                    Shulker.this.getLookControl().setLookAt(livingEntity, 180.0F, 180.0F);
-                    double d = Shulker.this.distanceToSqr(livingEntity);
-                    if (d < 400.0) {
+                --this.attackTime;
+                LivingEntity entityliving = Shulker.this.getTarget();
+
+                if (entityliving != null) {
+                    Shulker.this.getLookControl().setLookAt(entityliving, 180.0F, 180.0F);
+                    double d0 = Shulker.this.distanceToSqr((Entity) entityliving);
+
+                    if (d0 < 400.0D) {
                         if (this.attackTime <= 0) {
                             this.attackTime = 20 + Shulker.this.random.nextInt(10) * 20 / 2;
-                            Shulker.this.level()
-                                .addFreshEntity(new ShulkerBullet(Shulker.this.level(), Shulker.this, livingEntity, Shulker.this.getAttachFace().getAxis()));
-                            Shulker.this.playSound(
-                                SoundEvents.SHULKER_SHOOT, 2.0F, (Shulker.this.random.nextFloat() - Shulker.this.random.nextFloat()) * 0.2F + 1.0F
-                            );
+                            Shulker.this.level().addFreshEntity(new ShulkerBullet(Shulker.this.level(), Shulker.this, entityliving, Shulker.this.getAttachFace().getAxis()));
+                            Shulker.this.playSound(SoundEvents.SHULKER_SHOOT, 2.0F, (Shulker.this.random.nextFloat() - Shulker.this.random.nextFloat()) * 0.2F + 1.0F);
                         }
                     } else {
-                        Shulker.this.setTarget(null);
+                        Shulker.this.setTarget((LivingEntity) null);
                     }
 
                     super.tick();
@@ -619,126 +698,89 @@
         }
     }
 
-    static class ShulkerBodyRotationControl extends BodyRotationControl {
-        public ShulkerBodyRotationControl(Mob entity) {
-            super(entity);
-        }
+    private class ShulkerPeekGoal extends Goal {
 
-        @Override
-        public void clientTick() {
-        }
-    }
+        private int peekTime;
 
-    static class ShulkerDefenseAttackGoal extends NearestAttackableTargetGoal<LivingEntity> {
-        public ShulkerDefenseAttackGoal(Shulker shulker) {
-            super(shulker, LivingEntity.class, 10, true, false, entity -> entity instanceof Enemy);
-        }
+        ShulkerPeekGoal() {}
 
         @Override
         public boolean canUse() {
-            return this.mob.getTeam() != null && super.canUse();
+            return Shulker.this.getTarget() == null && Shulker.this.random.nextInt(reducedTickDelay(40)) == 0 && Shulker.this.canStayAt(Shulker.this.blockPosition(), Shulker.this.getAttachFace());
         }
 
         @Override
-        protected AABB getTargetSearchArea(double distance) {
-            Direction direction = ((Shulker)this.mob).getAttachFace();
-            if (direction.getAxis() == Direction.Axis.X) {
-                return this.mob.getBoundingBox().inflate(4.0, distance, distance);
-            } else {
-                return direction.getAxis() == Direction.Axis.Z
-                    ? this.mob.getBoundingBox().inflate(distance, distance, 4.0)
-                    : this.mob.getBoundingBox().inflate(distance, 4.0, distance);
-            }
-        }
-    }
-
-    class ShulkerLookControl extends LookControl {
-        public ShulkerLookControl(final Mob entity) {
-            super(entity);
+        public boolean canContinueToUse() {
+            return Shulker.this.getTarget() == null && this.peekTime > 0;
         }
 
         @Override
-        protected void clampHeadRotationToBody() {
+        public void start() {
+            this.peekTime = this.adjustedTickDelay(20 * (1 + Shulker.this.random.nextInt(3)));
+            Shulker.this.setRawPeekAmount(30);
         }
 
         @Override
-        protected Optional<Float> getYRotD() {
-            Direction direction = Shulker.this.getAttachFace().getOpposite();
-            Vector3f vector3f = direction.getRotation().transform(new Vector3f(Shulker.FORWARD));
-            Vec3i vec3i = direction.getNormal();
-            Vector3f vector3f2 = new Vector3f((float)vec3i.getX(), (float)vec3i.getY(), (float)vec3i.getZ());
-            vector3f2.cross(vector3f);
-            double d = this.wantedX - this.mob.getX();
-            double e = this.wantedY - this.mob.getEyeY();
-            double f = this.wantedZ - this.mob.getZ();
-            Vector3f vector3f3 = new Vector3f((float)d, (float)e, (float)f);
-            float g = vector3f2.dot(vector3f3);
-            float h = vector3f.dot(vector3f3);
-            return !(Math.abs(g) > 1.0E-5F) && !(Math.abs(h) > 1.0E-5F)
-                ? Optional.empty()
-                : Optional.of((float)(Mth.atan2((double)(-g), (double)h) * 180.0F / (float)Math.PI));
+        public void stop() {
+            if (Shulker.this.getTarget() == null) {
+                Shulker.this.setRawPeekAmount(0);
+            }
+
         }
 
         @Override
-        protected Optional<Float> getXRotD() {
-            return Optional.of(0.0F);
+        public void tick() {
+            --this.peekTime;
         }
     }
 
-    class ShulkerNearestAttackGoal extends NearestAttackableTargetGoal<Player> {
-        public ShulkerNearestAttackGoal(final Shulker shulker) {
-            super(shulker, Player.class, true);
+    private class ShulkerNearestAttackGoal extends NearestAttackableTargetGoal<Player> {
+
+        public ShulkerNearestAttackGoal(final Shulker entityshulker) {
+            super(entityshulker, Player.class, true);
         }
 
         @Override
         public boolean canUse() {
-            return Shulker.this.level().getDifficulty() != Difficulty.PEACEFUL && super.canUse();
+            return Shulker.this.level().getDifficulty() == Difficulty.PEACEFUL ? false : super.canUse();
         }
 
         @Override
         protected AABB getTargetSearchArea(double distance) {
-            Direction direction = ((Shulker)this.mob).getAttachFace();
-            if (direction.getAxis() == Direction.Axis.X) {
-                return this.mob.getBoundingBox().inflate(4.0, distance, distance);
-            } else {
-                return direction.getAxis() == Direction.Axis.Z
-                    ? this.mob.getBoundingBox().inflate(distance, distance, 4.0)
-                    : this.mob.getBoundingBox().inflate(distance, 4.0, distance);
-            }
+            Direction enumdirection = ((Shulker) this.mob).getAttachFace();
+
+            return enumdirection.getAxis() == Direction.Axis.X ? this.mob.getBoundingBox().inflate(4.0D, distance, distance) : (enumdirection.getAxis() == Direction.Axis.Z ? this.mob.getBoundingBox().inflate(distance, distance, 4.0D) : this.mob.getBoundingBox().inflate(distance, 4.0D, distance));
         }
     }
 
-    class ShulkerPeekGoal extends Goal {
-        private int peekTime;
+    private static class ShulkerDefenseAttackGoal extends NearestAttackableTargetGoal<LivingEntity> {
 
-        @Override
-        public boolean canUse() {
-            return Shulker.this.getTarget() == null
-                && Shulker.this.random.nextInt(reducedTickDelay(40)) == 0
-                && Shulker.this.canStayAt(Shulker.this.blockPosition(), Shulker.this.getAttachFace());
+        public ShulkerDefenseAttackGoal(Shulker shulker) {
+            super(shulker, LivingEntity.class, 10, true, false, (entityliving) -> {
+                return entityliving instanceof Enemy;
+            });
         }
 
         @Override
-        public boolean canContinueToUse() {
-            return Shulker.this.getTarget() == null && this.peekTime > 0;
+        public boolean canUse() {
+            return this.mob.getTeam() == null ? false : super.canUse();
         }
 
         @Override
-        public void start() {
-            this.peekTime = this.adjustedTickDelay(20 * (1 + Shulker.this.random.nextInt(3)));
-            Shulker.this.setRawPeekAmount(30);
+        protected AABB getTargetSearchArea(double distance) {
+            Direction enumdirection = ((Shulker) this.mob).getAttachFace();
+
+            return enumdirection.getAxis() == Direction.Axis.X ? this.mob.getBoundingBox().inflate(4.0D, distance, distance) : (enumdirection.getAxis() == Direction.Axis.Z ? this.mob.getBoundingBox().inflate(distance, distance, 4.0D) : this.mob.getBoundingBox().inflate(distance, 4.0D, distance));
         }
+    }
 
-        @Override
-        public void stop() {
-            if (Shulker.this.getTarget() == null) {
-                Shulker.this.setRawPeekAmount(0);
-            }
+    private static class ShulkerBodyRotationControl extends BodyRotationControl {
+
+        public ShulkerBodyRotationControl(Mob entity) {
+            super(entity);
         }
 
         @Override
-        public void tick() {
-            this.peekTime--;
-        }
+        public void clientTick() {}
     }
 }
