示例#1
0
        public Path CreatePath(Location fromLoc, Location toLoc, float howClose, ILocationHeuristics locationHeuristics)
        {
            logger.WriteLine("Creating Path from " + fromLoc.ToString() + " tot " + toLoc.ToString());

            var sw = new Stopwatch();

            sw.Start();

            fromLoc = GetBestLocations(fromLoc);
            toLoc   = GetBestLocations(toLoc);

            Spot from = FindClosestSpot("fromLoc", fromLoc, MinStepLength);
            Spot to   = FindClosestSpot("toLoc", toLoc, MinStepLength);

            if (from == null)
            {
                from = AddAndConnectSpot(new Spot(fromLoc));
            }
            if (to == null)
            {
                to = AddAndConnectSpot(new Spot(toLoc));
            }

            Path rawPath = CreatePath(from, to, howClose, locationHeuristics);

            if (rawPath != null && paint != null)
            {
                Location prev = null;
                for (int i = 0; i < rawPath.Count(); i++)
                {
                    Location l = rawPath.Get(i);
                    paint.AddBigMarker(l.X, l.Y, l.Z);
                    if (prev != null)
                    {
                        paint.PaintPath(l.X, l.Y, l.Z, prev.X, prev.Y, prev.Z);
                    }
                    prev = l;
                }
            }
            logger.Debug(string.Format("CreatePath took {0} seconds.", sw.ElapsedMilliseconds / 1000));
            if (rawPath == null)
            {
                return(null);
            }
            else
            {
                Location last = rawPath.GetLast();
                if (last.GetDistanceTo(toLoc) > 1.0)
                {
                    rawPath.AddLast(toLoc);
                }
            }
            LastPath = rawPath;
            return(rawPath);
        }
示例#2
0
        public Path CreatePath(Location fromLoc, Location toLoc,
                               float howClose,
                               ILocationHeuristics locationHeuristics)
        {
            Stopwatch t    = Stopwatch.StartNew();
            Spot      from = FindClosestSpot(fromLoc, MinStepLength);
            Spot      to   = FindClosestSpot(toLoc, MinStepLength);

            if (from == null)
            {
                from = AddAndConnectSpot(new Spot(fromLoc));
            }
            if (to == null)
            {
                to = AddAndConnectSpot(new Spot(toLoc));
            }

            Path rawPath = CreatePath(from, to, to.location, howClose, true, locationHeuristics);


            if (rawPath != null && paint != null)
            {
                Location prev = null;
                for (int i = 0; i < rawPath.Count(); i++)
                {
                    Location l = rawPath.Get(i);
                    paint.AddBigMarker(l.X, l.Y, l.Z);
                    if (prev != null)
                    {
                        paint.PaintPath(l.X, l.Y, l.Z + 3, prev.X, prev.Y, prev.Z + 3);
                    }
                    prev = l;
                }
            }
            t.Stop();
            Log("CreatePath took " + t.Elapsed);
            if (rawPath == null)
            {
                return(null);
            }
            else
            {
                Location last = rawPath.GetLast();
                if (last.GetDistanceTo(toLoc) > 1.0)
                {
                    rawPath.AddLast(toLoc);
                }
            }
            return(rawPath);
        }
示例#3
0
        public Path CreatePath(Location fromLoc, Location toLoc,
                               float howClose,
                               ILocationHeuristics locationHeuristics)
        {
            System.DateTime t    = System.DateTime.Now;
            Spot            from = FindClosestSpot(fromLoc, MinStepLength);
            Spot            to   = FindClosestSpot(toLoc, MinStepLength);

            if (from == null)
            {
                from = AddAndConnectSpot(new Spot(fromLoc));
            }
            if (to == null)
            {
                to = AddAndConnectSpot(new Spot(toLoc));
            }

            Path rawPath = CreatePath(from, to, to.location, howClose, true, locationHeuristics);


            if (rawPath != null && paint != null)
            {
                Location prev = null;
                for (int i = 0; i < rawPath.Count; i++)
                {
                    Location l = rawPath.Get(i);
                    paint.AddBigMarker(l.X, l.Y, l.Z);
                    if (prev != null)
                    {
                        paint.PaintPath(l.X, l.Y, l.Z + 3, prev.X, prev.Y, prev.Z + 3);
                    }
                    prev = l;
                }
            }
            Console.WriteLine("CreatePath took {0}", System.DateTime.Now.Subtract(t).Seconds);
            if (rawPath == null)
            {
                return(null);
            }
            else
            {
                Location last = rawPath.GetLast();
                if (last.GetDistanceTo(toLoc) > 1.0)
                {
                    rawPath.AddLast(toLoc);
                }
            }
            return(rawPath);
        }
