    001package net.minecraft.entity.ai;
    002
    003import java.util.Random;
    004import net.minecraft.entity.EntityCreature;
    005import net.minecraft.util.MathHelper;
    006import net.minecraft.util.Vec3;
    007
    008public class RandomPositionGenerator
    009{
    010    /**
    011     * used to store a driection when the user passes a point to move towards or away from. WARNING: NEVER THREAD SAFE.
    012     * MULTIPLE findTowards and findAway calls, will share this var
    013     */
    014    private static Vec3 staticVector = Vec3.createVectorHelper(0.0D, 0.0D, 0.0D);
    015
    016    /**
    017     * finds a random target within par1(x,z) and par2 (y) blocks
    018     */
    019    public static Vec3 findRandomTarget(EntityCreature par0EntityCreature, int par1, int par2)
    020    {
    021        return findRandomTargetBlock(par0EntityCreature, par1, par2, (Vec3)null);
    022    }
    023
    024    /**
    025     * finds a random target within par1(x,z) and par2 (y) blocks in the direction of the point par3
    026     */
    027    public static Vec3 findRandomTargetBlockTowards(EntityCreature par0EntityCreature, int par1, int par2, Vec3 par3Vec3)
    028    {
    029        staticVector.xCoord = par3Vec3.xCoord - par0EntityCreature.posX;
    030        staticVector.yCoord = par3Vec3.yCoord - par0EntityCreature.posY;
    031        staticVector.zCoord = par3Vec3.zCoord - par0EntityCreature.posZ;
    032        return findRandomTargetBlock(par0EntityCreature, par1, par2, staticVector);
    033    }
    034
    035    /**
    036     * finds a random target within par1(x,z) and par2 (y) blocks in the reverse direction of the point par3
    037     */
    038    public static Vec3 findRandomTargetBlockAwayFrom(EntityCreature par0EntityCreature, int par1, int par2, Vec3 par3Vec3)
    039    {
    040        staticVector.xCoord = par0EntityCreature.posX - par3Vec3.xCoord;
    041        staticVector.yCoord = par0EntityCreature.posY - par3Vec3.yCoord;
    042        staticVector.zCoord = par0EntityCreature.posZ - par3Vec3.zCoord;
    043        return findRandomTargetBlock(par0EntityCreature, par1, par2, staticVector);
    044    }
    045
    046    /**
    047     * searches 10 blocks at random in a within par1(x,z) and par2 (y) distance, ignores those not in the direction of
    048     * par3Vec3, then points to the tile for which creature.getBlockPathWeight returns the highest number
    049     */
    050    private static Vec3 findRandomTargetBlock(EntityCreature par0EntityCreature, int par1, int par2, Vec3 par3Vec3)
    051    {
    052        Random var4 = par0EntityCreature.getRNG();
    053        boolean var5 = false;
    054        int var6 = 0;
    055        int var7 = 0;
    056        int var8 = 0;
    057        float var9 = -99999.0F;
    058        boolean var10;
    059
    060        if (par0EntityCreature.hasHome())
    061        {
    062            double var11 = (double)(par0EntityCreature.getHomePosition().getDistanceSquared(MathHelper.floor_double(par0EntityCreature.posX), MathHelper.floor_double(par0EntityCreature.posY), MathHelper.floor_double(par0EntityCreature.posZ)) + 4.0F);
    063            double var13 = (double)(par0EntityCreature.getMaximumHomeDistance() + (float)par1);
    064            var10 = var11 < var13 * var13;
    065        }
    066        else
    067        {
    068            var10 = false;
    069        }
    070
    071        for (int var16 = 0; var16 < 10; ++var16)
    072        {
    073            int var12 = var4.nextInt(2 * par1) - par1;
    074            int var17 = var4.nextInt(2 * par2) - par2;
    075            int var14 = var4.nextInt(2 * par1) - par1;
    076
    077            if (par3Vec3 == null || (double)var12 * par3Vec3.xCoord + (double)var14 * par3Vec3.zCoord >= 0.0D)
    078            {
    079                var12 += MathHelper.floor_double(par0EntityCreature.posX);
    080                var17 += MathHelper.floor_double(par0EntityCreature.posY);
    081                var14 += MathHelper.floor_double(par0EntityCreature.posZ);
    082
    083                if (!var10 || par0EntityCreature.isWithinHomeDistance(var12, var17, var14))
    084                {
    085                    float var15 = par0EntityCreature.getBlockPathWeight(var12, var17, var14);
    086
    087                    if (var15 > var9)
    088                    {
    089                        var9 = var15;
    090                        var6 = var12;
    091                        var7 = var17;
    092                        var8 = var14;
    093                        var5 = true;
    094                    }
    095                }
    096            }
    097        }
    098
    099        if (var5)
    100        {
    101            return par0EntityCreature.worldObj.getWorldVec3Pool().getVecFromPool((double)var6, (double)var7, (double)var8);
    102        }
    103        else
    104        {
    105            return null;
    106        }
    107    }
    108}