--- a/net/minecraft/world/entity/AgeableMob.java
+++ b/net/minecraft/world/entity/AgeableMob.java
@@ -13,32 +13,58 @@
 import net.minecraft.world.level.ServerLevelAccessor;
 
 public abstract class AgeableMob extends PathfinderMob {
+
     private static final EntityDataAccessor<Boolean> DATA_BABY_ID = SynchedEntityData.defineId(AgeableMob.class, EntityDataSerializers.BOOLEAN);
     public static final int BABY_START_AGE = -24000;
     private static final int FORCED_AGE_PARTICLE_TICKS = 40;
     protected int age;
     protected int forcedAge;
     protected int forcedAgeTimer;
+    public boolean ageLocked; // CraftBukkit
 
     protected AgeableMob(EntityType<? extends AgeableMob> type, Level world) {
         super(type, world);
     }
 
+    // Spigot start
+    @Override
+    public void inactiveTick()
+    {
+        super.inactiveTick();
+        if ( this.level().isClientSide || this.ageLocked )
+        { // CraftBukkit
+            this.refreshDimensions();
+        } else
+        {
+            int i = this.getAge();
+
+            if ( i < 0 )
+            {
+                ++i;
+                this.setAge( i );
+            } else if ( i > 0 )
+            {
+                --i;
+                this.setAge( i );
+            }
+        }
+    }
+    // Spigot end
+
     @Override
     public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData) {
         if (entityData == null) {
             entityData = new AgeableMob.AgeableMobGroupData(true);
         }
 
-        AgeableMob.AgeableMobGroupData ageableMobGroupData = (AgeableMob.AgeableMobGroupData)entityData;
-        if (ageableMobGroupData.isShouldSpawnBaby()
-            && ageableMobGroupData.getGroupSize() > 0
-            && world.getRandom().nextFloat() <= ageableMobGroupData.getBabySpawnChance()) {
+        AgeableMob.AgeableMobGroupData entityageable_a = (AgeableMob.AgeableMobGroupData) entityData;
+
+        if (entityageable_a.isShouldSpawnBaby() && entityageable_a.getGroupSize() > 0 && world.getRandom().nextFloat() <= entityageable_a.getBabySpawnChance()) {
             this.setAge(-24000);
         }
 
-        ageableMobGroupData.increaseGroupSizeByOne();
-        return super.finalizeSpawn(world, difficulty, spawnReason, entityData);
+        entityageable_a.increaseGroupSizeByOne();
+        return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData);
     }
 
     @Nullable