示例#4
0
        public Path CreatePath(Location fromLoc, Location toLoc,
                               float howClose,
                               ILocationHeuristics locationHeuristics)
        {
            GSpellTimer t    = new GSpellTimer(0);
            Spot        from = FindClosestSpot(fromLoc, MinStepLength);
            Spot        to   = FindClosestSpot(toLoc, MinStepLength);

            if (from == null)
            {
                from = AddAndConnectSpot(new Spot(fromLoc));
            }
            if (to == null)
            {
                to = AddAndConnectSpot(new Spot(toLoc));
            }

            Path rawPath = CreatePath(from, to, to.location, howClose, true, locationHeuristics);


            if (rawPath != null && paint != null)
            {
                Location prev = null;
                for (int i = 0; i < rawPath.Count(); i++)
                {
                    Location l = rawPath.Get(i);
                    paint.AddBigMarker(l.X, l.Y, l.Z);
                    if (prev != null)
                    {
                        paint.PaintPath(l.X, l.Y, l.Z + 3, prev.X, prev.Y, prev.Z + 3);
                    }
                    prev = l;
                }
            }
            PPather.WriteLine("CreatePath took " + -t.TicksLeft);
            if (rawPath == null)
            {
                return(null);
            }
            else
            {
                Location last = rawPath.GetLast();
                if (last.GetDistanceTo(toLoc) > 1.0)
                {
                    rawPath.AddLast(toLoc);
                }
            }
            return(rawPath);
        }
示例#5
0
        private Path CreatePath(Spot from, Spot to, float minHowClose, ILocationHeuristics locationHeuristics)
        {
            Spot newTo = Search(from, to, minHowClose, locationHeuristics);

            if (newTo != null)
            {
                if (newTo.GetDistanceTo(to) <= minHowClose)
                {
                    List <Spot> path = FollowTraceBack(from, newTo);
                    LastPath = new Path(path);
                    return(LastPath);
                }
            }
            return(null);
        }
示例#6
0
        public Path CreatePath(Spot from, Spot to, Location realDst,
                               float minHowClose, bool AllowInvented,
                               ILocationHeuristics locationHeuristics)
        {
            Spot newTo = search(from, to, realDst, minHowClose, AllowInvented,
                                locationHeuristics);

            if (newTo != null)
            {
                if (newTo.GetDistanceTo(to) <= minHowClose)
                {
                    List <Spot> path = FollowTraceBack(from, newTo);
                    return(new Path(path));
                }
            }
            return(null);
        }
示例#7
0
        private Path CreatePath(Spot from, Spot to, float minHowClose, ILocationHeuristics locationHeuristics)
        {
            Spot newTo = Search(from, to, minHowClose, locationHeuristics);

            if (newTo != null)
            {
                if (newTo.GetDistanceTo(to) <= MaximumAllowedRangeFromTarget)
                {
                    List <Spot> path = FollowTraceBack(from, newTo);
                    LastPath = new Path(path);
                    return(LastPath);
                }
                else
                {
                    logger.WriteLine($"Closest spot is too far from target. {newTo.GetDistanceTo(to)}>{MaximumAllowedRangeFromTarget}");
                    return(null);
                }
            }
            return(null);
        }
示例#8
0
        public void ScoreSpot_Pather(Spot spotLinkedToCurrent, Spot destinationSpot, int currentSearchID, ILocationHeuristics locationHeuristics, PriorityQueue <Spot, float> prioritySpotQueue)
        {
            //score spots
            float currentSearchSpotScore = currentSearchSpot.SearchScoreGet(currentSearchID);
            float linkedSpotScore        = 1E30f;
            float new_score = currentSearchSpotScore + currentSearchSpot.GetDistanceTo(spotLinkedToCurrent) + TurnCost(currentSearchSpot, spotLinkedToCurrent);

            if (locationHeuristics != null)
            {
                new_score += locationHeuristics.Score(currentSearchSpot.X, currentSearchSpot.Y, currentSearchSpot.Z);
            }
            if (spotLinkedToCurrent.IsFlagSet(Spot.FLAG_WATER))
            {
                new_score += 30;
            }

            if (spotLinkedToCurrent.SearchScoreIsSet(currentSearchID))
            {
                linkedSpotScore = spotLinkedToCurrent.SearchScoreGet(currentSearchID);
            }

            if (new_score < linkedSpotScore)
            {
                // shorter path to here found
                spotLinkedToCurrent.traceBack = currentSearchSpot;
                spotLinkedToCurrent.SearchScoreSet(currentSearchID, new_score);
                prioritySpotQueue.Enqueue(spotLinkedToCurrent, -(new_score + spotLinkedToCurrent.GetDistanceTo(destinationSpot) * heuristicsFactor));
            }
        }
