    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 random = par0EntityCreature.getRNG();
    053        boolean flag = false;
    054        int k = 0;
    055        int l = 0;
    056        int i1 = 0;
    057        float f = -99999.0F;
    058        boolean flag1;
    059
    060        if (par0EntityCreature.hasHome())
    061        {
    062            double d0 = (double)(par0EntityCreature.getHomePosition().getDistanceSquared(MathHelper.floor_double(par0EntityCreature.posX), MathHelper.floor_double(par0EntityCreature.posY), MathHelper.floor_double(par0EntityCreature.posZ)) + 4.0F);
    063            double d1 = (double)(par0EntityCreature.getMaximumHomeDistance() + (float)par1);
    064            flag1 = d0 < d1 * d1;
    065        }
    066        else
    067        {
    068            flag1 = false;
    069        }
    070
    071        for (int j1 = 0; j1 < 10; ++j1)
    072        {
    073            int k1 = random.nextInt(2 * par1) - par1;
    074            int l1 = random.nextInt(2 * par2) - par2;
    075            int i2 = random.nextInt(2 * par1) - par1;
    076
    077            if (par3Vec3 == null || (double)k1 * par3Vec3.xCoord + (double)i2 * par3Vec3.zCoord >= 0.0D)
    078            {
    079                k1 += MathHelper.floor_double(par0EntityCreature.posX);
    080                l1 += MathHelper.floor_double(par0EntityCreature.posY);
    081                i2 += MathHelper.floor_double(par0EntityCreature.posZ);
    082
    083                if (!flag1 || par0EntityCreature.isWithinHomeDistance(k1, l1, i2))
    084                {
    085                    float f1 = par0EntityCreature.getBlockPathWeight(k1, l1, i2);
    086
    087                    if (f1 > f)
    088                    {
    089                        f = f1;
    090                        k = k1;
    091                        l = l1;
    092                        i1 = i2;
    093                        flag = true;
    094                    }
    095                }
    096            }
    097        }
    098
    099        if (flag)
    100        {
    101            return par0EntityCreature.worldObj.getWorldVec3Pool().getVecFromPool((double)k, (double)l, (double)i1);
    102        }
    103        else
    104        {
    105            return null;
    106        }
    107    }
    108}