private float GetEstimatedCost(Int2D End, Map map, float estimateAggression) { const float scale = 1f; float multiplier = scale * ((estimateAggression < 0f) ? -estimateAggression : estimateAggression); return((Index.x < End.x ? End.x - Index.x : Index.x - End.x) * multiplier + (Index.y < End.y ? End.y - Index.y : Index.y - End.y) * multiplier); }
public static Int2D[] IndexesBetween(Map map, Int2D start, Int2D end) // Start and end both are inclusive { if (start.x > end.x) { int StartX = start.x; start.x = end.x; end.x = StartX; } if (start.y > end.y) { int StartY = start.y; start.y = end.y; end.y = StartY; } start = BringInBounds(map, start); end = BringInBounds(map, end); Int2D[] collectedNodes = new Int2D[((end.x - start.x) + 1) * ((end.y - start.y) + 1)]; int current = 0; for (int i = start.x; i <= end.x; i++) { for (int j = start.y; j <= end.y; j++) { collectedNodes[current++] = new Int2D(i, j); } } return(collectedNodes); }
public void CalculateFGH(Int2D End, Map map, float aggression) { const float scale = 1f; float multiplier = scale * ((aggression < 0f) ? -aggression : aggression); G = Parent != null ? Parent.G + (Parent.MoveCost * scale * ((Parent.Index.x != Index.x && Parent.Index.y != Index.y) ? 1.414f : 1f)) : 0f; H = (Index.x < End.x ? End.x - Index.x : Index.x - End.x) * multiplier + (Index.y < End.y ? End.y - Index.y : Index.y - End.y) * multiplier; F = G + H; }
public static void UpdateNodeRuntime(Map map, Int2D index, Config config) { map.MakeBusy(); UpdateNode(map.GetNode(index), config, false); map.MakeFree(); map.TriggerUpdateEvent(); }
public Node(Int2D Index, Vector Position, bool Walkable, float MoveCost, Node Parent, bool OnOpenList, bool OnClosedList, float F, float G, float H, int BHIndex) : this(Index, Position, Walkable, MoveCost) { this.Parent = Parent; this.OnOpenList = OnOpenList; this.OnClosedList = OnClosedList; this.F = F; this.G = G; this.H = H; this.BHIndex = BHIndex; }
public PathRequest(Int2D Start, Int2D End, Map map, float EstimateAggression, bool MoveDiognal, float MaxDepthDiff, float DepthCostAggression, Int2D[] disallowedIndexes, System.Action <Vector[]> OutputMethod) { this.Start = Start; this.End = End; this.map = map; this.EstimateAggression = EstimateAggression; this.MoveDiognal = MoveDiognal; this.OutputMethod = OutputMethod; this.DepthCostAggression = DepthCostAggression; this.MaxDepthDifference = MaxDepthDiff; this.disallowedIndexes = disallowedIndexes; }
/// <summary> /// This calculates the difference in the dept (Z or Y axis) as cost too /// </summary> public void CalculateFGH(Int2D End, Map map, float aggression, float depthAggression, Generator.Config config) { const float scale = 1f; float multiplier = scale * ((aggression < 0f) ? -aggression : aggression); Vector parentPos = Parent.Position; int depthDimension = config.XYGrid ? 2 : 1; float depthDiff = parentPos[depthDimension] < Position[depthDimension] ? Position[depthDimension] - parentPos[depthDimension] : parentPos[depthDimension] - Position[depthDimension]; G = Parent != null ? (Parent.G + (Parent.MoveCost * scale * ((Parent.Index.x != Index.x && Parent.Index.y != Index.y) ? 1.414f : 1f))) + (depthAggression * depthDiff) : 0f; H = (Index.x < End.x ? End.x - Index.x : Index.x - End.x) * multiplier + (Index.y < End.y ? End.y - Index.y : Index.y - End.y) * multiplier; F = G + H; }
public Node(Node node, bool deep) { this.Index = node.Index; this.Position = node.Position; this.Walkable = node.Walkable; this.MoveCost = node.MoveCost; if (deep) { this.Parent = node.Parent; this.OnOpenList = node.OnOpenList; this.OnClosedList = node.OnClosedList; this.F = node.F; this.G = node.G; this.H = node.H; this.BHIndex = node.BHIndex; } }
private static PathRequest RequestPath(Int2D Start, Int2D End, Map map, float estimateAggression, bool moveDiognal, float maxDepthDiff, float depthDiffCostMultiplier, Int2D[] disallowedIndexes, System.Action <Vector[]> OutputMethod) { if (RequestQue == null) { RequestQue = new System.Collections.Generic.Queue <PathRequest>(); } UtilityMonoBehaviour.CreateInstance(); PathRequest request = new PathRequest(Start, End, map, estimateAggression, moveDiognal, maxDepthDiff, depthDiffCostMultiplier, disallowedIndexes, OutputMethod); RequestQue.Enqueue(request); if (RequestProcessThread == null || !RequestProcessThread.IsAlive) { RequestProcessThread = new Thread(ProcessRequests); RequestProcessThread.Priority = DefaultPriority; RequestProcessThread.Start(); } return(request); }
public static void UpdateNodesRuntime(Map map, Int2D Start, Int2D End) { map.MakeBusy(); Node[,] nodes = map.GetNodeArrayReference(); Generator.Config config = map.GetConfig(); if (End.x < Start.x) { int startX = Start.x; Start.x = End.x; End.x = startX; } if (End.y < Start.y) { int startY = Start.y; Start.y = End.y; End.y = startY; } if (Start.x < 0 || Start.y < 0 || End.x > map.TilesX || End.y > map.TilesY) { throw new System.IndexOutOfRangeException("Node index is out of range"); } for (int i = Start.x; i < End.x; i++) { for (int j = Start.y; j < End.y; j++) { UpdateNode(nodes[i, j], config, false); } } map.MakeFree(); map.TriggerUpdateEvent(); }
private static Vector[] FindPathImmediate(Int2D Start, Int2D End, Map map, float estimateAggression, bool moveDiognal, float maxDepthDiff, float depthCostAggression, Int2D[] disallowedIndexes) { Initialise(map); Start = map.BringInBounds(Start); End = map.BringInBounds(End); if (disallowedIndexes != null) { for (int i = 0; i < disallowedIndexes.Length; i++) { Node node = Nodes[disallowedIndexes[i].x, disallowedIndexes[i].y]; ClosedList[ClosedListLength++] = node; node.OnOpenList = false; node.OnClosedList = true; } } int depthDimension = config.XYGrid ? 1 : 2; // We disallowed the target node! // And starting one too.... if (!Nodes[Start.x, Start.y].Walkable || !Nodes[End.x, End.y].Walkable || Nodes[End.x, End.y].OnClosedList || Nodes[Start.x, Start.y].OnClosedList) { Clean(); return(null); } Node current = Nodes[Start.x, Start.y]; current.CalculateFGH(End, map, estimateAggression); AddToBH(current); while (!Nodes[End.x, End.y].OnClosedList) { if (OpenListLength < 0) { Clean(); return(null); } current = OpenList[1]; OpenList[1].OnClosedList = true; OpenList[1].OnOpenList = false; ClosedList[ClosedListLength++] = OpenList[1]; OpenList[1].BHIndex = -1; OpenList[1] = OpenList[OpenListLength--]; SortFrom(1); Int2D currentIndex = current.Index; for (int i = 0; i < 8; i++) { if (!moveDiognal) { if ((i & 1) != 0) // if i is not even { continue; } } Int2D nearbyIndex = currentIndex; switch (i) { case 0: nearbyIndex.x -= 1; break; case 1: nearbyIndex.x -= 1; nearbyIndex.y += 1; break; case 2: nearbyIndex.y += 1; break; case 3: nearbyIndex.y += 1; nearbyIndex.x += 1; break; case 4: nearbyIndex.x += 1; break; case 5: nearbyIndex.x += 1; nearbyIndex.y -= 1; break; case 6: nearbyIndex.y -= 1; break; case 7: nearbyIndex.x -= 1; nearbyIndex.y -= 1; break; } if (nearbyIndex.x < 0 || nearbyIndex.y < 0 || nearbyIndex.x >= TilesX || nearbyIndex.y >= TilesY) { continue; } Node nearbyNode = Nodes[nearbyIndex.x, nearbyIndex.y]; float depthDiff = nearbyNode.Position[depthDimension] - current.Position[depthDimension]; depthDiff = depthDiff < 0f ? -depthDiff : depthDiff; if (depthDiff > maxDepthDiff) { continue; } if (nearbyNode.OnOpenList) { if (nearbyNode.G < current.G) { nearbyNode.Parent = current; nearbyNode.CalculateFGH(End, map, estimateAggression, depthCostAggression, config); SortFrom(nearbyNode.BHIndex); } } else if (!nearbyNode.OnClosedList && nearbyNode.Walkable) { nearbyNode.Parent = current; nearbyNode.CalculateFGH(End, map, estimateAggression, depthCostAggression, config); nearbyNode.OnOpenList = true; nearbyNode.BHIndex = ++OpenListLength; OpenList[nearbyNode.BHIndex] = nearbyNode; SortFrom(OpenListLength); } } } int len = 0; Node n = Nodes[End.x, End.y]; while (n != null) { n = n.Parent; len += 1; } n = Nodes[End.x, End.y]; Vector[] path = new Vector[len]; int j = len - 1; while (n != null) { path[j--] = n.Position; n = n.Parent; } Clean(); return(path); }
public static void Update(Map map, Int2D index) { index = map.BringInBounds(index); Generator.UpdateNodeRuntime(map, index, map.GetConfig()); }
public Node GetNode(Int2D index) { return(Nodes[index.x, index.y]); }
public Node(Int2D Index, Vector Position, bool Walkable, float MoveCost) : this(Index, Position, Walkable) { this.MoveCost = MoveCost; }
public Node(Int2D Index, Vector Position, bool Walkable) : this(Index, Position) { this.Walkable = Walkable; }
public Node(Int2D Index, Vector Position) : this(Index) { this.Position = Position; }
public Node(Int2D Index) { this.Index = Index; }
public bool InBounds(Int2D start) { return((start.x >= 0 && start.x < config.TilesX) && (start.y >= 0 && start.y < config.TilesY)); }
public Int2D BringInBounds(Int2D index) { return(new Int2D(index.x < 0 ? 0 : index.x >= TilesX ? TilesX - 1 : index.x, index.y < 0 ? 0 : index.y >= TilesY ? TilesY - 1 : index.y)); }
public static Int2D BringInBounds(Map map, Int2D index) { return(map.BringInBounds(index)); }
public Int2D(Int2D int2D) { this.x = int2D.x; this.y = int2D.y; }
public static void Update(Map map, Int2D start, Int2D end) { start = map.BringInBounds(start); end = map.BringInBounds(end); Generator.UpdateNodesRuntime(map, start, end); }