    001    package net.minecraft.src;
    002
    003    import java.util.Iterator;
    004    import java.util.List;
    005    import java.util.Random;
    006
    007    public class EntityAIMate extends EntityAIBase
    008    {
    009        private EntityAnimal theAnimal;
    010        World theWorld;
    011        private EntityAnimal targetMate;
    012
    013        /**
    014         * Delay preventing a baby from spawning immediately when two mate-able animals find each other.
    015         */
    016        int spawnBabyDelay = 0;
    017
    018        /** The speed the creature moves at during mating behavior. */
    019        float moveSpeed;
    020
    021        public EntityAIMate(EntityAnimal par1EntityAnimal, float par2)
    022        {
    023            this.theAnimal = par1EntityAnimal;
    024            this.theWorld = par1EntityAnimal.worldObj;
    025            this.moveSpeed = par2;
    026            this.setMutexBits(3);
    027        }
    028
    029        /**
    030         * Returns whether the EntityAIBase should begin execution.
    031         */
    032        public boolean shouldExecute()
    033        {
    034            if (!this.theAnimal.isInLove())
    035            {
    036                return false;
    037            }
    038            else
    039            {
    040                this.targetMate = this.getNearbyMate();
    041                return this.targetMate != null;
    042            }
    043        }
    044
    045        /**
    046         * Returns whether an in-progress EntityAIBase should continue executing
    047         */
    048        public boolean continueExecuting()
    049        {
    050            return this.targetMate.isEntityAlive() && this.targetMate.isInLove() && this.spawnBabyDelay < 60;
    051        }
    052
    053        /**
    054         * Resets the task
    055         */
    056        public void resetTask()
    057        {
    058            this.targetMate = null;
    059            this.spawnBabyDelay = 0;
    060        }
    061
    062        /**
    063         * Updates the task
    064         */
    065        public void updateTask()
    066        {
    067            this.theAnimal.getLookHelper().setLookPositionWithEntity(this.targetMate, 10.0F, (float)this.theAnimal.getVerticalFaceSpeed());
    068            this.theAnimal.getNavigator().tryMoveToEntityLiving(this.targetMate, this.moveSpeed);
    069            ++this.spawnBabyDelay;
    070
    071            if (this.spawnBabyDelay == 60)
    072            {
    073                this.spawnBaby();
    074            }
    075        }
    076
    077        /**
    078         * Loops through nearby animals and finds another animal of the same type that can be mated with. Returns the first
    079         * valid mate found.
    080         */
    081        private EntityAnimal getNearbyMate()
    082        {
    083            float var1 = 8.0F;
    084            List var2 = this.theWorld.getEntitiesWithinAABB(this.theAnimal.getClass(), this.theAnimal.boundingBox.expand((double)var1, (double)var1, (double)var1));
    085            Iterator var3 = var2.iterator();
    086            EntityAnimal var4;
    087
    088            do
    089            {
    090                if (!var3.hasNext())
    091                {
    092                    return null;
    093                }
    094
    095                var4 = (EntityAnimal)var3.next();
    096            }
    097            while (!this.theAnimal.canMateWith(var4));
    098
    099            return var4;
    100        }
    101
    102        /**
    103         * Spawns a baby animal of the same type.
    104         */
    105        private void spawnBaby()
    106        {
    107            EntityAgeable var1 = this.theAnimal.func_90011_a(this.targetMate);
    108
    109            if (var1 != null)
    110            {
    111                this.theAnimal.setGrowingAge(6000);
    112                this.targetMate.setGrowingAge(6000);
    113                this.theAnimal.resetInLove();
    114                this.targetMate.resetInLove();
    115                var1.setGrowingAge(-24000);
    116                var1.setLocationAndAngles(this.theAnimal.posX, this.theAnimal.posY, this.theAnimal.posZ, 0.0F, 0.0F);
    117                this.theWorld.spawnEntityInWorld(var1);
    118                Random var2 = this.theAnimal.getRNG();
    119
    120                for (int var3 = 0; var3 < 7; ++var3)
    121                {
    122                    double var4 = var2.nextGaussian() * 0.02D;
    123                    double var6 = var2.nextGaussian() * 0.02D;
    124                    double var8 = var2.nextGaussian() * 0.02D;
    125                    this.theWorld.spawnParticle("heart", this.theAnimal.posX + (double)(var2.nextFloat() * this.theAnimal.width * 2.0F) - (double)this.theAnimal.width, this.theAnimal.posY + 0.5D + (double)(var2.nextFloat() * this.theAnimal.height), this.theAnimal.posZ + (double)(var2.nextFloat() * this.theAnimal.width * 2.0F) - (double)this.theAnimal.width, var4, var6, var8);
    126                }
    127
    128                this.theWorld.spawnEntityInWorld(new EntityXPOrb(this.theWorld, this.theAnimal.posX, this.theAnimal.posY, this.theAnimal.posZ, var2.nextInt(4) + 1));
    129            }
    130        }
    131    }