public static Tuple <DijkstraPoint, List <Rectangle3D> > FindRoute(Point3D point, Point3D target, Bitmap image) { Node n1 = Pathfinder.GetNode(Tibia_Path_Finder.Form1.beginx, Tibia_Path_Finder.Form1.beginy, 6); Node n2 = Pathfinder.GetNode(Tibia_Path_Finder.Form1.beginx, Tibia_Path_Finder.Form1.beginy, 7); Node beginNode = Pathfinder.GetNode(point.X, point.Y, point.Z); Node endNode = Pathfinder.GetNode(target.X, target.Y, target.Z); List <Rectangle3D> collisionBounds = null; DijkstraNode highresult = Dijkstra.FindRoute(beginNode, endNode, target); SpecialConnection connection = null; if (highresult != null) { collisionBounds = new List <Rectangle3D>(); while (highresult != null) { highresult.rect.Inflate(5, 5); collisionBounds.Add(new Rectangle3D(highresult.rect, highresult.node.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; } highresult = highresult.previous; } if (collisionBounds.Count == 0) { collisionBounds = null; } } return(new Tuple <DijkstraPoint, List <Rectangle3D> >(Dijkstra.FindRoute(image, point, target, collisionBounds, null, connection), collisionBounds)); }
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(); } } }
public Connection(Node node, SpecialConnection connection = null) { this.node = node; this.connection = connection; }
public static void LoadFromDatabase(string databaseFile) { SQLiteConnection conn; SQLiteCommand command; SQLiteDataReader reader; conn = new SQLiteConnection(String.Format("Data Source={0};Version=3;", databaseFile)); conn.Open(); // First add a list for each of the 16 floors for (int k = 0; k <= 15; k++) { nodes.Add(new List <Node>()); } // we keep a temporary <id,Node> map for adding connections Dictionary <int, Node> hnodeids = new Dictionary <int, Node>(); // Read the hierarchical nodes command = new SQLiteCommand("SELECT id,x,y,z,width,height FROM HierarchicalNode", conn); reader = command.ExecuteReader(); while (reader.Read()) { int id = reader.GetInt32(0); int x = reader.GetInt32(1); int y = reader.GetInt32(2); int z = reader.GetInt32(3); int width = reader.GetInt32(4); int height = reader.GetInt32(5); Node n = new Node(x, y, z, width, height); // add the node to the appropriate floor nodes[z].Add(n); // id-map hnodeids.Add(id, n); } Dictionary <int, SpecialConnection> connectionMap = new Dictionary <int, SpecialConnection>(); command = new SQLiteCommand("SELECT id, x1,y1,z1,x2,y2,z2,name,cost FROM SpecialConnections", conn); reader = command.ExecuteReader(); while (reader.Read()) { int id = reader.GetInt32(0); Coordinate source = new Coordinate(reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3)); Coordinate dest = new Coordinate(reader.GetInt32(4), reader.GetInt32(5), reader.GetInt32(6)); string name = reader[7].ToString(); int cost = reader.GetInt32(8); if (!specialConnection.ContainsKey(source.z)) { specialConnection.Add(source.z, new Dictionary <Tuple <int, int>, List <SpecialConnection> >()); } Tuple <int, int> tpl = new Tuple <int, int>(source.x, source.y); if (!specialConnection[source.z].ContainsKey(tpl)) { specialConnection[source.z].Add(tpl, new List <SpecialConnection>()); } SpecialConnection connection = new SpecialConnection { source = source, destination = dest, name = name, cost = cost }; specialConnection[source.z][tpl].Add(connection); connectionMap.Add(id, connection); } // Now read the hierarchical connections from the database command = new SQLiteCommand("SELECT nodeid,nodeid2, specialid FROM HierarchicalConnections", conn); reader = command.ExecuteReader(); while (reader.Read()) { int nodeid = reader.GetInt32(0); int nodeid2 = reader.GetInt32(1); int specialConnection = reader.GetInt32(2); SpecialConnection connection = null; if (specialConnection >= 0) { connection = connectionMap[specialConnection]; } // Add the connection to the nodes, using the id-map to extract the nodes hnodeids[nodeid].neighbors.Add(new Connection(hnodeids[nodeid2], connection)); } for (int i = 0; i <= 15; i++) { doors.Add(new Dictionary <Tuple <int, int>, string>()); } command = new SQLiteCommand("SELECT x,y,z,condition FROM Doors", conn); reader = command.ExecuteReader(); while (reader.Read()) { int x = reader.GetInt32(0); int y = reader.GetInt32(1); int z = reader.GetInt32(2); string condition = reader.IsDBNull(3) ? null : reader[3].ToString(); doors[z].Add(new Tuple <int, int>(x, y), condition); } }
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); }
public static void LoadFromDatabase(string databaseFile) { SQLiteConnection conn; SQLiteCommand command; SQLiteDataReader reader; conn = new SQLiteConnection(String.Format("Data Source={0};Version=3;", databaseFile)); conn.Open(); // First add a list for each of the 16 floors for (int k = 0; k <= 15; k++) { nodes.Add(new List<Node>()); } // we keep a temporary <id,Node> map for adding connections Dictionary<int, Node> hnodeids = new Dictionary<int, Node>(); // Read the hierarchical nodes command = new SQLiteCommand("SELECT id,x,y,z,width,height FROM HierarchicalNode", conn); reader = command.ExecuteReader(); while (reader.Read()) { int id = reader.GetInt32(0); int x = reader.GetInt32(1); int y = reader.GetInt32(2); int z = reader.GetInt32(3); int width = reader.GetInt32(4); int height = reader.GetInt32(5); Node n = new Node(x, y, z, width, height); // add the node to the appropriate floor nodes[z].Add(n); // id-map hnodeids.Add(id, n); } Dictionary<int, SpecialConnection> connectionMap = new Dictionary<int, SpecialConnection>(); command = new SQLiteCommand("SELECT id, x1,y1,z1,x2,y2,z2,name,cost FROM SpecialConnections", conn); reader = command.ExecuteReader(); while (reader.Read()) { int id = reader.GetInt32(0); Coordinate source = new Coordinate(reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3)); Coordinate dest = new Coordinate(reader.GetInt32(4), reader.GetInt32(5), reader.GetInt32(6)); string name = reader[7].ToString(); int cost = reader.GetInt32(8); if (!specialConnection.ContainsKey(source.z)) specialConnection.Add(source.z, new Dictionary<Tuple<int, int>, List<SpecialConnection>>()); Tuple<int, int> tpl = new Tuple<int, int>(source.x, source.y); if (!specialConnection[source.z].ContainsKey(tpl)) specialConnection[source.z].Add(tpl, new List<SpecialConnection>()); SpecialConnection connection = new SpecialConnection { source = source, destination = dest, name = name, cost = cost }; specialConnection[source.z][tpl].Add(connection); connectionMap.Add(id, connection); } // Now read the hierarchical connections from the database command = new SQLiteCommand("SELECT nodeid,nodeid2, specialid FROM HierarchicalConnections", conn); reader = command.ExecuteReader(); while (reader.Read()) { int nodeid = reader.GetInt32(0); int nodeid2 = reader.GetInt32(1); int specialConnection = reader.GetInt32(2); SpecialConnection connection = null; if (specialConnection >= 0) { connection = connectionMap[specialConnection]; } // Add the connection to the nodes, using the id-map to extract the nodes hnodeids[nodeid].neighbors.Add(new Connection(hnodeids[nodeid2], connection)); } for (int i = 0; i <= 15; i++) { doors.Add(new Dictionary<Tuple<int, int>, string>()); } command = new SQLiteCommand("SELECT x,y,z,condition FROM Doors", conn); reader = command.ExecuteReader(); while (reader.Read()) { int x = reader.GetInt32(0); int y = reader.GetInt32(1); int z = reader.GetInt32(2); string condition = reader.IsDBNull(3) ? null : reader[3].ToString(); doors[z].Add(new Tuple<int, int>(x, y), condition); } }
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; }