示例#9
0
        public void ScoreSpot_A_Star_With_Model_And_Gradient_Avoidance(Spot spotLinkedToCurrent, Spot destinationSpot, int currentSearchID, ILocationHeuristics locationHeuristics, PriorityQueue <Spot, float> prioritySpotQueue)
        {
            //score spot
            float G_Score = currentSearchSpot.traceBackDistance + currentSearchSpot.GetDistanceTo(spotLinkedToCurrent); //  the movement cost to move from the starting point A to a given square on the grid, following the path generated to get there.
            float H_Score = spotLinkedToCurrent.GetDistanceTo2D(destinationSpot) * heuristicsFactor;                    // the estimated movement cost to move from that given square on the grid to the final destination, point B. This is often referred to as the heuristic, which can be a bit confusing. The reason why it is called that is because it is a guess. We really don�t know the actual distance until we find the path, because all sorts of things can be in the way (walls, water, etc.). You are given one way to calculate H in this tutorial, but there are many others that you can find in other articles on the web.
            float F_Score = G_Score + H_Score;

            if (spotLinkedToCurrent.IsFlagSet(Spot.FLAG_WATER))
            {
                F_Score += 30;
            }

            int score = GetTriangleClosenessScore(spotLinkedToCurrent.location);

            score   += GetTriangleGradiantScore(spotLinkedToCurrent.location, gradiantMax);
            F_Score += score * 2;

            if (!spotLinkedToCurrent.SearchScoreIsSet(currentSearchID) || F_Score < spotLinkedToCurrent.SearchScoreGet(currentSearchID))
            {
                // shorter path to here found
                spotLinkedToCurrent.traceBack         = currentSearchSpot;
                spotLinkedToCurrent.traceBackDistance = G_Score;
                spotLinkedToCurrent.SearchScoreSet(currentSearchID, F_Score);
                prioritySpotQueue.Enqueue(spotLinkedToCurrent, -F_Score);
            }
        }
示例#10
0
        private void ScoreSpot(Spot spotLinkedToCurrent, Spot destinationSpot, int currentSearchID, ILocationHeuristics locationHeuristics, PriorityQueue <Spot, float> prioritySpotQueue)
        {
            switch (searchScoreSpot)
            {
            case eSearchScoreSpot.A_Star:
                ScoreSpot_A_Star(spotLinkedToCurrent, destinationSpot, currentSearchID, locationHeuristics, prioritySpotQueue);
                break;

            case eSearchScoreSpot.A_Star_With_Model_Avoidance:
                ScoreSpot_A_Star_With_Model_And_Gradient_Avoidance(spotLinkedToCurrent, destinationSpot, currentSearchID, locationHeuristics, prioritySpotQueue);
                break;

            case eSearchScoreSpot.OriginalPather:
            default:
                ScoreSpot_Pather(spotLinkedToCurrent, destinationSpot, currentSearchID, locationHeuristics, prioritySpotQueue);
                break;
            }
        }
