--- a/net/minecraft/world/entity/ambient/Bat.java
+++ b/net/minecraft/world/entity/ambient/Bat.java
@@ -40,7 +_,7 @@
     public final AnimationState flyAnimationState = new AnimationState();
     public final AnimationState restAnimationState = new AnimationState();
     @Nullable
-    private BlockPos targetPosition;
+    public BlockPos targetPosition;
 
     public Bat(EntityType<? extends Bat> entityType, Level level) {
         super(entityType, level);
@@ -61,7 +_,7 @@
     }
 
     @Override
-    protected float getSoundVolume() {
+    public float getSoundVolume() {
         return 0.1F;
     }
 
@@ -77,17 +_,17 @@
     }
 
     @Override
-    protected SoundEvent getHurtSound(DamageSource damageSource) {
+    public SoundEvent getHurtSound(DamageSource damageSource) {
         return SoundEvents.BAT_HURT;
     }
 
     @Override
-    protected SoundEvent getDeathSound() {
+    public SoundEvent getDeathSound() {
         return SoundEvents.BAT_DEATH;
     }
 
     @Override
-    public boolean isPushable() {
+    public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
         return false;
     }
 
@@ -141,13 +_,13 @@
                     this.yHeadRot = this.random.nextInt(360);
                 }
 
-                if (level.getNearestPlayer(BAT_RESTING_TARGETING, this) != null) {
+                if (level.getNearestPlayer(BAT_RESTING_TARGETING, this) != null && org.bukkit.craftbukkit.event.CraftEventFactory.handleBatToggleSleepEvent(this, true)) { // CraftBukkit - Call BatToggleSleepEvent
                     this.setResting(false);
                     if (!isSilent) {
                         level.levelEvent(null, 1025, blockPos, 0);
                     }
                 }
-            } else {
+            } else if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBatToggleSleepEvent(this, true)) { // CraftBukkit - Call BatToggleSleepEvent
                 this.setResting(false);
                 if (!isSilent) {
                     level.levelEvent(null, 1025, blockPos, 0);
@@ -180,7 +_,7 @@
             float f1 = Mth.wrapDegrees(f - this.getYRot());
             this.zza = 0.5F;
             this.setYRot(this.getYRot() + f1);
-            if (this.random.nextInt(100) == 0 && level.getBlockState(blockPos1).isRedstoneConductor(level, blockPos1)) {
+            if (this.random.nextInt(100) == 0 && level.getBlockState(blockPos1).isRedstoneConductor(level, blockPos1) && org.bukkit.craftbukkit.event.CraftEventFactory.handleBatToggleSleepEvent(this, false)) { // CraftBukkit - Call BatToggleSleepEvent
                 this.setResting(true);
             }
         }
@@ -205,7 +_,7 @@
         if (this.isInvulnerableTo(level, damageSource)) {
             return false;
         } else {
-            if (this.isResting()) {
+            if (this.isResting() && org.bukkit.craftbukkit.event.CraftEventFactory.handleBatToggleSleepEvent(this, true)) { // CraftBukkit - Call BatToggleSleepEvent
                 this.setResting(false);
             }
 
