--- a/net/minecraft/world/entity/animal/Bee.java
+++ b/net/minecraft/world/entity/animal/Bee.java
@@ -146,10 +_,26 @@
     Bee.BeeGoToHiveGoal goToHiveGoal;
     private Bee.BeeGoToKnownFlowerGoal goToKnownFlowerGoal;
     private int underWaterTicks;
+    public net.kyori.adventure.util.TriState rollingOverride = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Rolling override
 
     public Bee(EntityType<? extends Bee> entityType, Level level) {
         super(entityType, level);
-        this.moveControl = new FlyingMoveControl(this, 20, true);
+        // Paper start - Fix MC-167279
+        class BeeFlyingMoveControl extends FlyingMoveControl {
+            public BeeFlyingMoveControl(final Mob entity, final int maxPitchChange, final boolean noGravity) {
+                super(entity, maxPitchChange, noGravity);
+            }
+
+            @Override
+            public void tick() {
+                if (this.mob.getY() <= Bee.this.level().getMinY()) {
+                    this.mob.setNoGravity(false);
+                }
+                super.tick();
+            }
+        }
+        this.moveControl = new BeeFlyingMoveControl(this, 20, true);
+        // Paper end - Fix MC-167279
         this.lookControl = new Bee.BeeLookControl(this);
         this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F);
         this.setPathfindingMalus(PathType.WATER, -1.0F);
@@ -196,9 +_,18 @@
 
     @Override
     protected void addAdditionalSaveData(ValueOutput output) {
+        // CraftBukkit start - selectively save data
+        this.addAdditionalSaveData(output, true);
+    }
+
+    @Override
+    public void addAdditionalSaveData(ValueOutput output, boolean saveAll) {
+        // CraftBukkit end
         super.addAdditionalSaveData(output);
+        if (saveAll) { // Paper
         output.storeNullable("hive_pos", BlockPos.CODEC, this.hivePos);
         output.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos);
+        } // Paper
         output.putBoolean("HasNectar", this.hasNectar());
         output.putBoolean("HasStung", this.hasStung());
         output.putInt("TicksSincePollination", this.ticksWithoutNectarSinceExitingHive);
@@ -236,7 +_,7 @@
                 }
 
                 if (i > 0) {
-                    livingEntity.addEffect(new MobEffectInstance(MobEffects.POISON, i * 20, 0), this);
+                    livingEntity.addEffect(new MobEffectInstance(MobEffects.POISON, i * 20, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
                 }
             }
 
@@ -491,7 +_,11 @@
         if (this.hivePos == null) {
             return null;
         } else {
-            return this.isTooFarAway(this.hivePos) ? null : this.level().getBlockEntity(this.hivePos, BlockEntityType.BEEHIVE).orElse(null);
+            // Paper start - move over logic to accommodate isTooFarAway with chunk load check
+            return this.isTooFarAway(this.hivePos) || this.level().getChunkIfLoadedImmediately(this.hivePos.getX() >> 4, this.hivePos.getZ() >> 4) == null
+                ? null
+                : this.level().getBlockEntity(this.hivePos, BlockEntityType.BEEHIVE).orElse(null);
+            // Paper end
         }
     }
 
@@ -524,6 +_,7 @@
     }
 
     public void setRolling(boolean isRolling) {
+        isRolling = this.rollingOverride.toBooleanOrElse(isRolling); // Paper - Rolling override
         this.setFlag(2, isRolling);
     }
 
@@ -580,7 +_,7 @@
             if (beeInteractionEffect != null) {
                 this.usePlayerItem(player, hand, itemInHand);
                 if (!this.level().isClientSide) {
-                    this.addEffect(beeInteractionEffect);
+                    this.addEffect(beeInteractionEffect, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); // Paper - Add missing effect cause
                 }
 
                 return InteractionResult.SUCCESS;
@@ -649,8 +_,9 @@
         if (this.isInvulnerableTo(level, damageSource)) {
             return false;
         } else {
+            if (!super.hurtServer(level, damageSource, amount)) return false; // CraftBukkit - Only stop pollinating if entity was damaged
             this.beePollinateGoal.stopPollinating();
-            return super.hurtServer(level, damageSource, amount);
+            return true; // CraftBukkit - Only stop pollinating if entity was damaged
         }
     }
 
@@ -981,7 +_,7 @@
                             }
                         }
 
-                        if (blockState1 != null) {
+                        if (blockState1 != null && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(Bee.this, blockPos, blockState1)) { // CraftBukkit
                             Bee.this.level().levelEvent(2011, blockPos, 15);
                             Bee.this.level().setBlockAndUpdate(blockPos, blockState1);
                             Bee.this.incrementNumCropsGrownSincePollination();
@@ -1005,7 +_,7 @@
         @Override
         protected void alertOther(Mob mob, LivingEntity target) {
             if (mob instanceof Bee && this.mob.hasLineOfSight(target)) {
-                mob.setTarget(target);
+                mob.setTarget(target, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY); // CraftBukkit - reason
             }
         }
     }
@@ -1163,7 +_,7 @@
                     Bee.this.dropFlower();
                     this.pollinating = false;
                     Bee.this.remainingCooldownBeforeLocatingNewFlower = 200;
-                } else {
+                } else if (Bee.this.savedFlowerPos != null) { // Paper - add null check since API can manipulate this
                     Vec3 vec3 = Vec3.atBottomCenterOf(Bee.this.savedFlowerPos).add(0.0, 0.6F, 0.0);
                     if (vec3.distanceTo(Bee.this.position()) > 1.0) {
                         this.hoverPos = vec3;
