001package net.minecraft.entity.ai;
002
003import net.minecraft.entity.Entity;
004import net.minecraft.entity.passive.EntityVillager;
005import net.minecraft.util.MathHelper;
006import net.minecraft.village.Village;
007import net.minecraft.world.World;
008
009public 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 entity = this.worldObj.findNearestEntityWithinAABB(EntityVillager.class, this.villagerObj.boundingBox.expand(8.0D, 3.0D, 8.0D), this.villagerObj);
052
053                if (entity == null)
054                {
055                    return false;
056                }
057                else
058                {
059                    this.mate = (EntityVillager)entity;
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 i = (int)((double)((float)this.villageObj.getNumVillageDoors()) * 0.35D);
125            return this.villageObj.getNumVillagers() < i;
126        }
127    }
128
129    private void giveBirth()
130    {
131        EntityVillager entityvillager = this.villagerObj.func_90012_b(this.mate);
132        this.mate.setGrowingAge(6000);
133        this.villagerObj.setGrowingAge(6000);
134        entityvillager.setGrowingAge(-24000);
135        entityvillager.setLocationAndAngles(this.villagerObj.posX, this.villagerObj.posY, this.villagerObj.posZ, 0.0F, 0.0F);
136        this.worldObj.spawnEntityInWorld(entityvillager);
137        this.worldObj.setEntityState(entityvillager, (byte)12);
138    }
139}