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}