001    package net.minecraft.entity.ai;
002    
003    import net.minecraft.entity.Entity;
004    import net.minecraft.entity.passive.EntityVillager;
005    import net.minecraft.util.MathHelper;
006    import net.minecraft.village.Village;
007    import net.minecraft.world.World;
008    
009    public class EntityAIVillagerMate extends EntityAIBase
010    {
011        private EntityVillager villagerObj;
012        private EntityVillager mate;
013        private World worldObj;
014        private int matingTimeout = 0;
015        Village villageObj;
016    
017        public EntityAIVillagerMate(EntityVillager par1EntityVillager)
018        {
019            this.villagerObj = par1EntityVillager;
020            this.worldObj = par1EntityVillager.worldObj;
021            this.setMutexBits(3);
022        }
023    
024        /**
025         * Returns whether the EntityAIBase should begin execution.
026         */
027        public boolean shouldExecute()
028        {
029            if (this.villagerObj.getGrowingAge() != 0)
030            {
031                return false;
032            }
033            else if (this.villagerObj.getRNG().nextInt(500) != 0)
034            {
035                return false;
036            }
037            else
038            {
039                this.villageObj = this.worldObj.villageCollectionObj.findNearestVillage(MathHelper.floor_double(this.villagerObj.posX), MathHelper.floor_double(this.villagerObj.posY), MathHelper.floor_double(this.villagerObj.posZ), 0);
040    
041                if (this.villageObj == null)
042                {
043                    return false;
044                }
045                else if (!this.checkSufficientDoorsPresentForNewVillager())
046                {
047                    return false;
048                }
049                else
050                {
051                    Entity var1 = this.worldObj.findNearestEntityWithinAABB(EntityVillager.class, this.villagerObj.boundingBox.expand(8.0D, 3.0D, 8.0D), this.villagerObj);
052    
053                    if (var1 == null)
054                    {
055                        return false;
056                    }
057                    else
058                    {
059                        this.mate = (EntityVillager)var1;
060                        return this.mate.getGrowingAge() == 0;
061                    }
062                }
063            }
064        }
065    
066        /**
067         * Execute a one shot task or start executing a continuous task
068         */
069        public void startExecuting()
070        {
071            this.matingTimeout = 300;
072            this.villagerObj.setMating(true);
073        }
074    
075        /**
076         * Resets the task
077         */
078        public void resetTask()
079        {
080            this.villageObj = null;
081            this.mate = null;
082            this.villagerObj.setMating(false);
083        }
084    
085        /**
086         * Returns whether an in-progress EntityAIBase should continue executing
087         */
088        public boolean continueExecuting()
089        {
090            return this.matingTimeout >= 0 && this.checkSufficientDoorsPresentForNewVillager() && this.villagerObj.getGrowingAge() == 0;
091        }
092    
093        /**
094         * Updates the task
095         */
096        public void updateTask()
097        {
098            --this.matingTimeout;
099            this.villagerObj.getLookHelper().setLookPositionWithEntity(this.mate, 10.0F, 30.0F);
100    
101            if (this.villagerObj.getDistanceSqToEntity(this.mate) > 2.25D)
102            {
103                this.villagerObj.getNavigator().tryMoveToEntityLiving(this.mate, 0.25F);
104            }
105            else if (this.matingTimeout == 0 && this.mate.isMating())
106            {
107                this.giveBirth();
108            }
109    
110            if (this.villagerObj.getRNG().nextInt(35) == 0)
111            {
112                this.worldObj.setEntityState(this.villagerObj, (byte)12);
113            }
114        }
115    
116        private boolean checkSufficientDoorsPresentForNewVillager()
117        {
118            if (!this.villageObj.isMatingSeason())
119            {
120                return false;
121            }
122            else
123            {
124                int var1 = (int)((double)((float)this.villageObj.getNumVillageDoors()) * 0.35D);
125                return this.villageObj.getNumVillagers() < var1;
126            }
127        }
128    
129        private void giveBirth()
130        {
131            EntityVillager var1 = this.villagerObj.func_90012_b(this.mate);
132            this.mate.setGrowingAge(6000);
133            this.villagerObj.setGrowingAge(6000);
134            var1.setGrowingAge(-24000);
135            var1.setLocationAndAngles(this.villagerObj.posX, this.villagerObj.posY, this.villagerObj.posZ, 0.0F, 0.0F);
136            this.worldObj.spawnEntityInWorld(var1);
137            this.worldObj.setEntityState(var1, (byte)12);
138        }
139    }