コード例 #1
0
        public static DijkstraPoint GetMinimum(List <DijkstraPoint> list)
        {
            double        minValue = double.MaxValue;
            DijkstraPoint min      = null;

            foreach (var node in list)
            {
                double nodeValue = node.cost;
                if (nodeValue < minValue)
                {
                    min      = node;
                    minValue = nodeValue;
                }
            }
            return(min);
        }
コード例 #2
0
 public void DrawPath(Graphics gr, TibiaPath path)
 {
     if (path.begin.z == mapCoordinate.z)
     {
         List <Point>  points = new List <Point>();
         DijkstraPoint node   = path.path;
         while (node != null)
         {
             points.Add(new Point(convertx(node.point.X), converty(node.point.Y)));
             node = node.previous;
         }
         if (points.Count <= 1)
         {
             return;
         }
         gr.DrawLines(UIManager.pathPen, points.ToArray());
     }
 }
コード例 #3
0
ファイル: Pathfinder.cs プロジェクト: villor/Tibialyzer
 public DijkstraPoint(DijkstraPoint previous, Point point, double cost)
 {
     this.previous = previous;
     this.cost = cost;
     this.point = point;
 }
コード例 #4
0
        public void UpdateMap(bool periodicUpdate = false)
        {
            lock (mapBoxLock) {
                int  PlayerX = 0, PlayerY = 0, PlayerZ = 0;
                bool recomputeRoute = true;

                if (targetCoordinate != null)
                {
                    MemoryReader.UpdateBattleList();
                    PlayerX = MemoryReader.X;
                    PlayerY = MemoryReader.Y;
                    PlayerZ = MemoryReader.Z;

                    Point3D playerCoordinate = new Point3D(PlayerX, PlayerY, PlayerZ);
                    if (previousCoordinate != playerCoordinate)
                    {
                        previousCoordinate = playerCoordinate;
                        mapCoordinate      = new Coordinate(PlayerX, PlayerY, PlayerZ);
                    }
                    else
                    {
                        if (FakePlayerData.X >= 0)
                        {
                            PlayerX = FakePlayerData.X;
                            PlayerY = FakePlayerData.Y;
                            PlayerZ = FakePlayerData.Z;

                            mapCoordinate = new Coordinate(PlayerX, PlayerY, PlayerZ);

                            FakePlayerData = new Point3D(-1, -1, -1);
                        }
                        else
                        {
                            if (periodicUpdate)
                            {
                                return;
                            }
                            recomputeRoute = false;
                        }
                    }
                }
                if (beginCoordinate == null)
                {
                    beginCoordinate = new Coordinate(mapCoordinate);
                    beginWidth      = sourceWidth;
                }
                if (beginCoordinate.x == Coordinate.MaxWidth / 2 && beginCoordinate.y == Coordinate.MaxHeight / 2 && beginCoordinate.z == 7)
                {
                    Image oldImage = this.Image;
                    this.Image = StyleManager.GetImage("nomapavailable.png");
                    if (oldImage != StyleManager.GetImage("nomapavailable.png") && oldImage != null)
                    {
                        oldImage.Dispose();
                    }
                    this.SizeMode = PictureBoxSizeMode.Zoom;
                    return;
                }
                if (mapCoordinate.z < 0)
                {
                    mapCoordinate.z = 0;
                }
                else if (mapCoordinate.z >= StorageManager.mapFilesCount)
                {
                    mapCoordinate.z = StorageManager.mapFilesCount - 1;
                }
                if (mapCoordinate.x - sourceWidth / 2 < 0)
                {
                    mapCoordinate.x = sourceWidth / 2;
                }
                if (mapCoordinate.x + sourceWidth / 2 > Coordinate.MaxWidth)
                {
                    mapCoordinate.x = Coordinate.MaxWidth - sourceWidth / 2;
                }
                if (mapCoordinate.y - sourceWidth / 2 < 0)
                {
                    mapCoordinate.y = sourceWidth / 2;
                }
                if (mapCoordinate.y + sourceWidth / 2 > Coordinate.MaxHeight)
                {
                    mapCoordinate.y = Coordinate.MaxHeight - sourceWidth / 2;
                }

                Image image;
                if (mapCoordinate.z == zCoordinate)
                {
                    image = map != null?map.GetImage() : mapImage;
                }
                else
                {
                    Map m = StorageManager.getMap(mapCoordinate.z);
                    if (otherMap != null && m != otherMap)
                    {
                        otherMap.Dispose();
                    }
                    otherMap = m;
                    image    = m.GetImage();
                }

                lock (image) {
                    sourceWidth = Math.Min(Math.Max(sourceWidth, minWidth), maxWidth);
                    Rectangle sourceRectangle = new Rectangle(mapCoordinate.x - sourceWidth / 2, mapCoordinate.y - sourceWidth / 2, sourceWidth, sourceWidth);
                    Bitmap    bitmap          = new Bitmap(this.Width, this.Height);
                    using (Graphics gr = Graphics.FromImage(bitmap)) {
                        gr.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height), sourceRectangle, GraphicsUnit.Pixel);

                        if (targetCoordinate != null && recomputeRoute)
                        {
                            Coordinate beginCoordinate = new Coordinate(PlayerX, PlayerY, PlayerZ);

                            Node beginNode = Pathfinder.GetNode(beginCoordinate.x, beginCoordinate.y, beginCoordinate.z);
                            Node endNode   = Pathfinder.GetNode(targetCoordinate.x, targetCoordinate.y, targetCoordinate.z);

                            List <Rectangle3D> collisionBounds = null;
                            DijkstraNode       highresult      = Dijkstra.FindRoute(beginNode, endNode, new Point3D(targetCoordinate), previousResult);
                            previousResult = highresult;
                            SpecialConnection connection = null;

                            nextConnectionPoint = new Point3D(-1, -1, -1);
                            nextImportantTarget = null;
                            nextTarget          = "Head to the destination.";
                            if (highresult != null)
                            {
                                collisionBounds = new List <Rectangle3D>();
                                while (highresult != null)
                                {
                                    highresult.rect.Inflate(5, 5);
                                    collisionBounds.Add(new Rectangle3D(highresult.rect, highresult.node.z));

                                    /*if (highresult.node.z == beginCoordinate.z) {
                                     *  Point tl = new Point(convertx(highresult.rect.X), converty(highresult.rect.Y));
                                     *  Point tr = new Point(convertx(highresult.rect.X + highresult.rect.Width), converty(highresult.rect.Y + highresult.rect.Height));
                                     *  gr.DrawRectangle(Pens.Yellow, new Rectangle(tl.X, tl.Y, (tr.X - tl.X), (tr.Y - tl.Y)));
                                     * }*/
                                    if (highresult.connection.connection != null)
                                    {
                                        connection = highresult.connection.connection;
                                        if (connection.name.Equals("stairs", StringComparison.InvariantCultureIgnoreCase))
                                        {
                                            nextTarget = connection.destination.z > connection.source.z ? "Go down the stairs." : "Go up the stairs.";
                                        }
                                        else if (connection.name.Equals("levitate", StringComparison.InvariantCultureIgnoreCase))
                                        {
                                            nextTarget = connection.destination.z > connection.source.z ? "Levitate down." : "Levitate up.";
                                        }
                                        else
                                        {
                                            nextImportantTarget = String.Format("Take the {0}.", connection.name);
                                            nextTarget          = null;
                                        }
                                        nextConnectionPoint = new Point3D(connection.destination.x, connection.destination.y, connection.destination.z);
                                    }
                                    highresult = highresult.previous;
                                }
                                if (collisionBounds.Count == 0)
                                {
                                    collisionBounds = null;
                                }
                            }

                            Map           m      = StorageManager.getMap(beginCoordinate.z);
                            DijkstraPoint result = Dijkstra.FindRoute(image as Bitmap, new Point3D(beginCoordinate), new Point3D(targetCoordinate), collisionBounds, null, connection);
                            if (result != null)
                            {
                                playerPath       = new TibiaPath();
                                playerPath.path  = result;
                                playerPath.begin = beginCoordinate;
                                playerPath.end   = targetCoordinate;
                                DrawPath(gr, playerPath);
                            }
                        }
                        else if (!recomputeRoute && playerPath != null)
                        {
                            DrawPath(gr, playerPath);
                        }

                        foreach (TibiaPath path in paths)
                        {
                            DrawPath(gr, path);
                        }

                        foreach (Target target in targets)
                        {
                            if (target.coordinate.z == mapCoordinate.z)
                            {
                                int x = target.coordinate.x - (mapCoordinate.x - sourceWidth / 2);
                                int y = target.coordinate.y - (mapCoordinate.y - sourceWidth / 2);
                                if (x >= 0 && y >= 0 && x < sourceWidth && y < sourceWidth)
                                {
                                    x = (int)((double)x / sourceWidth * bitmap.Width);
                                    y = (int)((double)y / sourceWidth * bitmap.Height);
                                    lock (target.image) {
                                        int targetWidth = (int)((double)target.size / target.image.Height * target.image.Width);
                                        gr.DrawImage(target.image, new Rectangle(x - targetWidth, y - target.size, targetWidth * 2, target.size * 2));
                                    }
                                }
                            }
                        }
                    }
                    Image oldImage = this.Image;
                    this.Image = bitmap;
                    if (oldImage != null)
                    {
                        oldImage.Dispose();
                    }
                }
                if (MapUpdated != null)
                {
                    MapUpdated();
                }
            }
        }