@@ -47,7 +73,7 @@
     @Override
     protected void defineSynchedData(SynchedEntityData.Builder builder) {
         super.defineSynchedData(builder);
-        builder.define(DATA_BABY_ID, false);
+        builder.define(AgeableMob.DATA_BABY_ID, false);
     }
 
     public boolean canBreed() {
@@ -55,24 +81,24 @@
     }
 
     public int getAge() {
-        if (this.level().isClientSide) {
-            return this.entityData.get(DATA_BABY_ID) ? -1 : 1;
-        } else {
-            return this.age;
-        }
+        return this.level().isClientSide ? ((Boolean) this.entityData.get(AgeableMob.DATA_BABY_ID) ? -1 : 1) : this.age;
     }
 
     public void ageUp(int age, boolean overGrow) {
-        int i = this.getAge();
-        i += age * 20;
-        if (i > 0) {
-            i = 0;
+        if (this.ageLocked) return; // Paper - Honor ageLock
+        int j = this.getAge();
+        int k = j;
+
+        j += age * 20;
+        if (j > 0) {
+            j = 0;
         }
 
-        int k = i - i;
-        this.setAge(i);
+        int l = j - k;
+
+        this.setAge(j);
         if (overGrow) {
-            this.forcedAge += k;
+            this.forcedAge += l;
             if (this.forcedAgeTimer == 0) {
                 this.forcedAgeTimer = 40;
             }
@@ -81,6 +107,7 @@
         if (this.getAge() == 0) {
             this.setAge(this.forcedAge);
         }
+
     }
 
     public void ageUp(int age) {
@@ -88,12 +115,14 @@
     }
 
     public void setAge(int age) {
-        int i = this.getAge();
+        int j = this.getAge();
+
         this.age = age;
-        if (i < 0 && age >= 0 || i >= 0 && age < 0) {
-            this.entityData.set(DATA_BABY_ID, age < 0);
+        if (j < 0 && age >= 0 || j >= 0 && age < 0) {
+            this.entityData.set(AgeableMob.DATA_BABY_ID, age < 0);
             this.ageBoundaryReached();
         }
+
     }
 
     @Override
@@ -101,6 +130,7 @@
         super.addAdditionalSaveData(nbt);
         nbt.putInt("Age", this.getAge());
         nbt.putInt("ForcedAge", this.forcedAge);
+        nbt.putBoolean("AgeLocked", this.ageLocked); // CraftBukkit
     }
 
     @Override
@@ -108,11 +138,12 @@
         super.readAdditionalSaveData(nbt);
         this.setAge(nbt.getInt("Age"));
         this.forcedAge = nbt.getInt("ForcedAge");
+        this.ageLocked = nbt.getBoolean("AgeLocked"); // CraftBukkit
     }
 
     @Override
     public void onSyncedDataUpdated(EntityDataAccessor<?> data) {
-        if (DATA_BABY_ID.equals(data)) {
+        if (AgeableMob.DATA_BABY_ID.equals(data)) {
             this.refreshDimensions();
         }
 
@@ -122,28 +153,41 @@
     @Override
     public void aiStep() {
         super.aiStep();
-        if (this.level().isClientSide) {
+        if (this.level().isClientSide || this.ageLocked) { // CraftBukkit
             if (this.forcedAgeTimer > 0) {
                 if (this.forcedAgeTimer % 4 == 0) {
-                    this.level().addParticle(ParticleTypes.HAPPY_VILLAGER, this.getRandomX(1.0), this.getRandomY() + 0.5, this.getRandomZ(1.0), 0.0, 0.0, 0.0);
+                    this.level().addParticle(ParticleTypes.HAPPY_VILLAGER, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), 0.0D, 0.0D, 0.0D);
                 }
 
-                this.forcedAgeTimer--;
+                --this.forcedAgeTimer;
             }
         } else if (this.isAlive()) {
             int i = this.getAge();
+
             if (i < 0) {
-                this.setAge(++i);
+                ++i;
+                this.setAge(i);
             } else if (i > 0) {
-                this.setAge(--i);
+                --i;
+                this.setAge(i);
             }
         }
+
     }
 
     protected void ageBoundaryReached() {
-        if (!this.isBaby() && this.isPassenger() && this.getVehicle() instanceof Boat boat && !boat.hasEnoughSpaceFor(this)) {
-            this.stopRiding();
+        if (!this.isBaby() && this.isPassenger()) {
+            Entity entity = this.getVehicle();
+
+            if (entity instanceof Boat) {
+                Boat entityboat = (Boat) entity;
+
+                if (!entityboat.hasEnoughSpaceFor(this)) {
+                    this.stopRiding();
+                }
+            }
         }
+
     }
 
     @Override
@@ -157,10 +201,11 @@
     }
 
     public static int getSpeedUpSecondsWhenFeeding(int breedingAge) {
-        return (int)((float)(breedingAge / 20) * 0.1F);
+        return (int) ((float) (breedingAge / 20) * 0.1F);
     }
 
     public static class AgeableMobGroupData implements SpawnGroupData {
+
         private int groupSize;
         private final boolean shouldSpawnBaby;
         private final float babySpawnChance;
@@ -183,7 +228,7 @@
         }
 
         public void increaseGroupSizeByOne() {
-            this.groupSize++;
+            ++this.groupSize;
         }
 
         public boolean isShouldSpawnBaby() {
