/// <summary> /// Returns a new location based on offsetted positions. /// </summary> /// <param name="loc">The location to use as offset.</param> /// <returns></returns> public Location Offset(Location loc) { return Offset(loc.X, loc.Y, loc.Z); }
public bool ContainsLocation(Location worldLocation) { if (worldLocation.Z != this.WorldLocation.Z) return false; int multiplier = this.Client.Addresses.MiniMap.WorldLocationMultiplier; return this.MiniMapLocation == new Objects.Location(worldLocation.X / multiplier, worldLocation.Y / multiplier, worldLocation.Z); }
/// <summary> /// Gets whether this location is in walkable range. /// </summary> /// <param name="loc">The location to compare to.</param> /// <returns></returns> public bool IsInRange(Location loc) { if (this.Z != loc.Z) return false; if (Math.Abs(this.X - loc.X) > 110 || Math.Abs(this.Y - loc.Y) > 110) return false; return true; }
/// <summary> /// Checks whether another location is visible from this location. /// </summary> /// <param name="loc">The other location to check.</param> /// <returns></returns> public bool IsOnScreen(Location loc) { if (this.Z != loc.Z) return false; return Math.Abs(this.X - loc.X) <= 7 && Math.Abs(this.Y - loc.Y) <= 5; }
/// <summary> /// Checks whether this location is non-diagonally adjacent to another location. /// </summary> /// <param name="loc">The location to compare to.</param> /// <returns></returns> public bool IsAdjacentNonDiagonalOnly(Location loc) { int x = Math.Abs(this.X - loc.X), y = Math.Abs(this.Y - loc.Y); return this.Z == loc.Z && (x == 1 ^ y == 1) && (x == 0 ^ y == 0); }
/// <summary> /// Checks whether this location is adjacent (1 sqm away, regardless of direction) to another location. /// </summary> /// <param name="loc">The location to compare to.</param> /// <returns></returns> public bool IsAdjacentTo(Location loc) { return this.Z == loc.Z && Math.Max(Math.Abs(this.X - loc.X), Math.Abs(this.Y - loc.Y)) <= 1; }
/// <summary> /// Gets a collection of pathfinder nodes to a given location. Returns 0 elements if unsuccessful. /// </summary> /// <param name="c">The client to perform the operation on.</param> /// <param name="loc">The location to reach.</param> /// <param name="tiles">A list of tiles to use for pathfinding.</param> /// <param name="pathFinder">The pathfinder to use.</param> /// <param name="considerPlayerWalkable">Whether to consider the player as walkable.</param> /// <param name="considerCreatureOnLocationWalkable">Whether to consider any creatures on the target location as walkable.</param> /// <returns></returns> public IEnumerable<Objects.PathFinder.Node> GetTilesToLocation(Objects.Client c, Location loc, Map.TileCollection tiles, Objects.PathFinder pathFinder, bool considerPlayerWalkable = false, bool considerCreatureOnLocationWalkable = false) { if (pathFinder == null) return Enumerable.Empty<Objects.PathFinder.Node>(); //return pathFinder. if (!this.IsOnScreen(c.Player.Location)) return Enumerable.Empty<Objects.PathFinder.Node>(); uint playerId = c.Player.ID; Map.Tile playerTile = tiles.GetTile(count: playerId); Map.Tile fromTile = tiles.GetTile(this); Map.Tile targetTile = tiles.GetTile(loc); if (playerTile == null || fromTile == null || targetTile == null) return Enumerable.Empty<Objects.PathFinder.Node>(); // check if target tile is walkable if (!targetTile.IsWalkable() && (!considerPlayerWalkable || targetTile != playerTile)) return Enumerable.Empty<Objects.PathFinder.Node>(); if (fromTile == targetTile) return Enumerable.AsEnumerable(new Objects.PathFinder.Node[] { new Objects.PathFinder.Node() }); lock (pathFinder) { pathFinder.ResetGrid(); foreach (Map.Tile tile in tiles.GetTiles()) { if (tile == null) continue; if ((considerPlayerWalkable && tile == playerTile) || tile.IsWalkable()) pathFinder.Grid[tile.MemoryLocation.X, tile.MemoryLocation.Y] = 1; else pathFinder.Grid[tile.MemoryLocation.X, tile.MemoryLocation.Y] = (byte)Enums.MiniMapSpeedValues.Unwalkable; } pathFinder.Grid[fromTile.MemoryLocation.X, fromTile.MemoryLocation.Y] = 1; return pathFinder.FindPath(fromTile.MemoryLocation, targetTile.MemoryLocation); } }
/// <summary> /// Checks whether this location can reach another location. /// </summary> /// <param name="c">The client to perform the operation on.</param> /// <param name="loc">The location to reach.</param> /// <returns></returns> public bool CanReachLocation(Objects.Client c, Location loc) { return this.CanReachLocation(c, loc, c.Map.GetTilesOnScreen()); }
public bool Equals(Location other) { if ((object)this == null && (object)other == null) return true; return other.X == this.X && other.Y == this.Y && other.Z == this.Z; }
/// <summary> /// Gets a collection of pathfinder nodes to a given location. Returns 0 elements if unsuccessful. /// </summary> /// <param name="c">The client to perform the operation on.</param> /// <param name="loc">The location to reach.</param> /// <param name="tiles">A list of tiles to use for pathfinding.</param> /// <param name="considerPlayerWalkable">Whether to consider the player as walkable.</param> /// <param name="considerCreatureOnLocationWalkable">Whether to consider any creatures on the target location as walkable.</param> /// <returns></returns> public IEnumerable<Objects.PathFinder.Node> GetTilesToLocation(Objects.Client c, Location loc, Map.TileCollection tiles, bool considerPlayerWalkable = false, bool considerCreatureOnLocationWalkable = false) { return this.GetTilesToLocation(c, loc, tiles, c.PathFinder, considerPlayerWalkable, considerCreatureOnLocationWalkable); }
/// <summary> /// Returns the distance between two locations. Does not count tiles, only calculates a straight line. /// </summary> /// <param name="loc">The location to compare to.</param> /// <returns></returns> public double DistanceTo(Location loc) { int diffX = this.X - loc.X; int diffY = this.Y - loc.Y; return Math.Sqrt(diffX * diffX + diffY * diffY); }
/// <summary> /// Checks whether this location can reach another location. /// </summary> /// <param name="c">The client to perform the operation on.</param> /// <param name="loc">The location to reach.</param> /// <param name="tiles">A list of tiles to use for pathfinding.</param> /// <param name="pathFinder">The pathfinder to use.</param> /// <returns></returns> public bool CanReachLocation(Objects.Client c, Location loc, Map.TileCollection tiles, Objects.PathFinder pathFinder) { return this.GetTilesToLocation(c, loc, tiles, pathFinder, false).ToArray<Objects.PathFinder.Node>().Length > 0; }
/// <summary> /// Checks whether this location can reach another location. /// </summary> /// <param name="c">The client to perform the operation on.</param> /// <param name="loc">The location to reach.</param> /// <param name="tiles">A list of tiles to use for pathfinding.</param> /// <returns></returns> public bool CanReachLocation(Objects.Client c, Location loc, Map.TileCollection tiles) { return this.CanReachLocation(c, loc, tiles, c.LocalPathFinder); }
public Node[,] GetNodes(Location start, Location end) { if (!this.ContainsLocation(start)) throw new IndexOutOfRangeException("start is out of range"); if (!this.ContainsLocation(end)) throw new IndexOutOfRangeException("end is out of range"); Point indexStart = new Point(Math.Min(start.X - this.WorldLocation.X, end.X - this.WorldLocation.X), Math.Min(start.Y - this.WorldLocation.Y, end.Y - this.WorldLocation.Y)); Point indexEnd = new Point(Math.Max(start.X - this.WorldLocation.X, end.X - this.WorldLocation.X), Math.Max(start.Y - this.WorldLocation.Y, end.Y - this.WorldLocation.Y)); int lengthX = indexEnd.X - indexStart.X + 1, lengthY = indexEnd.Y - indexStart.Y + 1; var nodes = new Node[lengthX, lengthY]; int x, y; byte[] colors = null, speeds = null; if (this.IsInMemory) { for (x = 0; x < lengthX; x++) { // read the entire y axis in one go colors = this.Client.Memory.ReadBytes(this.Address + this.Client.Addresses.MiniMap.Distances.Colors + indexStart.X + x, lengthY); speeds = this.Client.Memory.ReadBytes(this.Address + this.Client.Addresses.MiniMap.Distances.TileSpeeds + indexStart.X + x, lengthY); for (y = 0; y < lengthY; y++) { nodes[x, y] = new Node() { Color = colors[y], Speed = speeds[y] }; } } } else { using (BinaryReader reader = new BinaryReader(this.MapFile.OpenRead())) { for (x = 0; x < lengthX; x++) { // read the entire y axis in one go int index = this.GetIndex(indexStart.X + x, indexStart.Y); // set stream position to color index reader.BaseStream.Position = index; colors = reader.ReadBytes(lengthY); // set stream position to speed index reader.BaseStream.Position = this.Client.Addresses.MiniMap.DataLength + index; speeds = reader.ReadBytes(lengthY); for (y = 0; y < lengthY; y++) { nodes[x, y] = new Node() { Color = colors[y], Speed = speeds[y] }; } } } } return nodes; }
/// <summary> /// Checks whether this location is diagonally adjacent to another location. /// </summary> /// <param name="loc">The location to compare to.</param> /// <returns></returns> public bool IsAdjacentDiagonalOnly(Location loc) { return this.Z == loc.Z && Math.Abs(this.X - loc.X) == 1 && Math.Abs(this.Y - loc.Y) == 1; }
public void UpdateLocations() { if (!this.IsInMemory) return; this.MiniMapLocation = new Location(this.Client.Memory.ReadUInt16(this.Address + this.Client.Addresses.MiniMap.Distances.X), this.Client.Memory.ReadUInt16(this.Address + this.Client.Addresses.MiniMap.Distances.Y), this.Client.Memory.ReadByte(this.Address + this.Client.Addresses.MiniMap.Distances.Z)); int multiplier = this.Client.Addresses.MiniMap.WorldLocationMultiplier; this.WorldLocation = new Location(this.MiniMapLocation.X * multiplier, this.MiniMapLocation.Y * multiplier, this.MiniMapLocation.Z); }
public Node[,] GetNodes(Location start, Location end) { if (!this.ContainsLocation(start)) throw new IndexOutOfRangeException("start is out of range"); if (!this.ContainsLocation(end)) throw new IndexOutOfRangeException("end is out of range"); Point indexStart = new Point(Math.Min(start.X - this.WorldLocation.X, end.X - this.WorldLocation.X), Math.Min(start.Y - this.WorldLocation.Y, end.Y - this.WorldLocation.Y)); Point indexEnd = new Point(Math.Max(start.X - this.WorldLocation.X, end.X - this.WorldLocation.X), Math.Max(start.Y - this.WorldLocation.Y, end.Y - this.WorldLocation.Y)); int lengthX = indexEnd.X - indexStart.X + 1, lengthY = indexEnd.Y - indexStart.Y + 1; var nodes = new Node[lengthX, lengthY]; for (int x = 0; x < lengthX; x++) { for (int y = 0; y < lengthY; y++) { nodes[x, y] = this.Nodes[indexStart.X + x, indexStart.Y + y]; } } return nodes; }