コード例 #5
0
ファイル: MapPictureBox.cs プロジェクト: adgonz90/Tibialyzer
        public void UpdateMap()
        {
            if (beginCoordinate == null)
            {
                beginCoordinate = new Coordinate(mapCoordinate);
                beginWidth      = sourceWidth;
            }
            if (beginCoordinate.x == Coordinate.MaxWidth / 2 && beginCoordinate.y == Coordinate.MaxHeight / 2 && beginCoordinate.z == 7)
            {
                if (this.Image != StyleManager.GetImage("nomapavailable.png") && this.Image != null)
                {
                    this.Image.Dispose();
                }
                this.Image    = StyleManager.GetImage("nomapavailable.png");
                this.SizeMode = PictureBoxSizeMode.Zoom;
                return;
            }
            if (mapCoordinate.z < 0)
            {
                mapCoordinate.z = 0;
            }
            else if (mapCoordinate.z >= StorageManager.mapFilesCount)
            {
                mapCoordinate.z = StorageManager.mapFilesCount - 1;
            }
            if (mapCoordinate.x - sourceWidth / 2 < 0)
            {
                mapCoordinate.x = sourceWidth / 2;
            }
            if (mapCoordinate.x + sourceWidth / 2 > map.GetImage().Width)
            {
                mapCoordinate.x = map.GetImage().Width - sourceWidth / 2;
            }
            if (mapCoordinate.y - sourceWidth / 2 < 0)
            {
                mapCoordinate.y = sourceWidth / 2;
            }
            if (mapCoordinate.y + sourceWidth / 2 > map.GetImage().Height)
            {
                mapCoordinate.y = map.GetImage().Height - sourceWidth / 2;
            }

            sourceWidth = Math.Min(Math.Max(sourceWidth, minWidth), maxWidth);
            Rectangle sourceRectangle = new Rectangle(mapCoordinate.x - sourceWidth / 2, mapCoordinate.y - sourceWidth / 2, sourceWidth, sourceWidth);
            Bitmap    bitmap          = new Bitmap(this.Width, this.Height);

            using (Graphics gr = Graphics.FromImage(bitmap)) {
                if (mapCoordinate.z == zCoordinate)
                {
                    Image image = map != null?map.GetImage() : mapImage;

                    lock (image) {
                        gr.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height), sourceRectangle, GraphicsUnit.Pixel);
                    }
                }
                else
                {
                    Map m = StorageManager.getMap(mapCoordinate.z);
                    if (otherMap != null && m != otherMap)
                    {
                        otherMap.Dispose();
                    }
                    otherMap = m;
                    Image image = m.GetImage();
                    lock (image) {
                        gr.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height), sourceRectangle, GraphicsUnit.Pixel);
                    }
                }
                foreach (TibiaPath path in paths)
                {
                    if (path.begin.z == mapCoordinate.z)
                    {
                        List <Point>  points = new List <Point>();
                        DijkstraPoint node   = path.path;
                        while (node != null)
                        {
                            points.Add(new Point(convertx(node.point.X), converty(node.point.Y)));
                            node = node.previous;
                        }
                        gr.DrawLines(UIManager.pathPen, points.ToArray());
                    }
                }

                foreach (Target target in targets)
                {
                    if (target.coordinate.z == mapCoordinate.z)
                    {
                        int x = target.coordinate.x - (mapCoordinate.x - sourceWidth / 2);
                        int y = target.coordinate.y - (mapCoordinate.y - sourceWidth / 2);
                        if (x >= 0 && y >= 0 && x < sourceWidth && y < sourceWidth)
                        {
                            x = (int)((double)x / sourceWidth * bitmap.Width);
                            y = (int)((double)y / sourceWidth * bitmap.Height);
                            int targetWidth = (int)((double)target.size / target.image.Height * target.image.Width);
                            lock (target.image) {
                                gr.DrawImage(target.image, new Rectangle(x - targetWidth, y - target.size, targetWidth * 2, target.size * 2));
                            }
                        }
                    }
                }
            }
            if (this.Image != null)
            {
                this.Image.Dispose();
            }
            this.Image = bitmap;
            if (MapUpdated != null)
            {
                MapUpdated();
            }
        }
