public List <Unit> GetUnitsInAttackRange(List <Vector3Int> attackableTiles) { List <Unit> unitsInRange = new List <Unit>(); foreach (Vector3Int location in attackableTiles) { if (movementGrid.GetMovementTile(location) != null) { foreach (Unit unit in units) { if (unit.position == location && unit.teamNumber != selectedUnit.teamNumber) { unitsInRange.Add(unit); break; } } } } return(unitsInRange); }
private void DrawRange() { rangeOverlayMap.ClearAllTiles(); Vector3Int start = pathfinder.GetPath()[0]; int length = pathfinder.maxLength; if (length == 0) { List <Vector3Int> attackingTiles = unitController.GetAttackableTiles(unitController.GetSelectedUnit().position); DisplayCurrentAttackRange(attackingTiles); showingRange = true; return; } Dictionary <Vector3Int, RangeStatus> highlightStatuses = new Dictionary <Vector3Int, RangeStatus>(); List <Unit> unitsInRange = new List <Unit>(); for (int i = length * -1; i <= length; i++) { for (int j = length * -1; j <= length; j++) { Vector3Int dest = new Vector3Int(start.x + i, start.y + j, 0); if ((Mathf.Abs(i) + Mathf.Abs(j)) > length || unitController.CheckForUnit(dest) != null) //if true, always out of range even if there would be a direct path { continue; } if (movementGrid.GetMovementTile(dest) != null) { List <Vector3Int> testPath = pathfinder.AStar(start, dest, new List <Vector3Int> { start }); if (testPath == null) //pathfinding escaped, no path { List <Vector3Int> attackingTiles = unitController.GetAttackableTiles(unitController.GetSelectedUnit().position); DisplayCurrentAttackRange(attackingTiles); } else if (testPath.Count > 0 && testPath[testPath.Count - 1] == dest) //there is a valid path to the coordinates { List <Vector3Int> attackingTiles = unitController.GetAttackableTiles(testPath[testPath.Count - 1]); foreach (Vector3Int location in attackingTiles) { if (movementGrid.GetMovementTile(location) == null) { Debug.Log("Attack location out of bounds: " + location); continue; } //Debug.Log("Enter Attack Highlight for location: " + location); if (!highlightStatuses.ContainsKey(location)) { Unit unitAtLocation = unitController.CheckForUnit(location); if (unitAtLocation != null) { if (unitAtLocation.teamNumber == unitController.GetSelectedUnit().teamNumber) { //Debug.Log("Marked blocked by ally"); highlightStatuses.Add(location, RangeStatus.BlockedByAlly); } else { //Debug.Log("Marked blocked by enemy"); highlightStatuses.Add(location, RangeStatus.BlockedByEnemy); unitsInRange.Add(unitAtLocation); rangeOverlayMap.SetTile(location, attackTileHighlight); } } else { //Debug.Log("Marked attacking"); highlightStatuses.Add(location, RangeStatus.Attack); rangeOverlayMap.SetTile(location, attackTileHighlight); } } } foreach (Vector3Int location in testPath) { if (highlightStatuses.ContainsKey(location)) { if (highlightStatuses[location] == RangeStatus.Movement || highlightStatuses[location] == RangeStatus.BlockedByAlly || highlightStatuses[location] == RangeStatus.BlockedByEnemy) { continue; } else { highlightStatuses[location] = RangeStatus.Movement; rangeOverlayMap.SetTile(location, movementTileHighlight); } } else if (unitController.CheckForUnit(location) != null) { if (unitController.CheckForUnit(location).teamNumber == unitController.GetSelectedUnit().teamNumber) { highlightStatuses.Add(location, RangeStatus.BlockedByAlly); } } else { highlightStatuses.Add(location, RangeStatus.Movement); rangeOverlayMap.SetTile(location, movementTileHighlight); } } } } } } unitController.SetUnitsInAttackRange(unitsInRange); showingRange = true; }
public List <Vector3Int> AStar(Vector3Int startPos, Vector3Int destPos, List <Vector3Int> currentPath) { MovementTile startTile = movementGrid.GetMovementTile(startPos); MovementTile endTile = movementGrid.GetMovementTile(destPos); if (startTile == null || endTile == null) { Debug.Log("Start or end point invalid"); Debug.Log("startPos: " + startPos); Debug.Log("destPos: " + destPos); return(null); } List <MovementTile> openTiles = new List <MovementTile>(); List <MovementTile> closedTiles = new List <MovementTile>(); openTiles.Add(startTile); while (openTiles.Count > 0) { MovementTile currentTile = openTiles[0]; for (int i = 1; i < openTiles.Count; i++) { if (openTiles[i].fCost < currentTile.fCost || (openTiles[i].fCost == currentTile.fCost && openTiles[i].hCost < currentTile.hCost)) { currentTile = openTiles[i]; } } openTiles.Remove(currentTile); closedTiles.Add(currentTile); if (currentTile == endTile) { return(AddToPath(RetracePath(startTile, endTile), maxLength, currentPath)); } foreach (MovementTile neighbor in currentTile.neighbors) { Unit unitAtNeighbor = unitController.CheckForUnit(neighbor.coordinates); if ((unitAtNeighbor != null && unitAtNeighbor.teamNumber != unitController.GetSelectedUnit().teamNumber)) { closedTiles.Add(neighbor); continue; } if (closedTiles.Contains(neighbor)) { continue; } int newCostToNeighbor = currentTile.gCost + neighbor.movementCost; if (newCostToNeighbor < neighbor.gCost || !openTiles.Contains(neighbor)) { neighbor.gCost = newCostToNeighbor; neighbor.hCost = GetHeuristicDistance(neighbor, endTile); neighbor.parent = currentTile; if (!openTiles.Contains(neighbor)) { openTiles.Add(neighbor); } } } } Debug.Log("Escaped"); return(null); }