    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}