Example #1
0
    public void DrawPath(List <Vector3> nodes, Transform org)
    {
        worldLine = this.GetComponent <WorldLine> ();

        this.org = org;

        worldLine.line.Clear();

        foreach (Vector3 node in nodes)
        {
            worldLine.line.Push(node, Vector3.zero, Vector3.zero, .05f);
        }
    }
        private bool FindPoolPoint(WoWGameObject pool)
        {
            int         traceStep = AutoAngler.Instance.MySettings.TraceStep;
            const float pIx2      = 3.14159f * 2f;
            var         traceLine = new WorldLine[traceStep];

            PoolPoints.Clear();

            // scans starting at 15 yards from player for water at every 18 degress

            float range = 15;
            int   min   = AutoAngler.Instance.MySettings.MinPoolRange;
            int   max   = AutoAngler.Instance.MySettings.MaxPoolRange;
            float step  = AutoAngler.Instance.MySettings.PoolRangeStep;
            float delta = step;
            float avg   = (min + max) / 2;

            while (true)
            {
                for (int i = 0; i < traceStep; i++)
                {
                    WoWPoint p      = pool.Location.RayCast((i * pIx2) / traceStep, range);
                    WoWPoint hPoint = p;
                    hPoint.Z += 45;
                    WoWPoint lPoint = p;
                    lPoint.Z          -= 1;
                    traceLine[i].Start = hPoint;
                    traceLine[i].End   = lPoint;
                }
                WoWPoint[] hitPoints;
                bool[]     tracelineRetVals;
                GameWorld.MassTraceLine(traceLine, GameWorld.CGWorldFrameHitFlags.HitTestGroundAndStructures,
                                        out tracelineRetVals, out hitPoints);
                // what I'm doing here is compare the elevation of 4 corners around a point with
                // that point's elevation to determine if that point is too steep to stand on.
                var slopetraces = new List <WorldLine>();
                var testPoints  = new List <WoWPoint>();
                for (int i = 0; i < traceStep; i++)
                {
                    if (tracelineRetVals[i])
                    {
                        slopetraces.AddRange(GetQuadSloopTraceLines(hitPoints[i]));
                        testPoints.Add(hitPoints[i]);
                    }
                    else if (WaterWalking.CanCast)
                    {
                        traceLine[i].End.Z = pool.Z + 1;
                        PoolPoints.Add(traceLine[i].End);
                    }
                }
                // fire tracelines..
                bool[]     lavaRetVals = null;
                WoWPoint[] slopeHits;
                using (new FrameLock())
                {
                    bool[] slopelinesRetVals;
                    GameWorld.MassTraceLine(slopetraces.ToArray(),
                                            GameWorld.CGWorldFrameHitFlags.HitTestGroundAndStructures,
                                            out slopelinesRetVals, out slopeHits);
                    if (AutoAngler.Instance.MySettings.AvoidLava)
                    {
                        GameWorld.MassTraceLine(slopetraces.ToArray(), GameWorld.CGWorldFrameHitFlags.HitTestLiquid2,
                                                out lavaRetVals);
                    }
                }

                // process results
                PoolPoints.AddRange(ProcessSlopeAndLavaResults(testPoints, slopeHits, lavaRetVals));
                // perform LOS checks
                if (PoolPoints.Count > 0)
                {
                    var losLine = new WorldLine[PoolPoints.Count];
                    for (int i2 = 0; i2 < PoolPoints.Count; i2++)
                    {
                        WoWPoint point = PoolPoints[i2];
                        point.Z          += 2;
                        losLine[i2].Start = point;
                        losLine[i2].End   = pool.Location;
                    }
                    GameWorld.MassTraceLine(losLine, GameWorld.CGWorldFrameHitFlags.HitTestGroundAndStructures,
                                            out tracelineRetVals);
                    for (int i2 = PoolPoints.Count - 1; i2 >= 0; i2--)
                    {
                        if (tracelineRetVals[i2])
                        {
                            PoolPoints.RemoveAt(i2);
                        }
                    }
                }
                // sort pools by distance to player
                PoolPoints.Sort((p1, p2) => p1.Distance(_me.Location).CompareTo(p2.Distance(_me.Location)));
                if (!_me.IsFlying)
                {
                    // if we are not flying check if we can genorate a path to points.
                    for (int i = 0; i < PoolPoints.Count;)
                    {
                        WoWPoint[] testP = Navigator.GeneratePath(_me.Location, PoolPoints[i]);
                        if (testP.Length > 0)
                        {
                            return(true);
                        }
                        PoolPoints.RemoveAt(i);
                        PoolPoints.Sort((a, b) => a.Distance(_me.Location).CompareTo(b.Distance(_me.Location)));
                    }
                }
                if (PoolPoints.Count > 0)
                {
                    return(true);
                }
                bool minCaped = (15 - delta) < min;
                bool maxCaped = (15 + delta) > max;
                if (minCaped && maxCaped)
                {
                    break;
                }

                if ((range <= 15 && (15 + delta) <= max) || minCaped)
                {
                    range = 15 + delta;
                    if (avg < 15 || minCaped)
                    {
                        delta += step;
                    }
                    continue;
                }

                if ((range > 15 && (15 - delta) >= min) || maxCaped)
                {
                    range = 15 - delta;
                    if (avg >= 15 || maxCaped)
                    {
                        delta += step;
                    }
                }
            }
            return(false);
        }
        private bool FindPoolPoint(WoWGameObject pool)
        {
            int traceStep = AutoAngler.Instance.MySettings.TraceStep;
            const float pIx2 = 3.14159f*2f;
            var traceLine = new WorldLine[traceStep];
            PoolPoints.Clear();

            // scans starting at 15 yards from player for water at every 18 degress 

            float range = 15;
            int min = AutoAngler.Instance.MySettings.MinPoolRange;
            int max = AutoAngler.Instance.MySettings.MaxPoolRange;
            float step = AutoAngler.Instance.MySettings.PoolRangeStep;
            float delta = step;
            float avg = (min + max)/2;
            while (true)
            {
                for (int i = 0; i < traceStep; i++)
                {
                    WoWPoint p = pool.Location.RayCast((i*pIx2)/traceStep, range);
                    WoWPoint hPoint = p;
                    hPoint.Z += 45;
                    WoWPoint lPoint = p;
                    lPoint.Z -= 1;
                    traceLine[i].Start = hPoint;
                    traceLine[i].End = lPoint;
                }
                WoWPoint[] hitPoints;
                bool[] tracelineRetVals;
                GameWorld.MassTraceLine(traceLine, GameWorld.CGWorldFrameHitFlags.HitTestGroundAndStructures,
                                        out tracelineRetVals, out hitPoints);
                // what I'm doing here is compare the elevation of 4 corners around a point with 
                // that point's elevation to determine if that point is too steep to stand on.
                var slopetraces = new List<WorldLine>();
                var testPoints = new List<WoWPoint>();
                for (int i = 0; i < traceStep; i++)
                {
                    if (tracelineRetVals[i])
                    {
                        slopetraces.AddRange(GetQuadSloopTraceLines(hitPoints[i]));
                        testPoints.Add(hitPoints[i]);
                    }
                    else if (WaterWalking.CanCast)
                    {
                        traceLine[i].End.Z = pool.Z + 1;
                        PoolPoints.Add(traceLine[i].End);
                    }
                }
                // fire tracelines.. 
                bool[] lavaRetVals = null;
                WoWPoint[] slopeHits;
                using (StyxWoW.Memory.AcquireFrame())
                {
                    bool[] slopelinesRetVals;
                    GameWorld.MassTraceLine(slopetraces.ToArray(),
                                            GameWorld.CGWorldFrameHitFlags.HitTestGroundAndStructures,
                                            out slopelinesRetVals, out slopeHits);
                    if (AutoAngler.Instance.MySettings.AvoidLava)
                    {
                        GameWorld.MassTraceLine(slopetraces.ToArray(), GameWorld.CGWorldFrameHitFlags.HitTestLiquid2,
                                                out lavaRetVals);
                    }
                }

                // process results
                PoolPoints.AddRange(ProcessSlopeAndLavaResults(testPoints, slopeHits, lavaRetVals));
                // perform LOS checks
                if (PoolPoints.Count > 0)
                {
                    var losLine = new WorldLine[PoolPoints.Count];
                    for (int i2 = 0; i2 < PoolPoints.Count; i2++)
                    {
                        WoWPoint point = PoolPoints[i2];
                        point.Z += 2;
                        losLine[i2].Start = point;
                        losLine[i2].End = pool.Location;
                    }
                    GameWorld.MassTraceLine(losLine, GameWorld.CGWorldFrameHitFlags.HitTestGroundAndStructures,
                                            out tracelineRetVals);
                    for (int i2 = PoolPoints.Count - 1; i2 >= 0; i2--)
                    {
                        if (tracelineRetVals[i2])
                            PoolPoints.RemoveAt(i2);
                    }
                }
                // sort pools by distance to player                
                PoolPoints.Sort((p1, p2) => p1.Distance(_me.Location).CompareTo(p2.Distance(_me.Location)));
                if (!_me.IsFlying)
                {
                    // if we are not flying check if we can genorate a path to points.
                    for (int i = 0; i < PoolPoints.Count;)
                    {
                        WoWPoint[] testP = Navigator.GeneratePath(_me.Location, PoolPoints[i]);
                        if (testP.Length > 0)
                        {
                            return true;
                        }
                        PoolPoints.RemoveAt(i);
                        PoolPoints.Sort((a, b) => a.Distance(_me.Location).CompareTo(b.Distance(_me.Location)));
                    }
                }
                if (PoolPoints.Count > 0)
                    return true;
                bool minCaped = (15 - delta) < min;
                bool maxCaped = (15 + delta) > max;
                if (minCaped && maxCaped)
                    break;

                if ((range <= 15 && (15 + delta) <= max) || minCaped)
                {
                    range = 15 + delta;
                    if (avg < 15 || minCaped)
                        delta += step;
                    continue;
                }

                if ((range > 15 && (15 - delta) >= min) || maxCaped)
                {
                    range = 15 - delta;
                    if (avg >= 15 || maxCaped)
                        delta += step;
                }
            }
            return false;
        }
