using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using Blizzard.HabboHotel.Users; namespace Blizzard.HabboHotel.Rooms { class Pathfinder6 { Point[] Movements; CompleteSquare[,] Squares; Room Room; RoomsData RoomData; RoomModel Model; Habbo User; int mapSizeX; int mapSizeY; private int vId; public Pathfinder6(Room Room, Habbo cUser) { this.Room = Room; this.RoomData = RoomsData.Rooms[cUser.CurrentRoomId]; this.Model = RoomData.GetRoomModel(); User = cUser; vId = User.VirtualId; if (Room == null || Model == null || User == null) { return; } InitMovements(0); mapSizeX = Model.MapSizeX; mapSizeY = Model.MapSizeY; Model.Area = (Model.MapSizeX * Model.MapSizeY); Squares = new CompleteSquare[mapSizeX, mapSizeY]; for (int x = 0; x < mapSizeX; x++) { for (int y = 0; y < mapSizeY; y++) { Squares[x, y] = new CompleteSquare(x, y); } } } private IEnumerable GetSquares() { for (int x = 0; x < mapSizeX; x++) { for (int y = 0; y < mapSizeY; y++) { yield return new Point(x, y); } } } private IEnumerable ValidMoves(int x, int y) { foreach (Point movePoint in Movements) { int newX = x + movePoint.X; int newY = y + movePoint.Y; if (ValidCoordinates(newX, newY) && IsSquareOpen(newX, newY, true) && !Room.IsItemOnXY(newX, newY)) { yield return new Point(newX, newY); } } } public List FindPath() { // Locate the user, and set the distance to zero int UserX = User.X; int UserY = User.Y; Squares[User.X, User.Y].DistanceSteps = 0; // Find all possible moves foreach (Point MainPoint in GetSquares()) { int x = MainPoint.X; int y = MainPoint.Y; Squares[x, y].DistanceSteps = Math.Abs(UserX - x) + Math.Abs(UserY - y); } // Locate the goal int goalX = User.GoalX; int goalY = User.GoalY; if (goalX == -1 || goalY == -1) { return null; } // Now trace the shortest possible route to our goal List Path = new List(); if (!Room.IsItemOnXY(User.GoalX, User.GoalY)) Path.Add(new Coord(User.GoalX, User.GoalY)); for (int i = 0; i < RoomData.GetRoomModel().Area; i++) { Point lowestPoint = Point.Empty; int lowest = 100; foreach (Point movePoint in ValidMoves(goalX, goalY)) { int count = Squares[movePoint.X, movePoint.Y].DistanceSteps; if (count < lowest) { lowest = count; lowestPoint.X = movePoint.X; lowestPoint.Y = movePoint.Y; } } if (lowest != 100) { Squares[lowestPoint.X, lowestPoint.Y].IsPath = true; if (Room.IsItemOnXY(lowestPoint.X, lowestPoint.Y)) return null; goalX = lowestPoint.X; goalY = lowestPoint.Y; Path.Add(new Coord(lowestPoint.X, lowestPoint.Y)); } else { break; } if (goalX == UserX && goalY == UserY) { break; } } if (Path.Count == 1) return null; if (Path.Count == 477) { while (true) { Coord C1 = Path[0]; Coord C2 = Path[1]; if (!C1.IsAround(C1.X, C1.Y, C2.X, C2.Y)) return null; else break; } } return Path; } private Boolean IsSquareOpen(int x, int y, Boolean CheckHeight) { if (Room.ValidTile(x, y, mapSizeX, mapSizeY)) { return true; } if (User.X == x && User.Y == y) { return true; } if (Room.IsItemOnXY(x, y)) return false; return true; } private Boolean ValidCoordinates(int x, int y) { if (x < 0 || y < 0 || x >= mapSizeX || y >= mapSizeY) { return false; } if (Room.IsItemOnXY(x, y)) return false; return true; } public void InitMovements(int movementCount) { if (movementCount == 4) { Movements = new Point[] { new Point(0, -1), new Point(1, 0), new Point(0, 1), new Point(-1, 0) }; } else { Movements = new Point[] { new Point(0, -1), new Point(1, 0), new Point(0, 1), new Point(-1, 0), new Point(-1, -1), new Point(1, -1), new Point(1, 1), new Point(-1, 1) }; } } } class CompleteSquare { public int x = 0; public int y = 0; int _distanceSteps = 100; public int DistanceSteps { get { return _distanceSteps; } set { _distanceSteps = value; } } bool _isPath = false; public bool IsPath { get { return _isPath; } set { _isPath = value; } } public CompleteSquare(int x, int y) { this.x = x; this.y = y; } } }