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 }