示例#11
0
        private Spot Search(Spot fromSpot, Spot destinationSpot, float minHowClose, ILocationHeuristics locationHeuristics)
        {
            var searchDuration = new Stopwatch();

            searchDuration.Start();
            var timeSinceProgress = new Stopwatch();

            timeSinceProgress.Start();

            var closest = 99999f;

            ClosestSpot = null;

            currentSearchStartSpot = fromSpot;
            searchID++;
            int currentSearchID = searchID;
            //searchProgress = new SearchProgress(fromSpot, destinationSpot, searchID);

            // lowest first queue
            PriorityQueue <Spot, float> prioritySpotQueue = new PriorityQueue <Spot, float>(); // (new SpotSearchComparer(dst, score)); ;

            prioritySpotQueue.Enqueue(fromSpot, -fromSpot.GetDistanceTo(destinationSpot) * heuristicsFactor);

            fromSpot.SearchScoreSet(currentSearchID, 0.0f);
            fromSpot.traceBack         = null;
            fromSpot.traceBackDistance = 0;

            // A* -ish algorithm
            while (prioritySpotQueue.Count != 0 && SearchEnabled)
            {
                if (sleepMSBetweenSpots != 0)
                {
                    Thread.Sleep(sleepMSBetweenSpots);
                }                                                                    // slow down the pathing

                float prio;
                currentSearchSpot = prioritySpotQueue.Dequeue(out prio); // .Value;

                // force the world to be loaded
                TriangleCollection tc = triangleWorld.GetChunkAt(currentSearchSpot.X, currentSearchSpot.Y);

                if (currentSearchSpot.SearchIsClosed(currentSearchID))
                {
                    continue;
                }
                currentSearchSpot.SearchClose(currentSearchID);

                //update status
                //if (!searchProgress.CheckProgress(currentSearchSpot)) { break; }

                // are we there?

                var distance = currentSearchSpot.location.GetDistanceTo(destinationSpot.location);

                if (distance <= minHowClose)
                {
                    return(currentSearchSpot); // got there
                }

                if (distance < closest)
                {
                    // spamming as hell
                    //logger.WriteLine($"Closet spot is {distance} from the target");
                    closest     = distance;
                    ClosestSpot = currentSearchSpot;
                    PeekSpot    = ClosestSpot;
                    timeSinceProgress.Reset();
                    timeSinceProgress.Start();
                }

                if (timeSinceProgress.Elapsed.TotalSeconds > ProgressTimeoutSeconds || searchDuration.Elapsed.TotalSeconds > TimeoutSeconds)
                {
                    logger.WriteLine("search failed, 10 seconds since last progress, returning the closest spot.");
                    return(ClosestSpot);
                }

                //Find spots to link to
                CreateSpotsAroundSpot(currentSearchSpot);

                //score each spot around the current search spot and add them to the queue
                foreach (Spot spotLinkedToCurrent in currentSearchSpot.GetPathsToSpots(this))
                {
                    if (spotLinkedToCurrent != null && !spotLinkedToCurrent.IsBlocked() && !spotLinkedToCurrent.SearchIsClosed(currentSearchID))
                    {
                        ScoreSpot(spotLinkedToCurrent, destinationSpot, currentSearchID, locationHeuristics, prioritySpotQueue);
                    }
                }
            }

            //we ran out of spots to search
            //searchProgress.LogStatus("  search failed. ");

            if (ClosestSpot != null && closest < MaximumAllowedRangeFromTarget)
            {
                logger.WriteLine("search failed, returning the closest spot.");
                return(ClosestSpot);
            }
            return(null);
        }
