Example #1
0
        /// <summary>
        /// Gets a collection of pathfinder nodes to this creature. Returns an empty IEnumerable if unreachable.
        /// </summary>
        /// <param name="tileCollection">The list of tiles on screen to use for pathfinding.</param>
        /// <param name="pathFinder">The PathFinder object to use.</param>
        /// <returns></returns>
        public IEnumerable <Objects.PathFinder.Node> GetTilesToCreature(Map.TileCollection tileCollection,
                                                                        Objects.PathFinder pathFinder)
        {
            if (pathFinder == null)
            {
                return(Enumerable.Empty <Objects.PathFinder.Node>());
            }

            if (this.Location.IsAdjacentTo(this.Client.Player.Location))
            {
                return(new List <Objects.PathFinder.Node>()
                {
                    new Objects.PathFinder.Node()
                    {
                        X = 8, Y = 6
                    }
                });
            }
            if (!this.Location.IsOnScreen(this.Client.Player.Location))
            {
                return(Enumerable.Empty <Objects.PathFinder.Node>());
            }
            uint playerZ = this.Client.Player.Z;

            if (tileCollection.IsEmpty())
            {
                return(Enumerable.Empty <Objects.PathFinder.Node>());
            }
            Map.Tile playerTile   = tileCollection.GetTile(count: this.Client.Player.ID);
            Map.Tile creatureTile = tileCollection.GetTile(count: this.ID);
            if (playerTile == null || creatureTile == null)
            {
                return(Enumerable.Empty <Objects.PathFinder.Node>());
            }
            lock (pathFinder)
            {
                pathFinder.ResetGrid();
                foreach (Map.Tile tile in tileCollection.GetTiles())
                {
                    if (tile == null)
                    {
                        continue;
                    }

                    if (!tile.IsWalkable())
                    {
                        pathFinder.Grid[tile.MemoryLocation.X, tile.MemoryLocation.Y] = (byte)Enums.MiniMapSpeedValues.Unwalkable;
                    }
                    else
                    {
                        pathFinder.Grid[tile.MemoryLocation.X, tile.MemoryLocation.Y] = 1;
                    }
                }
                pathFinder.Grid[playerTile.MemoryLocation.X, playerTile.MemoryLocation.Y]     = 1;
                pathFinder.Grid[creatureTile.MemoryLocation.X, creatureTile.MemoryLocation.Y] = 1;
                return(pathFinder.FindPath(playerTile.MemoryLocation, creatureTile.MemoryLocation, true));
            }
        }
Example #2
0
        /// <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));
            }
        }
Example #3
0
        /// <summary>
        /// Checks whether this location can shoot another location.
        /// </summary>
        /// <param name="c">The client to perform the operation on.</param>
        /// <param name="loc">The location to shoot at.</param>
        /// <param name="tileCollection">The tiles on screen to use for pathfinding.</param>
        /// <returns></returns>
        public bool CanShootLocation(Objects.Client c, Objects.Location loc, Map.TileCollection tileCollection)
        {
            if (!this.IsOnScreen(loc))
            {
                return(false);
            }

            Map.Tile playerTile = tileCollection.GetTile(count: c.Player.ID);
            if (playerTile == null)
            {
                return(false);
            }
            Location playerLocation = playerTile.WorldLocation;

            if (playerLocation == loc)
            {
                return(true);
            }
            if (!playerLocation.IsOnScreen(this) || !playerLocation.IsOnScreen(loc))
            {
                return(false);
            }

            int    XSign     = (this.X > loc.X) ? 1 : -1;
            int    YSign     = (this.Y > loc.Y) ? 1 : -1;
            double XDistance = Math.Abs(this.X - loc.X);
            double YDistance = Math.Abs(this.Y - loc.Y);
            double max       = this.DistanceTo(loc);

            for (int i = 0; i <= max; i++)
            {
                Location check = this.Offset((int)Math.Ceiling(i * XDistance / max) * XSign,
                                             (int)Math.Ceiling(i * YDistance / max) * YSign);
                Map.Tile tile = tileCollection.GetTile(check);
                if (tile == null)
                {
                    return(false);
                }
                if (tile.ContainsObjectProperty(Enums.ObjectPropertiesFlags.IsMissileBlocking))
                {
                    return(false);
                }
            }
            return(true);
        }
Example #4
0
        public IEnumerable<Node> FindPath(Objects.Location start, Objects.Location end,
            Map.TileCollection tiles, Objects.MiniMap.MergedChunk mergedChunk,
            bool considerPlayerWalkable = false, bool considerCreatureOnLocationWalkable = false)
        {
            if (start == null || end == null || tiles == null || mergedChunk == null) return Enumerable.Empty<Node>();

            Objects.Location playerLoc = this.Client.Player.Location;
            Objects.Location topLeft = playerLoc.Offset(-Constants.Map.MemoryLocationCenterX, -Constants.Map.MemoryLocationCenterY),
                bottomRight = playerLoc.Offset(Constants.Map.MemoryLocationCenterX, Constants.Map.MemoryLocationCenterY);
            if (start.Z != end.Z ||
                start.X < topLeft.X || start.Y < topLeft.Y || start.X > bottomRight.X || start.Y > bottomRight.Y ||
                end.X < topLeft.X || end.Y < topLeft.Y || end.X > bottomRight.X || end.Y > bottomRight.Y)
            {
                return Enumerable.Empty<Node>();
            }

            var nodes = mergedChunk.GetNodes();
            Point gridLength = new Point(this.Grid.GetLength(0), this.Grid.GetLength(1)),
                nodeStartIndex = new Point(Math.Max(0, mergedChunk.WorldLocation.X - topLeft.X),
                    Math.Max(0, mergedChunk.WorldLocation.Y - topLeft.Y)),
                nodeEndIndex = new Point(Math.Min(gridLength.X, nodeStartIndex.X + nodes.GetLength(0)),
                    Math.Min(gridLength.Y, nodeStartIndex.Y + nodes.GetLength(1))),
                alignedStart = new Point(start.X - topLeft.X, start.Y - topLeft.Y),
                alignedEnd = new Point(end.X - topLeft.X, end.Y - topLeft.Y);

            lock (this.SyncObject)
            {
                // assign node values to pathfinder grid
                for (int x = 0; x < gridLength.X; x++)
                {
                    for (int y = 0; y < gridLength.Y; y++)
                    {
                        if (considerPlayerWalkable)
                        {
                            var tile = tiles.GetTile(topLeft.Offset(x, y));
                            if (tile != null && tile.ContainsCreature(this.Client.Player.ID))
                            {
                                this.Grid[x, y] = 1;
                                continue;
                            }
                        }

                        if (nodeStartIndex.X <= x && nodeEndIndex.X > x &&
                            nodeStartIndex.Y <= y && nodeEndIndex.Y > y)
                        {
                            Objects.MiniMap.Node node = nodes[x - nodeStartIndex.X, y - nodeStartIndex.Y];
                            this.Grid[x, y] = this.Client.MiniMap.IsTileWalkable(node.Color, node.Speed,
                                alignedEnd.X == x && alignedEnd.Y == y, this.ConsiderUnexploredAsUnwalkable) ?
                                node.Speed :
                                (byte)Enums.MiniMapSpeedValues.Unwalkable;
                        }
                        else
                        {
                            this.Grid[x, y] = (byte)Enums.MiniMapSpeedValues.Unwalkable;
                        }
                    }
                }

                return this.FindPath(alignedStart, alignedEnd);
            }
        }