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 }