--- a/net/minecraft/world/entity/monster/AbstractSkeleton.java
+++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java
@@ -10,6 +10,7 @@
 import net.minecraft.util.RandomSource;
 import net.minecraft.world.Difficulty;
 import net.minecraft.world.DifficultyInstance;
+import net.minecraft.world.entity.Entity;
 import net.minecraft.world.entity.EntityType;
 import net.minecraft.world.entity.EquipmentSlot;
 import net.minecraft.world.entity.LivingEntity;
@@ -43,10 +44,11 @@
 import net.minecraft.world.level.block.state.BlockState;
 
 public abstract class AbstractSkeleton extends Monster implements RangedAttackMob {
+
     private static final int HARD_ATTACK_INTERVAL = 20;
     private static final int NORMAL_ATTACK_INTERVAL = 40;
-    private final RangedBowAttackGoal<AbstractSkeleton> bowGoal = new RangedBowAttackGoal<>(this, 1.0, 20, 15.0F);
-    private final MeleeAttackGoal meleeGoal = new MeleeAttackGoal(this, 1.2, false) {
+    private final RangedBowAttackGoal<AbstractSkeleton> bowGoal = new RangedBowAttackGoal<>(this, 1.0D, 20, 15.0F);
+    private final MeleeAttackGoal meleeGoal = new MeleeAttackGoal(this, 1.2D, false) {
         @Override
         public void stop() {
             super.stop();
@@ -68,19 +70,19 @@
     @Override
     protected void registerGoals() {
         this.goalSelector.addGoal(2, new RestrictSunGoal(this));
-        this.goalSelector.addGoal(3, new FleeSunGoal(this, 1.0));
-        this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Wolf.class, 6.0F, 1.0, 1.2));
-        this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0));
+        this.goalSelector.addGoal(3, new FleeSunGoal(this, 1.0D));
+        this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Wolf.class, 6.0F, 1.0D, 1.2D));
+        this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0D));
         this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 8.0F));
         this.goalSelector.addGoal(6, new RandomLookAroundGoal(this));
-        this.targetSelector.addGoal(1, new HurtByTargetGoal(this));
+        this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0]));
         this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
         this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
         this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR));
     }
 
     public static AttributeSupplier.Builder createAttributes() {
-        return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.25);
+        return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.25D);
     }
 
     @Override
@@ -90,24 +92,32 @@
 
     abstract SoundEvent getStepSound();
 