Example #4
0
        // Finds another point near the destination.  Useful when toon is 'waiting' for something
        // (e.g., boat, mob repops, etc). This allows multiple people running
        // the same profile to not stand on top of each other while waiting for
        // something.
        public static WoWPoint FanOutRandom(this WoWPoint location,
                                            double maxRadius)
        {
            const int    CYLINDER_LINE_COUNT  = 12;
            const int    MAX_TRIES            = 50;
            const double SAFE_DISTANCE_BUFFER = 1.75;

            WoWPoint candidateDestination = location;
            int      tryCount;

            // Most of the time we'll find a viable spot in less than 2 tries...
            // However, if you're standing on a pier, or small platform a
            // viable alternative may take 10-15 tries--its all up to the
            // random number generator.
            for (tryCount = MAX_TRIES; tryCount > 0; --tryCount)
            {
                WoWPoint    circlePoint;
                bool[]      hitResults;
                WoWPoint[]  hitPoints;
                int         index;
                WorldLine[] traceLines = new WorldLine[CYLINDER_LINE_COUNT + 1];

                candidateDestination = location.AddPolarXY((TAU * StyxWoW.Random.NextDouble()), (maxRadius * StyxWoW.Random.NextDouble()), 0.0);

                // Build set of tracelines that can evaluate the candidate destination --
                // We build a cone of lines with the cone's base at the destination's 'feet',
                // and the cone's point at maxRadius over the destination's 'head'.  We also
                // include the cone 'normal' as the first entry.

                // 'Normal' vector
                index = 0;
                traceLines[index].Start = candidateDestination.Add(0.0, 0.0, maxRadius);
                traceLines[index].End   = candidateDestination.Add(0.0, 0.0, -maxRadius);

                // Cylinder vectors
                for (double turnFraction = 0.0; turnFraction < TAU; turnFraction += (TAU / CYLINDER_LINE_COUNT))
                {
                    ++index;
                    circlePoint             = candidateDestination.AddPolarXY(turnFraction, SAFE_DISTANCE_BUFFER, 0.0);
                    traceLines[index].Start = circlePoint.Add(0.0, 0.0, maxRadius);
                    traceLines[index].End   = circlePoint.Add(0.0, 0.0, -maxRadius);
                }


                // Evaluate the cylinder...
                // The result for the 'normal' vector (first one) will be the location where the
                // destination meets the ground.  Before this MassTrace, only the candidateDestination's
                // X/Y values were valid.
                GameWorld.MassTraceLine(traceLines.ToArray(),
                                        TraceLineHitFlags.Collision,
                                        out hitResults,
                                        out hitPoints);

                candidateDestination = hitPoints[0];    // From 'normal', Destination with valid Z coordinate


                // Sanity check...
                // We don't want to be standing right on the edge of a drop-off (say we'e on
                // a plaform or pier).  If there is not solid ground all around us, we reject
                // the candidate.  Our test for validity is that the walking distance must
                // not be more than 20% greater than the straight-line distance to the point.
                int viableVectorCount = hitPoints.Sum(point => ((Me.Location.SurfacePathDistance(point) < (Me.Location.Distance(point) * 1.20))
                                                                      ? 1
                                                                      : 0));

                if (viableVectorCount < (CYLINDER_LINE_COUNT + 1))
                {
                    continue;
                }

                // If new destination is 'too close' to our current position, try again...
                if (Me.Location.Distance(candidateDestination) <= SAFE_DISTANCE_BUFFER)
                {
                    continue;
                }

                break;
            }

            // If we exhausted our tries, just go with simple destination --
            if (tryCount <= 0)
            {
                candidateDestination = location;
            }

            return(candidateDestination);
        }