示例#12
0
        // return null if failed or the last spot in the path found

        private Spot search(Spot src, Spot dst,
                            Location realDst,
                            float minHowClose, bool AllowInvented,
                            ILocationHeuristics locationHeuristics)
        {
            searchID++;
            int      count            = 0;
            int      prevCount        = 0;
            int      currentSearchID  = searchID;
            float    heuristicsFactor = 1.3f;
            DateTime pre      = DateTime.Now;
            DateTime lastSpam = pre;

            // lowest first queue
            var q = new PriorityQueue <Spot, float>(); // (new SpotSearchComparer(dst, score)); ;

            q.Enqueue(src, -src.GetDistanceTo(dst) * heuristicsFactor);
            Spot BestSpot = null;

            //Set<Spot> closed      = new Set<Spot>();
            //SpotData<float> score = new SpotData<float>();

            src.SearchScoreSet(currentSearchID, 0.0f);
            src.traceBack = null;

            // A* -ish algorithm

            while (q.Count != 0) // && count < 100000)
            {
                float prio;
                Spot  spot = q.Dequeue(out prio); // .Value;
                //q.Remove(spot);


                if (spot.SearchIsClosed(currentSearchID))
                {
                    continue;
                }
                spot.SearchClose(currentSearchID);

                if (count % 100 == 0)
                {
                    TimeSpan span = DateTime.Now.Subtract(lastSpam);
                    if (span.Seconds != 0 && BestSpot != null)
                    {
                        Thread.Sleep(50); // give glider a chance to stop us
                        int t = span.Seconds * 1000 + span.Milliseconds;
                        if (t == 0)
                        {
                            Log("searching.... " + (count + 1) + " d: " + BestSpot.location.GetDistanceTo(realDst));
                        }
                        else
                        {
                            Log("searching.... " + (count + 1) + " d: " + BestSpot.location.GetDistanceTo(realDst) + " " +
                                (count - prevCount) * 1000 / t + " steps/s");
                        }
                        lastSpam  = DateTime.Now;
                        prevCount = count;
                    }
                }
                count++;


                if (spot.Equals(dst) || spot.location.GetDistanceTo(realDst) <= minHowClose)
                {
                    TimeSpan ts = DateTime.Now.Subtract(pre);
                    int      t  = ts.Seconds * 1000 + ts.Milliseconds;

                    /*if(t == 0)
                     *  Log("  search found the way there. " + count);
                     * else
                     *  Log("  search found the way there. " + count + " " + (count * 1000) / t + " steps/s");
                     */
                    return(spot); // got there
                }

                if (BestSpot == null ||
                    spot.location.GetDistanceTo(realDst) < BestSpot.location.GetDistanceTo(realDst))
                {
                    BestSpot = spot;
                }
                {
                    TimeSpan ts = DateTime.Now.Subtract(pre);
                    if (ts.Seconds > 15)
                    {
                        Log("too long search, aborting");
                        break;
                    }
                }

                float src_score = spot.SearchScoreGet(currentSearchID);

                //PathGraph.Log("inspect: " + c + " score " + s);


                int         new_found = 0;
                List <Spot> ll        = spot.GetPathsToSpots(this);
                foreach (Spot to in ll)
                {
                    //Spot to = GetSpot(l);

                    if (to != null && !to.IsBlocked() && !to.SearchIsClosed(currentSearchID))
                    {
                        float old_score = 1E30f;

                        float new_score = src_score + spot.GetDistanceTo(to) + TurnCost(spot, to);
                        if (locationHeuristics != null)
                        {
                            new_score += locationHeuristics.Score(spot.X, spot.Y, spot.Z);
                        }
                        if (to.GetFlag(Spot.FLAG_WATER))
                        {
                            new_score += 30;
                        }

                        if (to.SearchScoreIsSet(currentSearchID))
                        {
                            old_score = to.SearchScoreGet(currentSearchID);
                        }

                        if (new_score < old_score)
                        {
                            // shorter path to here found
                            to.traceBack = spot;
                            //if (q.Contains(to))
                            //   q.Remove(to); // very sloppy to not dequeue it
                            to.SearchScoreSet(currentSearchID, new_score);
                            q.Enqueue(to, -(new_score + to.GetDistanceTo(dst) * heuristicsFactor));
                            new_found++;
                        }
                    }
                }

                //hmm search the triangles :p
                if (!spot.GetFlag(Spot.FLAG_MPQ_MAPPED))
                {
                    var PI = (float)Math.PI;

                    spot.SetFlag(Spot.FLAG_MPQ_MAPPED, true);
                    for (float a = 0; a < PI * 2; a += PI / 8)
                    {
                        float nx = spot.X + (float)Math.Sin(a) * WantedStepLength; // *0.8f;
                        float ny = spot.Y + (float)Math.Cos(a) * WantedStepLength; // *0.8f;
                        Spot  s  = GetSpot(nx, ny, spot.Z);
                        if (s == null)
                        {
                            s = FindClosestSpot(new Location(nx, ny, spot.Z), MinStepLength); // TODO: this is slow
                        }
                        if (s != null)
                        {
                            // hmm, they should already be connected
                        }
                        else
                        {
                            float new_z;
                            int   flags;
                            // gogo find a new one
                            //PathGraph.Log("gogo brave new world");
                            if (!triangleWorld.FindStandableAt(nx, ny,
                                                               spot.Z - WantedStepLength * .75f,
                                                               spot.Z + WantedStepLength * .75f,
                                                               out new_z, out flags, toonHeight, toonSize))
                            {
                                //Spot blocked = new Spot(nx, ny, spot.Z);
                                //blocked.SetFlag(Spot.FLAG_BLOCKED, true);
                                //AddSpot(blocked);
                            }
                            else
                            {
                                s = FindClosestSpot(new Location(nx, ny, new_z), MinStepLength);
                                if (s == null)
                                {
                                    if (!triangleWorld.IsStepBlocked(spot.X, spot.Y, spot.Z, nx, ny, new_z,
                                                                     toonHeight, toonSize, null))
                                    {
                                        var  n  = new Spot(nx, ny, new_z);
                                        Spot to = AddAndConnectSpot(n);
                                        if ((flags & ChunkedTriangleCollection.TriangleFlagDeepWater) != 0)
                                        {
                                            to.SetFlag(Spot.FLAG_WATER, true);
                                        }
                                        if (((flags & ChunkedTriangleCollection.TriangleFlagModel) != 0) ||
                                            ((flags & ChunkedTriangleCollection.TriangleFlagObject) != 0))
                                        {
                                            to.SetFlag(Spot.FLAG_INDOORS, true);
                                        }
                                        if (to != n || to.SearchIsClosed(currentSearchID))
                                        {
                                            // PathGraph.Log("/sigh");
                                        }
                                        else
                                        {
                                            // There should be a path from source to this one now
                                            if (spot.HasPathTo(to.location))
                                            {
                                                float old_score = 1E30f;

                                                float new_score = src_score + spot.GetDistanceTo(to) +
                                                                  TurnCost(spot, to);
                                                if (locationHeuristics != null)
                                                {
                                                    new_score += locationHeuristics.Score(spot.X, spot.Y, spot.Z);
                                                }


                                                if (to.GetFlag(Spot.FLAG_WATER))
                                                {
                                                    new_score += 30;
                                                }

                                                if (to.SearchScoreIsSet(currentSearchID))
                                                {
                                                    old_score = to.SearchScoreGet(currentSearchID);
                                                }

                                                if (new_score < old_score)
                                                {
                                                    // shorter path to here found
                                                    to.traceBack = spot;
                                                    //if (q.Contains(to))
                                                    //    q.Remove(to);
                                                    to.SearchScoreSet(currentSearchID, new_score);
                                                    q.Enqueue(to, -(new_score + to.GetDistanceTo(dst) * heuristicsFactor));
                                                    new_found++;
                                                }
                                            }
                                            else
                                            {
                                                // woot! I added a new one and it is not connected!?!?
                                                //PathGraph.Log("/cry");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            {
                TimeSpan ts = DateTime.Now.Subtract(pre);
                int      t  = ts.Seconds * 1000 + ts.Milliseconds;
                if (t == 0)
                {
                    t = 1;
                }
                Log("  search failed. " + (count * 1000) / t + " steps/s");
            }
            return(BestSpot); // :(
        }
示例#13
0
        private Spot search(Spot src, Spot dst, Location realDst, float minHowClose, bool AllowInvented, ILocationHeuristics locationHeuristics)
        {
            searchID++;
            int count = 0;
            Cancel = false;
            int prevCount = 0;
            int currentSearchID = searchID;
            float heuristicsFactor = 1.3f;
            System.DateTime pre = System.DateTime.Now;
            System.DateTime lastSpam = pre;

            // lowest first queue
            PriorityQueue<Spot, float> q = new PriorityQueue<Spot, float>(); // (new SpotSearchComparer(dst, score)); ;
            q.Enqueue(src, -src.GetDistanceTo(dst) * heuristicsFactor);
            Spot BestSpot = null;

            //Set<Spot> closed      = new Set<Spot>();
            //SpotData<float> score = new SpotData<float>();

            src.SearchScoreSet(currentSearchID, 0.0f);
            src.traceBack = null;

            // A* -ish algorithm

            while ((q.Count != 0) && !Cancel) // && count < 100000)
            {
                float prio;
                Spot spot = q.Dequeue(out prio); // .Value;
                //q.Remove(spot);

                if (spot.SearchIsClosed(currentSearchID))
                    continue;
                spot.SearchClose(currentSearchID);

                if (count % 100 == 0)
                {
                    System.TimeSpan span = System.DateTime.Now.Subtract(lastSpam);
                    if (span.Seconds != 0 && BestSpot != null)
                    {
                        Thread.Sleep(50); // give glider a chance to stop us
                        int t = span.Seconds * 1000 + span.Milliseconds;
                        if (t == 0)
                            Log("searching.... " + (count + 1) + " d: " + BestSpot.location.GetDistanceTo(realDst));
                        else
                            Log("searching.... " + (count + 1) + " d: " + BestSpot.location.GetDistanceTo(realDst) + " " + (count - prevCount) * 1000 / t + " steps/s");
                        lastSpam = System.DateTime.Now;
                        prevCount = count;
                    }
                }
                count++;

                if (spot.Equals(dst) || spot.location.GetDistanceTo(realDst) <= minHowClose)
                {
                    System.TimeSpan ts = System.DateTime.Now.Subtract(pre);
                    int t = ts.Seconds * 1000 + ts.Milliseconds;
                    /*if(t == 0)
                        Log("  search found the way there. " + count);
                    else
                        Log("  search found the way there. " + count + " " + (count * 1000) / t + " steps/s");
                      */
                    return spot; // got there
                }

                if (BestSpot == null ||
                   spot.location.GetDistanceTo(realDst) < BestSpot.location.GetDistanceTo(realDst))
                {
                    BestSpot = spot;
                }
                {
                    System.TimeSpan ts = System.DateTime.Now.Subtract(pre);
                    if (ts.Seconds > 120)
                    {
                        Log("too long search, aborting");
                        break;
                    }
                }

                float src_score = spot.SearchScoreGet(currentSearchID);

                //Console.WriteLine("inspect: " + c + " score " + s);

                int new_found = 0;
                List<Spot> ll = spot.GetPathsToSpots(this);
                foreach (Spot to in ll)
                {
                    //Spot to = GetSpot(l);

                    if (to != null && !to.IsBlocked() && !to.SearchIsClosed(currentSearchID))
                    {
                        float old_score = 1E30f;

                        float new_score = src_score + spot.GetDistanceTo(to) + TurnCost(spot, to);
                        if (locationHeuristics != null)
                            new_score += locationHeuristics.Score(spot.X, spot.Y, spot.Z);
                        if (to.GetFlag(Spot.FLAG_WATER))
                            new_score += 30;

                        if (to.SearchScoreIsSet(currentSearchID))
                        {
                            old_score = to.SearchScoreGet(currentSearchID);
                        }

                        if (new_score < old_score)
                        {
                            // shorter path to here found
                            to.traceBack = spot;
                            //if (q.Contains(to))
                            //   q.Remove(to); // very sloppy to not dequeue it
                            to.SearchScoreSet(currentSearchID, new_score);
                            q.Enqueue(to, -(new_score + to.GetDistanceTo(dst) * heuristicsFactor));
                            new_found++;
                        }
                    }

                    if (Cancel)
                        break;
                }

                //hmm search the triangles :p
                if (!spot.GetFlag(Spot.FLAG_MPQ_MAPPED))
                {

                    float PI = (float)Math.PI;

                    spot.SetFlag(Spot.FLAG_MPQ_MAPPED, true);
                    for (float a = 0; a < PI * 2; a += PI / 8)
                    {
                        float nx = spot.X + (float)Math.Sin(a) * WantedStepLength;// *0.8f;
                        float ny = spot.Y + (float)Math.Cos(a) * WantedStepLength;// *0.8f;
                        Spot s = GetSpot(nx, ny, spot.Z);
                        if (s == null)
                            s = FindClosestSpot(new Location(nx, ny, spot.Z), MinStepLength); // TODO: this is slow
                        if (s != null)
                        {
                            // hmm, they should already be connected
                        }
                        else
                        {
                            float new_z;
                            int flags;
                            // gogo find a new one
                            //Console.WriteLine("gogo brave new world");
                            if (!triangleWorld.FindStandableAt(nx, ny,
                                                               spot.Z - WantedStepLength * .75f, spot.Z + WantedStepLength * .75f,
                                                               out new_z, out flags, toonHeight, toonSize))
                            {
                                //Spot blocked = new Spot(nx, ny, spot.Z);
                                //blocked.SetFlag(Spot.FLAG_BLOCKED, true);
                                //AddSpot(blocked);
                            }
                            else
                            {
                                s = FindClosestSpot(new Location(nx, ny, new_z), MinStepLength);
                                if (s == null)
                                {
                                    if (!triangleWorld.IsStepBlocked(spot.X, spot.Y, spot.Z, nx, ny, new_z,
                                                                     toonHeight, toonSize, null))
                                    {

                                        Spot n = new Spot(nx, ny, new_z);
                                        Spot to = AddAndConnectSpot(n);
                                        if ((flags & ChunkedTriangleCollection.TriangleFlagDeepWater) != 0)
                                        {
                                            to.SetFlag(Spot.FLAG_WATER, true);
                                        }
                                        if (((flags & ChunkedTriangleCollection.TriangleFlagModel) != 0) ||
                                            ((flags & ChunkedTriangleCollection.TriangleFlagObject) != 0))
                                        {
                                            to.SetFlag(Spot.FLAG_INDOORS, true);
                                        }
                                        if (to != n || to.SearchIsClosed(currentSearchID))
                                        {
                                            // Console.WriteLine("/sigh");
                                        }
                                        else
                                        {
                                            // There should be a path from source to this one now
                                            if (spot.HasPathTo(to.location))
                                            {
                                                float old_score = 1E30f;

                                                float new_score = src_score + spot.GetDistanceTo(to) + TurnCost(spot, to);
                                                if (locationHeuristics != null)
                                                    new_score += locationHeuristics.Score(spot.X, spot.Y, spot.Z);

                                                if (to.GetFlag(Spot.FLAG_WATER))
                                                    new_score += 30;

                                                if (to.SearchScoreIsSet(currentSearchID))
                                                {
                                                    old_score = to.SearchScoreGet(currentSearchID);
                                                }

                                                if (new_score < old_score)
                                                {
                                                    // shorter path to here found
                                                    to.traceBack = spot;
                                                    //if (q.Contains(to))
                                                    //    q.Remove(to);
                                                    to.SearchScoreSet(currentSearchID, new_score);
                                                    q.Enqueue(to, -(new_score + to.GetDistanceTo(dst) * heuristicsFactor));
                                                    new_found++;
                                                }
                                            }
                                            else
                                            {
                                                // woot! I added a new one and it is not connected!?!?
                                                //Console.WriteLine("/cry");
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (Cancel)
                            break;
                    }

                }

            }
            {
                System.TimeSpan ts = System.DateTime.Now.Subtract(pre);
                int t = ts.Seconds * 1000 + ts.Milliseconds;
                if (t == 0)
                    t = 1;
                Log("  search failed. " + (count * 1000) / t + " steps/s");

            }
            return BestSpot; // :(
        }
示例#14
0
        public Path CreatePath(Location fromLoc, Location toLoc,
							   float howClose,
							   ILocationHeuristics locationHeuristics)
        {
            System.DateTime t = System.DateTime.Now;
            Spot from = FindClosestSpot(fromLoc, MinStepLength);
            Spot to = FindClosestSpot(toLoc, MinStepLength);

            if (from == null)
            {
                from = AddAndConnectSpot(new Spot(fromLoc));
            }
            if (to == null)
            {
                to = AddAndConnectSpot(new Spot(toLoc));
            }

            Path rawPath = CreatePath(from, to, to.location, howClose, true, locationHeuristics);

            if (rawPath != null && paint != null)
            {
                Location prev = null;
                for (int i = 0; i < rawPath.Count; i++)
                {
                    Location l = rawPath.Get(i);
                    paint.AddBigMarker(l.X, l.Y, l.Z);
                    if (prev != null)
                    {
                        paint.PaintPath(l.X, l.Y, l.Z + 3, prev.X, prev.Y, prev.Z + 3);
                    }
                    prev = l;
                }
            }
            Console.WriteLine("CreatePath took {0}", System.DateTime.Now.Subtract(t).Seconds);
            if (rawPath == null)
            {
                return null;
            }
            else
            {
                Location last = rawPath.GetLast();
                if (last.GetDistanceTo(toLoc) > 1.0)
                    rawPath.AddLast(toLoc);
            }
            return rawPath;
        }
示例#15
0
        public Path CreatePath(Spot from, Spot to, Location realDst,
							   float minHowClose, bool AllowInvented,
							   ILocationHeuristics locationHeuristics)
        {
            Spot newTo = search(from, to, realDst, minHowClose, AllowInvented,
                                locationHeuristics);
            if (newTo != null)
            {
                if (newTo.GetDistanceTo(to) <= minHowClose)
                {
                    List<Spot> path = FollowTraceBack(from, newTo);
                    return new Path(path);
                }
            }
            return null;
        }
示例#16
0
        private Spot Search(Spot fromSpot, Spot destinationSpot, float minHowClose, ILocationHeuristics locationHeuristics)
        {
            currentSearchStartSpot = fromSpot;
            searchID++;
            int currentSearchID = searchID;
            //searchProgress = new SearchProgress(fromSpot, destinationSpot, searchID);

            // lowest first queue
            PriorityQueue <Spot, float> prioritySpotQueue = new PriorityQueue <Spot, float>(); // (new SpotSearchComparer(dst, score)); ;

            prioritySpotQueue.Enqueue(fromSpot, -fromSpot.GetDistanceTo(destinationSpot) * heuristicsFactor);

            fromSpot.SearchScoreSet(currentSearchID, 0.0f);
            fromSpot.traceBack         = null;
            fromSpot.traceBackDistance = 0;

            // A* -ish algorithm
            while (prioritySpotQueue.Count != 0 && SearchEnabled)
            {
                if (sleepMSBetweenSpots != 0)
                {
                    Thread.Sleep(sleepMSBetweenSpots);
                }                                                                    // slow down the pathing

                float prio;
                currentSearchSpot = prioritySpotQueue.Dequeue(out prio); // .Value;

                // force the world to be loaded
                TriangleCollection tc = triangleWorld.GetChunkAt(currentSearchSpot.X, currentSearchSpot.Y);

                if (currentSearchSpot.SearchIsClosed(currentSearchID))
                {
                    continue;
                }
                currentSearchSpot.SearchClose(currentSearchID);

                //update status
                //if (!searchProgress.CheckProgress(currentSearchSpot)) { break; }

                // are we there?
                if (currentSearchSpot.location.GetDistanceTo(destinationSpot.location) <= minHowClose)
                {
                    return(currentSearchSpot); // got there
                }

                //Find spots to link to
                CreateSpotsAroundSpot(currentSearchSpot);

                //score each spot around the current search spot and add them to the queue
                foreach (Spot spotLinkedToCurrent in currentSearchSpot.GetPathsToSpots(this))
                {
                    if (spotLinkedToCurrent != null && !spotLinkedToCurrent.IsBlocked() && !spotLinkedToCurrent.SearchIsClosed(currentSearchID))
                    {
                        ScoreSpot(spotLinkedToCurrent, destinationSpot, currentSearchID, locationHeuristics, prioritySpotQueue);
                    }
                }
            }

            //we ran out of spots to search
            //searchProgress.LogStatus("  search failed. ");

            return(null); // :(
        }