コード例 #6
0
 public DijkstraPoint(DijkstraPoint previous, Point point, double cost)
 {
     this.previous = previous;
     this.cost     = cost;
     this.point    = point;
 }
コード例 #7
0
        public static DijkstraPoint FindRoute(Bitmap mapImage, Point start, Point end, List <Rectangle> bounds, List <Color> additionalWalkableColors)
        {
            if (!isWalkable(mapImage.GetPixel(start.X, start.Y), additionalWalkableColors))
            {
                throw new Exception(String.Format("Point ({0},{1}) is not walkable.", start.X, start.Y));
            }

            List <DijkstraPoint> openSet = new List <DijkstraPoint> {
                new DijkstraPoint(null, start, 0)
            };
            HashSet <Point> closedSet       = new HashSet <Point>();
            DijkstraPoint   closestNode     = null;
            double          closestDistance = double.MaxValue;


            while (openSet.Count > 0)
            {
                DijkstraPoint current = GetMinimum(openSet);
                if (current.point.Equals(end))
                {
                    return(current);
                }
                if (Distance(current.point, end) < closestDistance)
                {
                    closestDistance = Distance(current.point, end);
                    closestNode     = current;
                }

                openSet.Remove(current);
                closedSet.Add(current.point);

                //check all the neighbors of the current point
                foreach (Point p in getNeighbors(current.point))
                {
                    if (closedSet.Contains(p))
                    {
                        continue;
                    }
                    if (!isWalkable(mapImage.GetPixel(p.X, p.Y), additionalWalkableColors))
                    {
                        closedSet.Add(p);
                        continue;
                    }
                    if (bounds != null)
                    {
                        bool found = false;
                        foreach (Rectangle bound in bounds)
                        {
                            if (bound.Contains(p))
                            {
                                found = true;
                                break;
                            }
                        }
                        if (!found)
                        {
                            continue;
                        }
                    }
                    double newCost = current.cost + Distance(current.point, p);

                    DijkstraPoint neighborPoint = openSet.Find(o => o.point == p);
                    if (neighborPoint == null)
                    {
                        openSet.Add(new DijkstraPoint(current, p, newCost));
                    }
                    else if (neighborPoint.cost < newCost)
                    {
                        continue;
                    }
                    else
                    {
                        openSet.Remove(neighborPoint);
                        openSet.Add(new DijkstraPoint(current, p, newCost));
                    }
                }
            }
            if (closestDistance > 5 && bounds != null)
            {
                return(FindRoute(mapImage, start, end, null, additionalWalkableColors));
            }
            return(closestNode);
        }
