001 package net.minecraft.entity.ai; 002 003 import java.util.List; 004 import net.minecraft.entity.Entity; 005 import net.minecraft.entity.EntityCreature; 006 import net.minecraft.entity.passive.EntityTameable; 007 import net.minecraft.entity.player.EntityPlayer; 008 import net.minecraft.pathfinding.PathEntity; 009 import net.minecraft.pathfinding.PathNavigate; 010 import net.minecraft.util.Vec3; 011 012 public class EntityAIAvoidEntity extends EntityAIBase 013 { 014 /** The entity we are attached to */ 015 private EntityCreature theEntity; 016 private float farSpeed; 017 private float nearSpeed; 018 private Entity closestLivingEntity; 019 private float distanceFromEntity; 020 021 /** The PathEntity of our entity */ 022 private PathEntity entityPathEntity; 023 024 /** The PathNavigate of our entity */ 025 private PathNavigate entityPathNavigate; 026 027 /** The class of the entity we should avoid */ 028 private Class targetEntityClass; 029 030 public EntityAIAvoidEntity(EntityCreature par1EntityCreature, Class par2Class, float par3, float par4, float par5) 031 { 032 this.theEntity = par1EntityCreature; 033 this.targetEntityClass = par2Class; 034 this.distanceFromEntity = par3; 035 this.farSpeed = par4; 036 this.nearSpeed = par5; 037 this.entityPathNavigate = par1EntityCreature.getNavigator(); 038 this.setMutexBits(1); 039 } 040 041 /** 042 * Returns whether the EntityAIBase should begin execution. 043 */ 044 public boolean shouldExecute() 045 { 046 if (this.targetEntityClass == EntityPlayer.class) 047 { 048 if (this.theEntity instanceof EntityTameable && ((EntityTameable)this.theEntity).isTamed()) 049 { 050 return false; 051 } 052 053 this.closestLivingEntity = this.theEntity.worldObj.getClosestPlayerToEntity(this.theEntity, (double)this.distanceFromEntity); 054 055 if (this.closestLivingEntity == null) 056 { 057 return false; 058 } 059 } 060 else 061 { 062 List var1 = this.theEntity.worldObj.getEntitiesWithinAABB(this.targetEntityClass, this.theEntity.boundingBox.expand((double)this.distanceFromEntity, 3.0D, (double)this.distanceFromEntity)); 063 064 if (var1.isEmpty()) 065 { 066 return false; 067 } 068 069 this.closestLivingEntity = (Entity)var1.get(0); 070 } 071 072 if (!this.theEntity.getEntitySenses().canSee(this.closestLivingEntity)) 073 { 074 return false; 075 } 076 else 077 { 078 Vec3 var2 = RandomPositionGenerator.findRandomTargetBlockAwayFrom(this.theEntity, 16, 7, this.theEntity.worldObj.getWorldVec3Pool().getVecFromPool(this.closestLivingEntity.posX, this.closestLivingEntity.posY, this.closestLivingEntity.posZ)); 079 080 if (var2 == null) 081 { 082 return false; 083 } 084 else if (this.closestLivingEntity.getDistanceSq(var2.xCoord, var2.yCoord, var2.zCoord) < this.closestLivingEntity.getDistanceSqToEntity(this.theEntity)) 085 { 086 return false; 087 } 088 else 089 { 090 this.entityPathEntity = this.entityPathNavigate.getPathToXYZ(var2.xCoord, var2.yCoord, var2.zCoord); 091 return this.entityPathEntity == null ? false : this.entityPathEntity.isDestinationSame(var2); 092 } 093 } 094 } 095 096 /** 097 * Returns whether an in-progress EntityAIBase should continue executing 098 */ 099 public boolean continueExecuting() 100 { 101 return !this.entityPathNavigate.noPath(); 102 } 103 104 /** 105 * Execute a one shot task or start executing a continuous task 106 */ 107 public void startExecuting() 108 { 109 this.entityPathNavigate.setPath(this.entityPathEntity, this.farSpeed); 110 } 111 112 /** 113 * Resets the task 114 */ 115 public void resetTask() 116 { 117 this.closestLivingEntity = null; 118 } 119 120 /** 121 * Updates the task 122 */ 123 public void updateTask() 124 { 125 if (this.theEntity.getDistanceSqToEntity(this.closestLivingEntity) < 49.0D) 126 { 127 this.theEntity.getNavigator().setSpeed(this.nearSpeed); 128 } 129 else 130 { 131 this.theEntity.getNavigator().setSpeed(this.farSpeed); 132 } 133 } 134 }