public Point FindSpawnPosition(RoamingPresence presence)
        {
            var homeRange = presence.Flocks.Max(f => f.HomeRange);
            var rangeMax  = homeRange * 2;

            var walkableArea = _zone.FindWalkableArea(presence.Area, rangeMax * rangeMax);

            return(walkableArea.RandomElement());
        }
Beispiel #2
0
        public Point FindNextRoamingPosition(RoamingPresence presence)
        {
            var homeRange = presence.Flocks.Max(f => f.HomeRange);
            var rangeMax  = homeRange * 2;

            var length  = rangeMax * MathHelper.PI2;
            var radians = 1.0 / length;
            var zigzag  = radians * 4;

            var pq = new PriorityQueue <Node>(rangeMax * rangeMax * 2);

            var startNode = new Node(presence.CurrentRoamingPosition);

            pq.Enqueue(startNode);

            var closed = new Dictionary <int, bool> {
                { startNode.GetHashCode(), true }
            };

            var randomRadians = FastRandom.NextDouble(-zigzag, zigzag);

            _direction += randomRadians;
            MathHelper.NormalizeDirection(ref _direction);

            var farPosition = startNode.position.OffsetInDirection(_direction, rangeMax);

            Node currentNode;

            while (pq.TryDequeue(out currentNode))
            {
                var distance = startNode.Distance(currentNode);
                if (distance >= homeRange)
                {
                    _direction = startNode.position.DirectionTo(currentNode.position);

                    if (!IsRoamingPosition(currentNode.position))
                    {
                        _direction += radians;
                        MathHelper.NormalizeDirection(ref _direction);
                    }

                    return(currentNode.position);
                }

                for (var i = 0; i < 8; i++)
                {
                    var neighbor = new Node(_n[i, 0] + currentNode.position.X, _n[i, 1] + currentNode.position.Y);

                    if (closed.ContainsKey(neighbor.GetHashCode()))
                    {
                        continue;
                    }

                    closed[neighbor.GetHashCode()] = true;

                    if (!_zone.IsWalkableForNpc(neighbor.position))
                    {
                        continue;
                    }

                    neighbor.cost = CalculateCost(farPosition, neighbor.position);
                    pq.Enqueue(neighbor);
                }
            }

            return(startNode.position);
        }
Beispiel #3
0
        public Point FindSpawnPosition(RoamingPresence presence)
        {
            var point = _zone.SafeSpawnPoints.GetAll().RandomElement();

            return(point.Location);
        }
        public Point FindNextRoamingPosition(RoamingPresence presence)
        {
            var minSlope     = presence.Flocks.GetMembers().Min(m => m.Slope);
            var maxHomeRange = presence.Flocks.Max(f => f.HomeRange);
            var range        = new IntRange((int)(maxHomeRange * 1.1), (int)(maxHomeRange * 1.5));

            var queue     = new PriorityQueue <Node>(500);
            var startNode = new Node(presence.CurrentRoamingPosition);

            queue.Enqueue(startNode);

            var closed = new HashSet <Point> {
                presence.CurrentRoamingPosition
            };

            if (FastRandom.NextDouble() < 0.3)
            {
                _direction += FastRandom.NextDouble(0, 0.25) - 0.25;
                MathHelper.NormalizeDirection(ref _direction);
            }

            var farPosition = startNode.location.ToPosition().OffsetInDirection(_direction, FastRandom.NextDouble(range.Min, range.Max));

//            _zone.CreateAlignedDebugBeam(BeamType.red_20sec,farPosition);

            Node current;

            while (queue.TryDequeue(out current))
            {
                var d = startNode.location.Distance(current.location);
                if (d > range.Min)
                {
                    _direction = startNode.location.DirectionTo(current.location);
//                    _zone.CreateAlignedDebugBeam(BeamType.green_20sec,current.location.ToPosition());
                    return(current.location);
                }

                foreach (var np in current.location.GetNeighbours())
                {
                    if (closed.Contains(np))
                    {
                        continue;
                    }

                    closed.Add(np);

                    if (!_zone.IsWalkableForNpc(np, minSlope))
                    {
                        continue;
                    }

                    if (np.Distance(startNode.location) >= range.Max)
                    {
                        continue;
                    }

//                    _zone.CreateAlignedDebugBeam(BeamType.orange_20sec,np.ToPosition());

                    queue.Enqueue(new Node(np, Heuristic.Manhattan.Calculate(np.X, np.Y, (int)farPosition.X, (int)farPosition.Y)));
                }
            }

            _direction = FastRandom.NextDouble();
            return(presence.CurrentRoamingPosition);
        }