コード例 #8
0
ファイル: Pathfinder.cs プロジェクト: umdez/Tibialyzer
        public static DijkstraPoint FindRoute(Bitmap mapImage, Point3D start, Point3D end, List <Rectangle3D> bounds, List <Color> additionalWalkableColors, SpecialConnection connection = null)
        {
            Point3D connectionPoint = connection == null ? new Point3D(-1, -1, 0) : (connection.source.z == start.Z ? new Point3D(connection.source) : new Point3D(connection.destination));

            List <DijkstraPoint> openSet = new List <DijkstraPoint> {
                new DijkstraPoint(null, start, 0)
            };
            HashSet <Point3D> closedSet       = new HashSet <Point3D>();
            DijkstraPoint     closestNode     = null;
            double            closestDistance = double.MaxValue;

            while (openSet.Count > 0)
            {
                DijkstraPoint current = GetMinimum(openSet);
                if (current.point.Equals(end))
                {
                    return(current);
                }
                if (Distance(current.point, end) < closestDistance)
                {
                    closestDistance = Distance(current.point, end);
                    closestNode     = current;
                }

                openSet.Remove(current);
                closedSet.Add(current.point);

                //check all the neighbors of the current point
                foreach (Point3D p in getNeighbors(current.point))
                {
                    double newCost = current.cost + Distance(current.point, p);

                    if (connection != null && p == connectionPoint)
                    {
                        return(new DijkstraPoint(current, p, newCost));
                    }

                    if (current.point.Z != start.Z)
                    {
                        continue;
                    }

                    if (closedSet.Contains(p))
                    {
                        continue;
                    }
                    if (!isWalkable(p, mapImage.GetPixel(p.X, p.Y)))
                    {
                        closedSet.Add(p);
                        continue;
                    }
                    if (bounds != null)
                    {
                        bool found = false;
                        foreach (Rectangle3D bound in bounds)
                        {
                            if (bound.Contains(p))
                            {
                                found = true;
                                break;
                            }
                        }
                        if (!found)
                        {
                            continue;
                        }
                    }

                    DijkstraPoint neighborPoint = openSet.Find(o => o.point == p);
                    if (neighborPoint == null)
                    {
                        openSet.Add(new DijkstraPoint(current, p, newCost));
                    }
                    else if (neighborPoint.cost < newCost)
                    {
                        continue;
                    }
                    else
                    {
                        openSet.Remove(neighborPoint);
                        openSet.Add(new DijkstraPoint(current, p, newCost));
                    }
                }
            }
            return(closestNode);
        }
