Beispiel #1
0
        public List <ImprovedTile> FindPath(Entity source, BlockCoordinates target, double distance)
        {
            try
            {
                //new EmptyBlockedProvider(), // Instance of: IBockedProvider
                var blockAccess = new CachedBlockAccess(source.Level);

                var navigator = new ImprovedTileNavigator(
                    new LevelNavigator(source, blockAccess, distance, _blockCache),
                    new BlockDiagonalNeighborProvider(blockAccess, (int)Math.Truncate(source.KnownPosition.Y), _blockCache, source),                     // Instance of: INeighborProvider
                    new FastBlockDistanceAlgorithm(_blockCache)
                    );

                BlockCoordinates targetPos = target;
                BlockCoordinates sourcePos = (BlockCoordinates)source.KnownPosition;
                var from = new ImprovedTile(sourcePos.X, sourcePos.Z);
                var to   = new ImprovedTile(targetPos.X, targetPos.Z);

                return(navigator.Navigate(from, to).ToList() ?? new List <ImprovedTile>());
            }
            catch (Exception e)
            {
                Log.Error("Navigate", e);
            }

            return(new List <ImprovedTile>());
        }
Beispiel #2
0
        public int Calculate(ImprovedTile from, ImprovedTile to)
        {
            Vector3 vFrom = GetBlock(from).Coordinates;
            Vector3 vTo   = GetBlock(to).Coordinates;

            return((int)Vector3.Distance(vFrom, vTo));
        }
Beispiel #3
0
        public HashSet <ImprovedTile> Navigate(ImprovedTile from, ImprovedTile to)
        {
            var closed = new HashSet <ImprovedTile>();
            var open   = new HashSet <ImprovedTile> {
                from
            };

            var path = new Dictionary <ImprovedTile, ImprovedTile>();

            var gScore = new Hashtable();

            //var gScore = new Dictionary<Tile, int>();
            gScore[from] = 0;

            var fScore = new Hashtable();

            fScore[from] = Calculate(from, to);

            while (open.Any())
            {
                var current = open
                              .OrderBy(c => fScore[c])
                              .First();

                if (current == to)
                {
                    return(new HashSet <ImprovedTile>(ReconstructPath(path, current)));
                }

                open.Remove(current);
                closed.Add(current);

                foreach (ImprovedTile neighbor in neighborProvider.GetNeighbors(current))
                {
                    if (closed.Contains(neighbor) || blockedProvider.IsBlocked(neighbor))
                    {
                        continue;
                    }

                    var tentativeG = (int)gScore[current] + distanceAlgorithm.Calculate(current, neighbor);

                    if (!open.Contains(neighbor))
                    {
                        open.Add(neighbor);
                    }
                    else if (tentativeG >= (int)gScore[neighbor])
                    {
                        continue;
                    }

                    path[neighbor] = current;

                    gScore[neighbor] = tentativeG;
                    fScore[neighbor] = (int)gScore[neighbor] + Calculate(neighbor, to);
                }
            }

            return(null);
        }
Beispiel #4
0
        public Block GetBlock(ImprovedTile tile)
        {
            Block block;

            if (!_blockCache.TryGetValue(tile, out block))
            {
                return(null);
            }

            return(block);
        }
        private bool GetNextTile(out ImprovedTile next)
        {
            next = new ImprovedTile(0, 0);
            if (_currentPath.Count == 0)
            {
                return(false);
            }

            next = _currentPath.First();

            BlockCoordinates currPos = (BlockCoordinates)_entity.KnownPosition;

            if ((int)next.X == currPos.X && (int)next.Y == currPos.Z)
            {
                _currentPath.Remove(next);

                if (!GetNextTile(out next))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #6
0
        public bool IsBlocked(ImprovedTile coord)
        {
            Block block;

            if (!_blockCache.TryGetValue(coord, out block))
            {
                return(true);
            }

            if (block.IsSolid)
            {
                return(true);
            }

            if (Math.Abs(_entity.KnownPosition.Y - block.Coordinates.Y) > _entity.Height + 3)
            {
                return(true);
            }

            Vector2 entityPos = new Vector2(_entity.KnownPosition.X, _entity.KnownPosition.Z);
            Vector2 tilePos   = new Vector2(coord.X, coord.Y);

            if (Vector2.Distance(entityPos, tilePos) > _distance)
            {
                return(true);
            }

            BlockCoordinates blockCoordinates = block.Coordinates;

            if (IsObstructed(blockCoordinates))
            {
                return(true);
            }

            return(false);
        }
Beispiel #7
0
        public IEnumerable <ImprovedTile> GetNeighbors(ImprovedTile tile)
        {
            Block block;

            if (!_blockCache.TryGetValue(tile, out block))
            {
                block = _level.GetBlock(new BlockCoordinates(tile.X, _startY, tile.Y));
                _blockCache.Add(tile, block);
            }

            List <ImprovedTile> list = new List <ImprovedTile>();

            for (int index = 0; index < Neighbors.GetLength(0); ++index)
            {
                var item = new ImprovedTile(tile.X + Neighbors[index, 0], tile.Y + Neighbors[index, 1]);

                // Check for too high steps
                BlockCoordinates coord = new BlockCoordinates(item.X, block.Coordinates.Y, item.Y);
                if (_level.GetBlock(coord).IsSolid)
                {
                    Block blockUp = _level.GetBlock(coord + BlockCoordinates.Up);
                    if (blockUp.IsSolid)
                    {
                        // Can't jump
                        continue;
                    }

                    if (IsObstructed(blockUp.Coordinates))
                    {
                        continue;
                    }

                    _blockCache[item] = blockUp;
                }
                else
                {
                    var blockDown = _level.GetBlock(coord + BlockCoordinates.Down);
                    if (!blockDown.IsSolid)
                    {
                        if (!_level.GetBlock(coord + BlockCoordinates.Down + BlockCoordinates.Down).IsSolid)
                        {
                            // Will fall
                            continue;
                        }

                        if (IsObstructed(blockDown.Coordinates))
                        {
                            continue;
                        }

                        _blockCache[item] = blockDown;
                    }
                    else
                    {
                        if (IsObstructed(coord))
                        {
                            continue;
                        }

                        _blockCache[item] = _level.GetBlock(coord);
                    }
                }

                list.Add(item);
            }

            CheckDiagonals(block, list);

            return(list);
        }
Beispiel #8
0
        private IEnumerable <ImprovedTile> ReconstructPath(IDictionary <ImprovedTile, ImprovedTile> path, ImprovedTile current)
        {
            List <ImprovedTile> tileList = new List <ImprovedTile>
            {
                current
            };

            while (path.ContainsKey(current))
            {
                current = path[current];
                tileList.Add(current);
            }
            tileList.Reverse();
            tileList.RemoveAt(0);
            return(tileList);
        }
Beispiel #9
0
 private int Calculate(ImprovedTile from, ImprovedTile to)
 {
     return(Math.Abs(from.X - to.X) + Math.Abs(from.Y - to.Y));
 }