Example #5
0
        // Finds another point near the destination.  Useful when toon is 'waiting' for something
        // (e.g., boat, mob repops, etc). This allows multiple people running
        // the same profile to not stand on top of each other while waiting for
        // something.
        public static WoWPoint     FanOutRandom(this WoWPoint  location,
                                                double         maxRadius)
        {
            const int           CYLINDER_LINE_COUNT     =  12;
            const int           MAX_TRIES               =  50;
            const double        SAFE_DISTANCE_BUFFER    =   1.75;

            WoWPoint            candidateDestination  = location;
            int                 tryCount;

            // Most of the time we'll find a viable spot in less than 2 tries...
            // However, if you're standing on a pier, or small platform a
            // viable alternative may take 10-15 tries--its all up to the
            // random number generator.
            for (tryCount = MAX_TRIES;   tryCount > 0;    --tryCount)
            {
                WoWPoint        circlePoint;
                bool[]          hitResults;
                WoWPoint[]      hitPoints;
                int             index;
                WorldLine[]     traceLines  = new WorldLine[CYLINDER_LINE_COUNT +1];

                candidateDestination = location.AddPolarXY((TAU * _random.NextDouble()),  (maxRadius * _random.NextDouble()),  0.0);

                // Build set of tracelines that can evaluate the candidate destination --
                // We build a cone of lines with the cone's base at the destination's 'feet',
                // and the cone's point at maxRadius over the destination's 'head'.  We also
                // include the cone 'normal' as the first entry.

                // 'Normal' vector
                index = 0;
                traceLines[index].Start = candidateDestination.Add(0.0, 0.0, maxRadius);
                traceLines[index].End   = candidateDestination.Add(0.0, 0.0, -maxRadius);

                // Cylinder vectors
                for (double turnFraction = 0.0;    turnFraction < TAU;    turnFraction += (TAU / CYLINDER_LINE_COUNT))
                {
                    ++index;
                    circlePoint = candidateDestination.AddPolarXY(turnFraction, SAFE_DISTANCE_BUFFER, 0.0);
                    traceLines[index].Start = circlePoint.Add(0.0, 0.0, maxRadius);
                    traceLines[index].End   = circlePoint.Add(0.0, 0.0, -maxRadius);
                }
                

                // Evaluate the cylinder...
                // The result for the 'normal' vector (first one) will be the location where the
                // destination meets the ground.  Before this MassTrace, only the candidateDestination's
                // X/Y values were valid.
                GameWorld.MassTraceLine(traceLines.ToArray(),
                                        GameWorld.CGWorldFrameHitFlags.HitTestGroundAndStructures,
                                        out hitResults,
                                        out hitPoints);

                candidateDestination = hitPoints[0];    // From 'normal', Destination with valid Z coordinate


                // Sanity check...
                // We don't want to be standing right on the edge of a drop-off (say we'e on
                // a plaform or pier).  If there is not solid ground all around us, we reject
                // the candidate.  Our test for validity is that the walking distance must
                // not be more than 20% greater than the straight-line distance to the point.
                int     viableVectorCount = hitPoints.Sum(point => ((Me.Location.SurfacePathDistance(point) < (Me.Location.Distance(point) * 1.20))
                                                                      ? 1
                                                                      : 0));

                if (viableVectorCount < (CYLINDER_LINE_COUNT +1))
                    { continue; }

                // If new destination is 'too close' to our current position, try again...
                if (Me.Location.Distance(candidateDestination) <= SAFE_DISTANCE_BUFFER)
                    { continue; }

                break;
            }

            // If we exhausted our tries, just go with simple destination --
            if (tryCount <= 0)
                { candidateDestination = location; }
            
            return (candidateDestination);
        }