コード例 #9
0
ファイル: UIManager.cs プロジェクト: villor/Tibialyzer
        public static MapPictureBox DrawRoute(Coordinate begin, Coordinate end, Size pictureBoxSize, Size minSize, Size maxSize, List <Color> additionalWalkableColors, List <Target> targetList = null)
        {
            if (end.x >= 0 && begin.z != end.z)
            {
                throw new Exception("Can't draw route with different z-coordinates");
            }
            Rectangle     sourceRectangle;
            MapPictureBox pictureBox = new MapPictureBox();

            if (pictureBoxSize.Width != 0)
            {
                pictureBox.Size = pictureBoxSize;
            }
            pictureBox.SizeMode = PictureBoxSizeMode.Zoom;

            if (targetList != null)
            {
                foreach (Target target in targetList)
                {
                    pictureBox.targets.Add(target);
                }
                if (end.x < 0)
                {
                    if (pictureBoxSize.Width == 0)
                    {
                        pictureBoxSize = new Size(Math.Min(Math.Max(end.z, minSize.Width), maxSize.Width),
                                                  Math.Min(Math.Max(end.z, minSize.Height), maxSize.Height));
                        pictureBox.Size = pictureBoxSize;
                    }
                    Map map = StorageManager.getMap(begin.z);
                    pictureBox.map           = map;
                    pictureBox.sourceWidth   = end.z;
                    pictureBox.mapCoordinate = new Coordinate(begin.x, begin.y, begin.z);
                    pictureBox.zCoordinate   = begin.z;
                    pictureBox.UpdateMap();
                    return(pictureBox);
                }
            }

            // First find the route at a high level
            Node beginNode = Pathfinder.GetNode(begin.x, begin.y, begin.z);
            Node endNode   = Pathfinder.GetNode(end.x, end.y, end.z);

            List <Rectangle> collisionBounds = null;
            DijkstraNode     highresult      = Dijkstra.FindRoute(beginNode, endNode);

            if (highresult != null)
            {
                collisionBounds = new List <Rectangle>();
                while (highresult != null)
                {
                    highresult.rect.Inflate(5, 5);
                    collisionBounds.Add(highresult.rect);
                    highresult = highresult.previous;
                }
                if (collisionBounds.Count == 0)
                {
                    collisionBounds = null;
                }
            }

            Map           m      = StorageManager.getMap(begin.z);
            DijkstraPoint result = Dijkstra.FindRoute(m.image, new Point(begin.x, begin.y), new Point(end.x, end.y), collisionBounds, additionalWalkableColors);

            if (result == null)
            {
                throw new Exception("Couldn't find route.");
            }

            // create a rectangle from the result
            double        minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue;
            DijkstraPoint node = result;

            while (node != null)
            {
                if (node.point.X < minX)
                {
                    minX = node.point.X;
                }
                if (node.point.Y < minY)
                {
                    minY = node.point.Y;
                }
                if (node.point.X > maxX)
                {
                    maxX = node.point.X;
                }
                if (node.point.Y > maxY)
                {
                    maxY = node.point.Y;
                }
                node = node.previous;
            }

            minX -= 10;
            minY -= 10;
            maxX += 10;
            maxY += 10;

            int size = (int)Math.Max(maxX - minX, maxY - minY);

            sourceRectangle = new Rectangle((int)minX, (int)minY, size, size);
            if (pictureBoxSize.Width == 0)
            {
                pictureBoxSize = new Size(Math.Min(Math.Max(sourceRectangle.Width, minSize.Width), maxSize.Width),
                                          Math.Min(Math.Max(sourceRectangle.Height, minSize.Height), maxSize.Height));
                pictureBox.Size = pictureBoxSize;
            }
            TibiaPath path = new TibiaPath();

            path.begin = new Coordinate(begin);
            path.end   = new Coordinate(end);
            path.path  = result;
            pictureBox.paths.Add(path);

            pictureBox.map           = m;
            pictureBox.sourceWidth   = size;
            pictureBox.mapCoordinate = new Coordinate(sourceRectangle.X + sourceRectangle.Width / 2, sourceRectangle.Y + sourceRectangle.Height / 2, begin.z);
            pictureBox.zCoordinate   = begin.z;
            pictureBox.UpdateMap();

            return(pictureBox);
        }