+    // Paper start - shouldBurnInDay API
+    private boolean shouldBurnInDay = true;
+    public boolean shouldBurnInDay() { return shouldBurnInDay; }
+    public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; }
+    // Paper end - shouldBurnInDay API
+
     @Override
     public void aiStep() {
-        boolean bl = this.isSunBurnTick();
-        if (bl) {
-            ItemStack itemStack = this.getItemBySlot(EquipmentSlot.HEAD);
-            if (!itemStack.isEmpty()) {
-                if (itemStack.isDamageableItem()) {
-                    itemStack.setDamageValue(itemStack.getDamageValue() + this.random.nextInt(2));
-                    if (itemStack.getDamageValue() >= itemStack.getMaxDamage()) {
+        boolean flag = shouldBurnInDay && this.isSunBurnTick(); // Paper - shouldBurnInDay API
+
+        if (flag) {
+            ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
+
+            if (!itemstack.isEmpty()) {
+                if (itemstack.isDamageableItem()) {
+                    itemstack.setDamageValue(itemstack.getDamageValue() + this.random.nextInt(2));
+                    if (itemstack.getDamageValue() >= itemstack.getMaxDamage()) {
                         this.broadcastBreakEvent(EquipmentSlot.HEAD);
                         this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY);
                     }
                 }
 
-                bl = false;
+                flag = false;
             }
 
-            if (bl) {
+            if (flag) {
                 this.igniteForSeconds(8);
             }
         }
@@ -118,9 +128,12 @@
     @Override
     public void rideTick() {
         super.rideTick();
-        if (this.getControlledVehicle() instanceof PathfinderMob pathfinderMob) {
-            this.yBodyRot = pathfinderMob.yBodyRot;
+        Entity entity = this.getControlledVehicle();
+
+        if (entity instanceof PathfinderMob entitycreature) {
+            this.yBodyRot = entitycreature.yBodyRot;
         }
+
     }
 
     @Override
@@ -133,17 +146,19 @@
     @Override
     public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData) {
         entityData = super.finalizeSpawn(world, difficulty, spawnReason, entityData);
-        RandomSource randomSource = world.getRandom();
-        this.populateDefaultEquipmentSlots(randomSource, difficulty);
-        this.populateDefaultEquipmentEnchantments(randomSource, difficulty);
+        RandomSource randomsource = world.getRandom();
+
+        this.populateDefaultEquipmentSlots(randomsource, difficulty);
+        this.populateDefaultEquipmentEnchantments(randomsource, difficulty);
         this.reassessWeaponGoal();
-        this.setCanPickUpLoot(randomSource.nextFloat() < 0.55F * difficulty.getSpecialMultiplier());
+        this.setCanPickUpLoot(this.level().paperConfig().entities.behavior.mobsCanAlwaysPickUpLoot.skeletons || randomsource.nextFloat() < 0.55F * difficulty.getSpecialMultiplier()); // Paper - Add world settings for mobs picking up loot
         if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
-            LocalDate localDate = LocalDate.now();
-            int i = localDate.get(ChronoField.DAY_OF_MONTH);
-            int j = localDate.get(ChronoField.MONTH_OF_YEAR);
-            if (j == 10 && i == 31 && randomSource.nextFloat() < 0.25F) {
-                this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(randomSource.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN));
+            LocalDate localdate = LocalDate.now();
+            int i = localdate.get(ChronoField.DAY_OF_MONTH);
+            int j = localdate.get(ChronoField.MONTH_OF_YEAR);
+
+            if (j == 10 && i == 31 && randomsource.nextFloat() < 0.25F) {
+                this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(randomsource.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN));
                 this.armorDropChances[EquipmentSlot.HEAD.getIndex()] = 0.0F;
             }
         }
@@ -155,9 +170,11 @@
         if (this.level() != null && !this.level().isClientSide) {
             this.goalSelector.removeGoal(this.meleeGoal);
             this.goalSelector.removeGoal(this.bowGoal);
-            ItemStack itemStack = this.getItemInHand(ProjectileUtil.getWeaponHoldingHand(this, Items.BOW));
-            if (itemStack.is(Items.BOW)) {
+            ItemStack itemstack = this.getItemInHand(ProjectileUtil.getWeaponHoldingHand(this, Items.BOW));
+
+            if (itemstack.is(Items.BOW)) {
                 int i = this.getHardAttackInterval();
+
                 if (this.level().getDifficulty() != Difficulty.HARD) {
                     i = this.getAttackInterval();
                 }
@@ -167,6 +184,7 @@
             } else {
                 this.goalSelector.addGoal(4, this.meleeGoal);
             }
+
         }
     }
 
@@ -180,15 +198,27 @@
 
     @Override
     public void performRangedAttack(LivingEntity target, float pullProgress) {
-        ItemStack itemStack = this.getProjectile(this.getItemInHand(ProjectileUtil.getWeaponHoldingHand(this, Items.BOW)));
-        AbstractArrow abstractArrow = this.getArrow(itemStack, pullProgress);
-        double d = target.getX() - this.getX();
-        double e = target.getY(0.3333333333333333) - abstractArrow.getY();
-        double f = target.getZ() - this.getZ();
-        double g = Math.sqrt(d * d + f * f);
-        abstractArrow.shoot(d, e + g * 0.2F, f, 1.6F, (float)(14 - this.level().getDifficulty().getId() * 4));
+        ItemStack itemstack = this.getProjectile(this.getItemInHand(ProjectileUtil.getWeaponHoldingHand(this, Items.BOW)));
+        AbstractArrow entityarrow = this.getArrow(itemstack, pullProgress);
+        double d0 = target.getX() - this.getX();
+        double d1 = target.getY(0.3333333333333333D) - entityarrow.getY();
+        double d2 = target.getZ() - this.getZ();
+        double d3 = Math.sqrt(d0 * d0 + d2 * d2);
+
+        entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level().getDifficulty().getId() * 4));
+        // CraftBukkit start
+        org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); // Paper
+        if (event.isCancelled()) {
+            event.getProjectile().remove();
+            return;
+        }
+
+        if (event.getProjectile() == entityarrow.getBukkitEntity()) {
+            this.level().addFreshEntity(entityarrow);
+        }
+        // CraftBukkit end
         this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F));
-        this.level().addFreshEntity(abstractArrow);
+        // this.level().addFreshEntity(entityarrow); // CraftBukkit - moved up
     }
 
     protected AbstractArrow getArrow(ItemStack arrow, float damageModifier) {
@@ -204,14 +234,28 @@
     public void readAdditionalSaveData(CompoundTag nbt) {
         super.readAdditionalSaveData(nbt);
         this.reassessWeaponGoal();
+        // Paper start - shouldBurnInDay API
+        if (nbt.contains("Paper.ShouldBurnInDay")) {
+            this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay");
+        }
+        // Paper end - shouldBurnInDay API
     }
 
+    // Paper start - shouldBurnInDay API
     @Override
-    public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
-        super.setItemSlot(slot, stack);
+    public void addAdditionalSaveData(CompoundTag nbt) {
+        super.addAdditionalSaveData(nbt);
+        nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
+    }
+    // Paper end - shouldBurnInDay API
+
+    @Override
+    public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) { // Paper - Fix silent equipment change
+        super.setItemSlot(slot, stack, silent); // Paper - Fix silent equipment change
         if (!this.level().isClientSide) {
             this.reassessWeaponGoal();
         }
+
     }
 
     public boolean isShaking() {
