/// <summary> /// Finds a path from any of start to goal, such that the path has no links that are steeper up than maxIncline /// nor steeper down than maxDecline. /// </summary> /// <returns>The path.</returns> /// <param name="startPoint">PointWithDistance of point to start from</param> /// <param name="goalPoint">map indices of point to go to</param> List <PointWithDistance> FindPath(PointWithDistance startPoint, InclineIndexPoint goalPoint, float maxIncline, float maxDecline) { List <PointWithDistance> startList = new List <PointWithDistance>(); startList.Add(startPoint); return(FindPath(startList, goalPoint, maxIncline, maxDecline)); }
public Vector3 GetDestination(Vector3 goal, float movementBudget, float maxSlope, AbstractActor unit, bool shouldSprint, List <AbstractActor> lanceUnits, PathNodeGrid pathGrid, out Vector3 lookAtPoint) { List <PointWithDistance> startPointList = new List <PointWithDistance>(); List <PathNode> pathNodes = pathGrid.GetSampledPathNodes(); for (int pni = 0; pni < pathNodes.Count; ++pni) { PathNode pn = pathNodes[pni]; PointWithDistance pwd = new PointWithDistance(WorldPointToInclineIndices(pn.Position), pn.DepthInPath * 24, (goal - pn.Position).magnitude); pwd.pathNode = pn; startPointList.Add(pwd); } return(GetDestination(startPointList, goal, movementBudget, maxSlope, unit, shouldSprint, lanceUnits, pathGrid, out lookAtPoint)); }
protected override bool IsCellEatable(PointWithDistance p) { throw new System.NotImplementedException(); }
/// <summary> /// Finds a path from any of the points in startPointList to goal, such that the path has no links that are steeper up than maxIncline /// nor steeper down than maxDecline. /// </summary> /// <returns>The path.</returns> /// <param name="startPointList">PointWithDistance structs for starting area</param> /// <param name="goalPoint">map indices of point to go to</param> List <PointWithDistance> FindPath(List <PointWithDistance> startPointList, InclineIndexPoint goalPoint, float maxIncline, float maxDecline) { List <PointWithDistance> path = new List <PointWithDistance>(); HeapQueue <PointWithDistance> openHeap = new HeapQueue <PointWithDistance>(); Dictionary <InclineIndexPoint, float> bestDistanceDict = new Dictionary <InclineIndexPoint, float>(); Dictionary <InclineIndexPoint, PointWithDistance> bestPrevPoint = new Dictionary <InclineIndexPoint, PointWithDistance>(); Point goalMapPoint = InclineIndicesToMapIndices(goalPoint); Vector3 worldGoalPoint = mapMetaData.getWorldPos(goalMapPoint); for (int startIndex = 0; startIndex < startPointList.Count; ++startIndex) { PointWithDistance pwd = startPointList[startIndex]; openHeap.Push(pwd); bestDistanceDict[pwd.point] = pwd.distance; bestPrevPoint[pwd.point] = null; } float bestPathLength = -1; PointWithDistance bestGoalPoint = new PointWithDistance(new InclineIndexPoint(-1024, -1024), float.MaxValue, float.MaxValue); while (!openHeap.IsEmpty()) { PointWithDistance ptWithDist = openHeap.PopMinimum(); if ((bestPathLength > 0) && ((ptWithDist.estimatedTotalDistance > bestPathLength) || TAKE_FIRST_PATH)) { break; } int[] xOffsets = { 1, 0, -1, 0 }; int[] zOffsets = { 0, 1, 0, -1 }; InclineMeshNode node = nodes[ptWithDist.point.X, ptWithDist.point.Z]; Vector3 worldNodePoint = InclineIndicesToWorldPoint(ptWithDist.point); for (int direction = 0; direction < 4; ++direction) { int dx = xOffsets[direction]; int dz = zOffsets[direction]; int nx = ptWithDist.point.X + dx; int nz = ptWithDist.point.Z + dz; InclineIndexPoint neighborPoint = new InclineIndexPoint(nx, nz); Point mapNeighborPoint = InclineIndicesToMapIndices(neighborPoint); if ((!mapMetaData.IsWithinBounds(mapNeighborPoint)) || (node.NeighborLinks[direction] == null)) { continue; } Vector3 worldNeighborPoint = InclineIndicesToWorldPoint(neighborPoint); for (int linkIndex = 0; linkIndex < node.NeighborLinks[direction].Count; ++linkIndex) { Debug.DrawLine(worldNodePoint, worldNeighborPoint, Color.yellow, 15.0f); InclineLinkData link = node.NeighborLinks[direction][linkIndex]; if ((link.declineAsFloat() > maxDecline) || (link.inclineAsFloat() > maxIncline)) { continue; } float linkDistance = (worldNeighborPoint - worldNodePoint).magnitude; float totalDistance = ptWithDist.distance + linkDistance; if ((bestPathLength >= 0) && (totalDistance >= bestPathLength)) { continue; } if ((!bestDistanceDict.ContainsKey(neighborPoint)) || (totalDistance < bestDistanceDict[neighborPoint])) { bestDistanceDict[neighborPoint] = totalDistance; bestPrevPoint[neighborPoint] = ptWithDist; float distanceToGoal = (worldNeighborPoint - worldGoalPoint).magnitude; if (neighborPoint.Equals(goalPoint)) { if ((bestPathLength < 0) || (totalDistance < bestPathLength)) { bestPathLength = totalDistance; bestGoalPoint = new PointWithDistance(neighborPoint, totalDistance, 0.0f); } } else { openHeap.Push(new PointWithDistance(neighborPoint, totalDistance, totalDistance + distanceToGoal)); } } break; } } } if (bestPathLength >= 0) { PointWithDistance p = bestGoalPoint; path.Add(p); while (bestPrevPoint.ContainsKey(p.point)) { PointWithDistance prevPoint = bestPrevPoint[p.point]; if ((prevPoint == null) || (path.Contains(prevPoint))) { break; } path.Insert(0, prevPoint); p = prevPoint; } } return(path); }
protected override bool IsCellEatable(PointWithDistance p) { var obj = Game.Map.GetObjectFromCell(p); return(obj != null && obj.GetBaseName() == Resource.Plant); }
protected abstract bool IsCellEatable(PointWithDistance p);
protected override bool IsCellEatable(PointWithDistance p) { var obj = Game.Map.GetObjectFromCell(p); return((obj is Berry && obj.Name == Resource.Apple) || obj is Mushroom); }