Example #6
0
        float?GetFaceWaterDirection()
        {
            WoWPoint playerLoc  = _me.Location;
            var      sonar      = new List <int>(TraceStep);
            var      tracelines = new WorldLine[TraceStep * 3];

            bool[] tracelineRetVals;
            for (int i = 0; i < TraceStep; i++)
            {
                // scans 10,15 and 20 yards from player for water at every 18 degress
                for (int n = 0; n < 3; n++)
                {
                    WoWPoint p         = (playerLoc.RayCast((i * PIx2) / TraceStep, 10 + (n * 5)));
                    WoWPoint highPoint = p;
                    highPoint.Z += 5;
                    WoWPoint lowPoint = p;
                    lowPoint.Z -= 55;
                    tracelines[(i * 3) + n].Start = highPoint;
                    tracelines[(i * 3) + n].End   = lowPoint;
                }
            }
            GameWorld.MassTraceLine(tracelines,
                                    GameWorld.CGWorldFrameHitFlags.HitTestLiquid | GameWorld.CGWorldFrameHitFlags.HitTestLiquid2,
                                    out tracelineRetVals);
            for (int i = 0; i < TraceStep; i++)
            {
                int scan = 0;
                for (int n = 0; n < 3; n++)
                {
                    if (tracelineRetVals[(i * 3) + n])
                    {
                        scan++;
                    }
                }
                sonar.Add(scan);
            }

            int widest = 0;

            for (int i = 0; i < TraceStep; i++)
            {
                if (sonar[i] > widest)
                {
                    widest = sonar[i];
                }
            }
            bool counting = false;
            int  startIndex = 0, bigestStartIndex = 0, startLen = 0, endLen = 0, bigestStretch = 0;

            // if we found water find the largest area and face towards the center of it.


            if (widest > 0)
            {
                for (int i = 0; i < TraceStep; i++)
                {
                    if (sonar[i] == widest && !counting)
                    {
                        startIndex = i;
                        if (i == 0)
                        {
                            startLen = 1;
                        }
                        counting = true;
                    }
                    if (sonar[i] != widest && counting)
                    {
                        if ((i) - startIndex > bigestStretch)
                        {
                            bigestStretch    = (i) - startIndex;
                            bigestStartIndex = startIndex;
                        }
                        if (startIndex == 0)
                        {
                            startLen = i;
                        }
                        counting = false;
                    }
                    if (sonar[i] == widest && counting && i == 19)
                    {
                        endLen = i - startIndex;
                    }
                }
                int index;
                if (startLen + endLen > bigestStretch)
                {
                    if (startLen >= endLen)
                    {
                        index = startLen > endLen ? startLen - endLen : endLen - startLen;
                    }
                    else
                    {
                        index = (TraceStep - 1) - (endLen - startLen);
                    }
                }
                else
                {
                    index = bigestStartIndex + (bigestStretch / 2);
                }
                float direction = (index * PIx2) / 20;

                return(direction);
            }
            return(null);
        }
        /// <summary>
        /// <para>Finds another point near the destination.  Useful when toon is 'waiting' for something
        /// (e.g., boat, mob repops, etc). This allows multiple people running
        /// the same profile to not stand on top of each other while waiting for
        /// something.</para>
        /// <para>Notes:<list type="bullet">
        /// <item><description><para> * The returned Vector3 is carefully chosen.  The returned Vector3
        /// will not cause you to fall off a boat dock or Zeppelin landing.</para></description></item>
        /// </list></para>
        /// </summary>
        /// <param name="location"></param>
        /// <param name="maxRadius"></param>
        /// <returns></returns>
        /// <remarks>17Apr2011-12:16UTC chinajade</remarks>
        public static Vector3 FanOutRandom(this Vector3 location, double maxRadius)
        {
            Contract.Requires(maxRadius >= 0.0, context => "maxRadius >= 0.0");

            // Optimize situations where we want a very close-by point...
            if (maxRadius <= 1)
            {
                return(location);
            }

            const int    CYLINDER_LINE_COUNT  = 12;
            const int    MAX_TRIES            = 50;
            const double SAFE_DISTANCE_BUFFER = 1.75;

            Vector3 candidateDestination = location;
            int     tryCount;

            // ActiveMover is null in some cases where player is not in control of movement,
            // such as when on a taxi like the one for the
            // 'Mission: The Murketh and Shaadraz Gateways' quest (http://www.wowhead.com/quest=10146)
            var me = WoWMovement.ActiveMover ?? StyxWoW.Me;

            Contract.Requires(me != null, context => "me != null");
            var myLoc = me.Location;

            // Most of the time we'll find a viable spot in less than 2 tries...
            // However, if you're standing on a pier, or small platform a
            // viable alternative may take 10-15 tries--its all up to the
            // random number generator.
            for (tryCount = MAX_TRIES; tryCount > 0; --tryCount)
            {
                bool[]                hitResults;
                Vector3[]             hitPoints;
                Func <double, double> weightedRandomRadius =
                    (radiusMaximum) =>
                {
                    return
                        ((StyxWoW.Random.Next(101) < 80)
                         // We want a large number of the candidate magnitudes to be near the max range.
                         // This encourages toons to 'spread out'.
                                    ? ((radiusMaximum * 0.70) + (radiusMaximum * 0.30 * StyxWoW.Random.NextDouble()))
                                    : (radiusMaximum * StyxWoW.Random.NextDouble()));
                };
                var traceLines = new WorldLine[CYLINDER_LINE_COUNT + 1];

                candidateDestination = location.AddPolarXY((TAU * StyxWoW.Random.NextDouble()), weightedRandomRadius(maxRadius), 0.0);

                // If destination is in the air...
                if (!IsOverGround(candidateDestination, 3.0))
                {
                    // If we don't have clear LoS between the specified and candidate destinations, the candidate is unsuitable...
                    if (GameWorld.TraceLine(location, candidateDestination, TraceLineHitFlags.Collision))
                    {
                        continue;
                    }

                    // Otherwise, we have our candidate destination...
                    break;
                }


                // Ground-based destinations...
                // Build set of tracelines that can evaluate the candidate destination --
                // We build a cone of lines with the cone's base at the destination's 'feet',
                // and the cone's point at maxRadius over the destination's 'head'.  We also
                // include the cone 'normal' as the first entry.

                // 'Normal' vector
                var index = 0;
                traceLines[index].Start = candidateDestination.Add(0.0, 0.0, maxRadius);
                traceLines[index].End   = candidateDestination.Add(0.0, 0.0, -maxRadius);

                // Cylinder vectors
                for (double turnFraction = 0.0; turnFraction < TAU; turnFraction += (TAU / CYLINDER_LINE_COUNT))
                {
                    ++index;
                    var circlePoint = candidateDestination.AddPolarXY(turnFraction, SAFE_DISTANCE_BUFFER, 0.0);
                    traceLines[index].Start = circlePoint.Add(0.0, 0.0, maxRadius);
                    traceLines[index].End   = circlePoint.Add(0.0, 0.0, -maxRadius);
                }


                // Evaluate the cylinder...
                // The result for the 'normal' vector (first one) will be the location where the
                // destination meets the ground.  Before this MassTrace, only the candidateDestination's
                // X/Y values were valid.
                GameWorld.MassTraceLine(traceLines.ToArray(),
                                        TraceLineHitFlags.Collision,
                                        out hitResults,
                                        out hitPoints);

                candidateDestination = hitPoints[0];    // From 'normal', Destination with valid Z coordinate


                // Sanity check...
                // We don't want to be standing right on the edge of a drop-off (say we'e on
                // a plaform or pier).  If there is not solid ground all around us, we reject
                // the candidate.  Our test for validity is that the walking distance must
                // not be more than 20% greater than the straight-line distance to the point.
                // TODO: FanOutRandom PathTraversalCost on point (replace with HB's SampleMesh method instead)
                int viableVectorCount = hitPoints.Sum(point => ((location./*PathTraversalCost*/ Distance(point) < (location.Distance(point) * 1.20))
                                                                ? 1
                                                                : 0));

                if (viableVectorCount < (CYLINDER_LINE_COUNT * 0.8))
                {
                    continue;
                }

                // If new destination is 'too close' to our current position, try again...
                if (myLoc.Distance(candidateDestination) <= SAFE_DISTANCE_BUFFER)
                {
                    continue;
                }

                break;
            }

            // If we exhausted our tries, just go with simple destination --
            if (tryCount <= 0)
            {
                candidateDestination = location;
            }

            return(candidateDestination);
        }
