public void Shutdown() { while (FreeAgentCount > 0) { m_FreeAgents.Pop().Shutdown(); } foreach (ITaskAgent <T> workingAgent in m_WorkingAgents) { workingAgent.Shutdown(); } m_WorkingAgents.Clear(); m_WaitingTasks.Clear(); }
public List <Vector2i> PathFind(Vector2i start, Vector2i end) { bool found = false; mOpenTable.Clear(); mResultPath.Clear(); mOpenStatusValue += 2; mCloseStatusValue += 2; int closeNodeCounter = 0; ushort location = (ushort)((start[1] << mGridXLog2) + start[0]); ushort endLocation = (ushort)((end[1] << mGridXLog2) + end[0]); mGridNode[location].G = 0; mGridNode[location].F = _hEstimate; mGridNode[location].PX = (ushort)start[0]; mGridNode[location].PY = (ushort)start[1]; mGridNode[location].Status = mOpenStatusValue; mOpenTable.Enqueue(location, location, mGridNode[location].F); ushort locationX; ushort locationY; ushort mHoriz = 0; sbyte[,] direction = _useDiagonal ? AStarDirection.DiagonalDirection : AStarDirection.NormalDirection; int directionCount = _useDiagonal ? 8 : 4; while (mOpenTable.Count > 0) { location = mOpenTable.Dequeue(); if (mGridNode[location].Status == mCloseStatusValue) { continue; } if (location == endLocation) { mGridNode[location].Status = mCloseStatusValue; found = true; break; } if (closeNodeCounter > _searchLimit) { break; } locationX = (ushort)(location & mGridXMod); locationY = (ushort)(location >> mGridXLog2); if (_usePunish) { mHoriz = (ushort)(locationX - mGridNode[location].PX); } int newG; for (int i = 0; i < directionCount; i++) { ushort newLocationX = (ushort)(locationX + direction[i, 0]); ushort newLocationY = (ushort)(locationY + direction[i, 1]); ushort newLocation = (ushort)((newLocationY << mGridXLog2) + newLocationX); if (newLocationX >= mGridX || newLocationY >= mGridY) { continue; } if (mGridNode[newLocation].Status == mCloseStatusValue && !ReuseClose) { continue; } if (mGrid[newLocationX, newLocationY] == 0) { continue; } if (_useDiagonal && i > 3) { newG = mGridNode[location].G + (int)(mGrid[newLocationX, newLocationY] * 2.41); } else { newG = mGridNode[location].G + mGrid[newLocationX, newLocationY]; } if (Punish) { if ((newLocationX - locationX) != 0) { if (mHoriz == 0) { newG += Math.Abs(newLocationX - end[0]) + Math.Abs(newLocationY - end[1]); } } if ((newLocationY - locationY) != 0) { if (mHoriz != 0) { newG += Math.Abs(newLocationX - end[0]) + Math.Abs(newLocationY - end[1]); } } } if (mGridNode[newLocation].Status == mOpenStatusValue || mGridNode[newLocation].Status == mCloseStatusValue) { if (mGridNode[newLocation].G <= newG) { continue; } } mGridNode[newLocation].PX = locationX; mGridNode[newLocation].PY = locationY; mGridNode[newLocation].G = newG; int newH = 0; switch (_useFormula) { case AStarFormula.Manhattan: newH = _hEstimate * (Math.Abs(newLocationX - end[0]) + Math.Abs(newLocationY - end[1])); break; case AStarFormula.MaxDXDY: newH = _hEstimate * (Math.Max(Math.Abs(newLocationX - end[0]), Math.Abs(newLocationY - end[1]))); break; case AStarFormula.DiagonalShortCut: int h_diagonal = Math.Min(Math.Abs(newLocationX - end[0]), Math.Abs(newLocationY - end[1])); int h_straight = (Math.Abs(newLocationX - end[0]) + Math.Abs(newLocationY - end[1])); newH = (_hEstimate * 2) * h_diagonal + _hEstimate * (h_straight - 2 * h_diagonal); break; case AStarFormula.Euclidean: newH = (int)(_hEstimate * Math.Sqrt(Math.Pow((newLocationY - end[0]), 2) + Math.Pow((newLocationY - end[1]), 2))); break; case AStarFormula.EuclideanNoSQR: newH = (int)(_hEstimate * (Math.Pow((newLocationX - end[0]), 2) + Math.Pow((newLocationY - end[1]), 2))); break; case AStarFormula.Custom: Vector2i dxy = new Vector2i(Math.Abs(end[0] - newLocationX), Math.Abs(end[1] - newLocationY)); int Orthogonal = Math.Abs(dxy[0] - dxy[1]); int Diagonal = Math.Abs(((dxy[0] + dxy[1]) - Orthogonal) / 2); newH = _hEstimate * (Diagonal + Orthogonal + dxy[0] + dxy[1]); break; } if (_useTieBreaker) { int dx1 = locationX - end[0]; int dy1 = locationY - end[1]; int dx2 = start[0] - end[0]; int dy2 = start[1] - end[1]; int cross = Math.Abs(dx1 * dy2 - dx2 * dy1); newH = (int)(newH + cross * _multiple); } mGridNode[newLocation].F = newG + newH; mOpenTable.Enqueue(newLocation, newLocation, mGridNode[newLocation].F); mGridNode[newLocation].Status = mOpenStatusValue; } closeNodeCounter++; mGridNode[location].Status = mCloseStatusValue; } if (found) { mResultPath.Clear(); PathNode tmp = mGridNode[(end[1] << mGridXLog2) + end[0]]; PathNodeResult node = new PathNodeResult(); node.F = tmp.F; node.G = tmp.G; node.H = 0; node.PX = tmp.PX; node.PY = tmp.PY; node.X = end[0]; node.Y = end[1]; while (node.X != node.PX || node.Y != node.PY) { mResultPath.Add(node); ushort posX = node.PX; ushort posY = node.PY; tmp = mGridNode[(posY << mGridXLog2) + posX]; node = new PathNodeResult(); node.F = tmp.F; node.G = tmp.G; node.H = 0; node.PX = tmp.PX; node.PY = tmp.PY; node.X = posX; node.Y = posY; } mResultPath.Add(node); mResultPath.Reverse(0, mResultPath.Count); List <Vector2i> res = new List <Vector2i>(); foreach (PathNodeResult n in mResultPath) { res.Add(new Vector2i(n.X, n.Y)); } return(res); } return(null); }
public override void SysFinalize() { CancelInvoke("Tick"); m_queue.Clear(); base.SysFinalize(); }