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()); }
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); }
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); }