001 package net.minecraft.src; 002 003 import java.util.Iterator; 004 import java.util.List; 005 import java.util.Random; 006 007 public class EntityAIMate extends EntityAIBase 008 { 009 private EntityAnimal theAnimal; 010 World theWorld; 011 private EntityAnimal targetMate; 012 013 /** 014 * Delay preventing a baby from spawning immediately when two mate-able animals find each other. 015 */ 016 int spawnBabyDelay = 0; 017 018 /** The speed the creature moves at during mating behavior. */ 019 float moveSpeed; 020 021 public EntityAIMate(EntityAnimal par1EntityAnimal, float par2) 022 { 023 this.theAnimal = par1EntityAnimal; 024 this.theWorld = par1EntityAnimal.worldObj; 025 this.moveSpeed = par2; 026 this.setMutexBits(3); 027 } 028 029 /** 030 * Returns whether the EntityAIBase should begin execution. 031 */ 032 public boolean shouldExecute() 033 { 034 if (!this.theAnimal.isInLove()) 035 { 036 return false; 037 } 038 else 039 { 040 this.targetMate = this.getNearbyMate(); 041 return this.targetMate != null; 042 } 043 } 044 045 /** 046 * Returns whether an in-progress EntityAIBase should continue executing 047 */ 048 public boolean continueExecuting() 049 { 050 return this.targetMate.isEntityAlive() && this.targetMate.isInLove() && this.spawnBabyDelay < 60; 051 } 052 053 /** 054 * Resets the task 055 */ 056 public void resetTask() 057 { 058 this.targetMate = null; 059 this.spawnBabyDelay = 0; 060 } 061 062 /** 063 * Updates the task 064 */ 065 public void updateTask() 066 { 067 this.theAnimal.getLookHelper().setLookPositionWithEntity(this.targetMate, 10.0F, (float)this.theAnimal.getVerticalFaceSpeed()); 068 this.theAnimal.getNavigator().tryMoveToEntityLiving(this.targetMate, this.moveSpeed); 069 ++this.spawnBabyDelay; 070 071 if (this.spawnBabyDelay == 60) 072 { 073 this.spawnBaby(); 074 } 075 } 076 077 /** 078 * Loops through nearby animals and finds another animal of the same type that can be mated with. Returns the first 079 * valid mate found. 080 */ 081 private EntityAnimal getNearbyMate() 082 { 083 float var1 = 8.0F; 084 List var2 = this.theWorld.getEntitiesWithinAABB(this.theAnimal.getClass(), this.theAnimal.boundingBox.expand((double)var1, (double)var1, (double)var1)); 085 Iterator var3 = var2.iterator(); 086 EntityAnimal var4; 087 088 do 089 { 090 if (!var3.hasNext()) 091 { 092 return null; 093 } 094 095 var4 = (EntityAnimal)var3.next(); 096 } 097 while (!this.theAnimal.canMateWith(var4)); 098 099 return var4; 100 } 101 102 /** 103 * Spawns a baby animal of the same type. 104 */ 105 private void spawnBaby() 106 { 107 EntityAnimal var1 = this.theAnimal.spawnBabyAnimal(this.targetMate); 108 109 if (var1 != null) 110 { 111 this.theAnimal.setGrowingAge(6000); 112 this.targetMate.setGrowingAge(6000); 113 this.theAnimal.resetInLove(); 114 this.targetMate.resetInLove(); 115 var1.setGrowingAge(-24000); 116 var1.setLocationAndAngles(this.theAnimal.posX, this.theAnimal.posY, this.theAnimal.posZ, 0.0F, 0.0F); 117 this.theWorld.spawnEntityInWorld(var1); 118 Random var2 = this.theAnimal.getRNG(); 119 120 for (int var3 = 0; var3 < 7; ++var3) 121 { 122 double var4 = var2.nextGaussian() * 0.02D; 123 double var6 = var2.nextGaussian() * 0.02D; 124 double var8 = var2.nextGaussian() * 0.02D; 125 this.theWorld.spawnParticle("heart", this.theAnimal.posX + (double)(var2.nextFloat() * this.theAnimal.width * 2.0F) - (double)this.theAnimal.width, this.theAnimal.posY + 0.5D + (double)(var2.nextFloat() * this.theAnimal.height), this.theAnimal.posZ + (double)(var2.nextFloat() * this.theAnimal.width * 2.0F) - (double)this.theAnimal.width, var4, var6, var8); 126 } 127 } 128 } 129 }