Example #8
0
 // Use this for initialization
 void Start()
 {
     worldLine = this.GetComponent <WorldLine> ();
     worldLine.MakeNewMesh();
     transform.position = new Vector3(0, .25f, 0);
 }
Example #9
0
        float? GetFaceWaterDirection()
        {
            WoWPoint playerLoc = _me.Location;
            var sonar = new List<int>(TraceStep);
            var tracelines = new WorldLine[TraceStep * 3];
            bool[] tracelineRetVals;
            for (int i = 0; i < TraceStep; i++)
            {
                // scans 10,15 and 20 yards from player for water at every 18 degress
                for (int n = 0; n < 3; n++)
                {
                    WoWPoint p = (playerLoc.RayCast((i * PIx2) / TraceStep, 10 + (n * 5)));
                    WoWPoint highPoint = p;
                    highPoint.Z += 5;
                    WoWPoint lowPoint = p;
                    lowPoint.Z -= 55;
                    tracelines[(i * 3) + n].Start = highPoint;
                    tracelines[(i * 3) + n].End = lowPoint;
                }
            }
            GameWorld.MassTraceLine(tracelines,
                GameWorld.CGWorldFrameHitFlags.HitTestLiquid | GameWorld.CGWorldFrameHitFlags.HitTestLiquid2,
                out tracelineRetVals);
            for (int i = 0; i < TraceStep; i++)
            {
                int scan = 0;
                for (int n = 0; n < 3; n++)
                {
                    if (tracelineRetVals[(i * 3) + n])
                        scan++;
                }
                sonar.Add(scan);
            }

            int widest = 0;
            for (int i = 0; i < TraceStep; i++)
            {
                if (sonar[i] > widest)
                    widest = sonar[i];
            }
            bool counting = false;
            int startIndex = 0, bigestStartIndex = 0, startLen = 0, endLen = 0, bigestStretch = 0;
            // if we found water find the largest area and face towards the center of it.

            if (widest > 0)
            {
                for (int i = 0; i < TraceStep; i++)
                {
                    if (sonar[i] == widest && !counting)
                    {
                        startIndex = i;
                        if (i == 0)
                            startLen = 1;
                        counting = true;
                    }
                    if (sonar[i] != widest && counting)
                    {
                        if ((i) - startIndex > bigestStretch)
                        {
                            bigestStretch = (i) - startIndex;
                            bigestStartIndex = startIndex;
                        }
                        if (startIndex == 0)
                            startLen = i;
                        counting = false;
                    }
                    if (sonar[i] == widest && counting && i == 19)
                        endLen = i - startIndex;
                }
                int index;
                if (startLen + endLen > bigestStretch)
                {
                    if (startLen >= endLen)
                        index = startLen > endLen ? startLen - endLen : endLen - startLen;
                    else
                        index = (TraceStep - 1) - (endLen - startLen);
                }
                else
                    index = bigestStartIndex + (bigestStretch / 2);
                float direction = (index * PIx2) / 20;

                return direction;
            }
            return null;
        }
        private static bool FindPoolPoint(WoWGameObject pool, out List <WoWPoint> poolPoints)
        {
            int         traceStep = AutoAnglerSettings.Instance.TraceStep;
            const float pIx2      = 3.14159f * 2f;
            var         traceLine = new WorldLine[traceStep];

            poolPoints = new List <WoWPoint>();

            // scans starting at OptimumPoolDistance2D from player for water at every 18 degress
            float range      = OptimumPoolDistance2D;
            var   poolRadius = GetPoolRadius(pool);
            var   min        = MinCastDistance2D - poolRadius + PoolDistTolerance;
            var   max        = MaxCastDistance2D + poolRadius - PoolDistTolerance;


            float step  = AutoAnglerSettings.Instance.PoolRangeStep;
            float delta = step;
            float avg   = (min + max) / 2f;

            while (true)
            {
                for (int i = 0; i < traceStep; i++)
                {
                    WoWPoint p      = pool.Location.RayCast((i * pIx2) / traceStep, range);
                    WoWPoint hPoint = p;
                    hPoint.Z += 45;
                    WoWPoint lPoint = p;
                    lPoint.Z          -= 1;
                    traceLine[i].Start = hPoint;
                    traceLine[i].End   = lPoint;
                }
                WoWPoint[] hitPoints;
                bool[]     tracelineRetVals;
                GameWorld.MassTraceLine(traceLine, TraceLineHitFlags.Collision, out tracelineRetVals, out hitPoints);

                // what I'm doing here is compare the elevation of 4 corners around a point with
                // that point's elevation to determine if that point is too steep to stand on.
                var slopetraces = new List <WorldLine>();
                var testPoints  = new List <WoWPoint>();
                for (int i = 0; i < traceStep; i++)
                {
                    if (tracelineRetVals[i])
                    {
                        slopetraces.AddRange(GetQuadSloopTraceLines(hitPoints[i]));
                        testPoints.Add(hitPoints[i]);
                    }
                    else if (WaterWalking.IsActive || WaterWalking.CanCast)
                    {
                        traceLine[i].End.Z = pool.Z + 1;
                        poolPoints.Add(traceLine[i].End);
                    }
                }
                // fire tracelines..
                bool[]     lavaRetVals = null;
                WoWPoint[] slopeHits;
                using (StyxWoW.Memory.AcquireFrame())
                {
                    bool[] slopelinesRetVals;
                    GameWorld.MassTraceLine(slopetraces.ToArray(),
                                            TraceLineHitFlags.Collision,
                                            out slopelinesRetVals, out slopeHits);
                    if (AutoAnglerSettings.Instance.AvoidLava)
                    {
                        GameWorld.MassTraceLine(slopetraces.ToArray(), TraceLineHitFlags.LiquidAll,
                                                out lavaRetVals);
                    }
                }

                // process results
                poolPoints.AddRange(ProcessSlopeAndLavaResults(testPoints, slopeHits, lavaRetVals));
                // perform LOS checks
                if (poolPoints.Any())
                {
                    var losLine = new WorldLine[poolPoints.Count];
                    for (int i2 = 0; i2 < poolPoints.Count; i2++)
                    {
                        WoWPoint point = poolPoints[i2];
                        point.Z          += 2;
                        losLine[i2].Start = point;
                        losLine[i2].End   = pool.Location;
                    }
                    GameWorld.MassTraceLine(losLine, TraceLineHitFlags.Collision, out tracelineRetVals);
                    for (int i2 = poolPoints.Count - 1; i2 >= 0; i2--)
                    {
                        if (tracelineRetVals[i2])
                        {
                            poolPoints.RemoveAt(i2);
                        }
                    }
                }
                // sort pools by distance to player
                poolPoints.Sort((p1, p2) => p1.Distance(StyxWoW.Me.Location).CompareTo(p2.Distance(StyxWoW.Me.Location)));
                if (!StyxWoW.Me.IsFlying)
                {
                    // if we are not flying check if we can genorate a path to points.
                    for (int i = 0; i < poolPoints.Count;)
                    {
                        WoWPoint[] testP = Navigator.GeneratePath(StyxWoW.Me.Location, poolPoints[i]);
                        if (testP.Length > 0)
                        {
                            return(true);
                        }
                        poolPoints.RemoveAt(i);
                        poolPoints.Sort((a, b) => a.Distance(StyxWoW.Me.Location).CompareTo(b.Distance(StyxWoW.Me.Location)));
                    }
                }

                if (poolPoints.Any())
                {
                    return(true);
                }

                bool minCaped = (OptimumPoolDistance2D - delta) < min;
                bool maxCaped = (OptimumPoolDistance2D + delta) > max;
                if (minCaped && maxCaped)
                {
                    break;
                }

                if ((range <= OptimumPoolDistance2D && (OptimumPoolDistance2D + delta) <= max) || minCaped)
                {
                    range = OptimumPoolDistance2D + delta;
                    if (avg < OptimumPoolDistance2D || minCaped)
                    {
                        delta += step;
                    }
                    continue;
                }

                if ((range > OptimumPoolDistance2D && (OptimumPoolDistance2D - delta) >= min) || maxCaped)
                {
                    range = OptimumPoolDistance2D - delta;
                    if (avg >= OptimumPoolDistance2D || maxCaped)
                    {
                        delta += step;
                    }
                }
            }
            return(false);
        }