public Ability(string abilityName, float attackRange, int manaCost, bool targetsSameTeam, TargetingStyle targetingStyle, AbilityType[] abilityTypes, int multiAbilityRange = 0, int duration = -1) { this.abilityName = abilityName; this.attackRange = attackRange; this.manaCost = manaCost; this.targetsSameTeam = targetsSameTeam; this.targetingStyle = targetingStyle; this.abilityTypes = abilityTypes; this.multiAbilityRange = multiAbilityRange; this.duration = duration; }
public void FindAttackableTiles(Tile startTile, float attackRange, TargetingStyle targetingStyle = TargetingStyle.SINGLE) { #region Basic Targeting (Deprecated) /*if (targetingStyle == TargetingStyle.SINGLE || targetingStyle == TargetingStyle.MULTI || targetingStyle == TargetingStyle.SELFSINGLE) * { * int[] hor = { -1, 0, 1, 0 }; * int[] vert = { 0, 1, 0, -1 }; * * int currX = startTile.gridPosition.x, currY = startTile.gridPosition.y; * * bool[] passable = new bool[4]; * for (int i = 0; i < 4; i++) * { * passable[i] = true; * } * * for (int i = 1; i <= attackRange; i++) * { * for (int j = 0; j < 4; j++) * { * int newX = currX + i * hor[j]; * int newY = currY + i * vert[j]; * * if (newX >= 0 && newX < mapSize.x && newY >= 0 && newY < mapSize.y) * { * if (tileList[newX][newY].walkable && passable[j]) * { * tileList[newX][newY].attackable = true; * attackableTiles.Add(tileList[newX][newY]); * } * else * { * passable[j] = false; * } * } * } * } * }*/ #endregion #region Basic Targeting if (targetingStyle == TargetingStyle.SINGLE || targetingStyle == TargetingStyle.MULTI || targetingStyle == TargetingStyle.SELFSINGLE) { PriorityQueue <TileDistancePair> processing = new PriorityQueue <TileDistancePair>(); // Compute Adjacency List and reset all distances. InitPathFinding(startTile); attackableTiles.Add(startTile); processing.Enqueue(new TileDistancePair(0, startTile)); // relax edges with minimum SP estimate while (processing.Count() > 0) { TileDistancePair temp = processing.Dequeue(); float distanceEstimate = temp.d; Tile node = temp.t; if ((int)Math.Round(distanceEstimate) == node.distance) { foreach (Tile neighbour in node.adjacencyList) { int newEstimate = node.distance + 1; if (neighbour.walkable && neighbour.distance > newEstimate && newEstimate <= attackRange) { neighbour.attackable = true; attackableTiles.Add(neighbour); neighbour.distance = newEstimate; processing.Enqueue(new TileDistancePair(newEstimate, neighbour)); } } } } } #endregion #region Self Targeting if (targetingStyle == TargetingStyle.SELF || targetingStyle == TargetingStyle.SELFSINGLE) { startTile.attackable = true; attackableTiles.Add(startTile); } #endregion #region Radius Targeting if (targetingStyle == TargetingStyle.RADIUS) { // init Dijkstra PriorityQueue <TileDistancePair> processing = new PriorityQueue <TileDistancePair>(); // Compute Adjacency List and reset all distances. InitPathFinding(startTile, true); attackableTiles.Add(startTile); processing.Enqueue(new TileDistancePair(0, startTile)); // relax edges with minimum SP estimate while (processing.Count() > 0) { TileDistancePair temp = processing.Dequeue(); float distanceEstimate = temp.d; Tile node = temp.t; if ((int)Math.Round(distanceEstimate) == node.distance) { foreach (Tile neighbour in node.adjacencyList) { int newEstimate = node.distance + 1; if (neighbour.walkable && neighbour.distance > newEstimate && newEstimate <= attackRange) { neighbour.attackable = true; attackableTiles.Add(neighbour); neighbour.distance = newEstimate; processing.Enqueue(new TileDistancePair(newEstimate, neighbour)); } } } } } #endregion #region Obstacle Targeting if (targetingStyle == TargetingStyle.OBSTACLES) { int[] hor = { -1, 0, 1, 0 }; int[] vert = { 0, 1, 0, -1 }; int currX = startTile.gridPosition.x, currY = startTile.gridPosition.y; bool[] passable = new bool[4]; for (int i = 0; i < 4; i++) { passable[i] = true; } for (int i = 1; i <= attackRange; i++) { for (int j = 0; j < 4; j++) { int newX = currX + i * hor[j]; int newY = currY + i * vert[j]; if (newX >= 0 && newX < mapSize.x && newY >= 0 && newY < mapSize.y) { if (!tileList[newX][newY].walkable) { tileList[newX][newY].attackable = true; attackableTiles.Add(tileList[newX][newY]); } else { passable[j] = false; } } } } } #endregion }
public void HighlightSelectedTiles(HighlightTile mainTile) { // if alr clicked, do nothing: if (clicked) { return; } RemoveSelectedTiles(); // check if tile being hovered is attackable Tile mapStartTile = map.tileList[mainTile.gridPosition.x][mainTile.gridPosition.y]; if (!mapStartTile.attackable) { return; } Ability ability = GameAssets.MyInstance.turnScheduler.currUnit?.chosenAbility; if (ability == null) { ability = new AbilityDefault(); } TargetingStyle targetingStyle = ability.targetingStyle; #region Getting the correct target team IEnumerable <Unit> friendlyTeam; TurnScheduler turnScheduler = GameAssets.MyInstance.turnScheduler; if (turnScheduler.currTurn == Team.ENEMY) { if (ability.targetsSameTeam) { friendlyTeam = turnScheduler.enemies; } else { friendlyTeam = turnScheduler.players; } } else { if (ability.targetsSameTeam) { friendlyTeam = turnScheduler.enemies; } else { friendlyTeam = turnScheduler.players; } } #endregion bool IsFriendlyFire(Tile mapEquivalent) { if (mapEquivalent.occupied) { foreach (Unit unit in friendlyTeam) { if (unit.currentTile == mapEquivalent) { return(true); } } } return(false); } if (targetingStyle == TargetingStyle.MULTI) { int multiAbilityRange = ability.multiAbilityRange; //Debug.Log("multiAbilityRange = " + multiAbilityRange); // init BFS Queue <HighlightTile> processing = new Queue <HighlightTile>(); // Compute Adjacency List and reset all distances. InitPathFinding(mainTile); selectedTiles.Add(mainTile); processing.Enqueue(mainTile); // relax edges with minimum SP estimate while (processing.Count > 0) { HighlightTile node = processing.Dequeue(); foreach (HighlightTile neighbour in node.adjacencyList) { Tile mapEquivalent = map.tileList[neighbour.gridPosition.x][neighbour.gridPosition.y]; if (mapEquivalent.walkable && neighbour.distance > node.distance + 1 && node.distance + 1 <= multiAbilityRange) { if (!IsFriendlyFire(mapEquivalent)) { neighbour.distance = node.distance + 1; selectedTiles.Add(neighbour); processing.Enqueue(neighbour); } } } } } else if (targetingStyle == TargetingStyle.SINGLE || targetingStyle == TargetingStyle.SELF || targetingStyle == TargetingStyle.SELFSINGLE) { Tile mapEquivalent = map.tileList[mainTile.gridPosition.x][mainTile.gridPosition.y]; if (!IsFriendlyFire(mapEquivalent)) { selectedTiles.Add(mainTile); } } else if (targetingStyle == TargetingStyle.RADIUS) { foreach (Tile tile in map.GetAttackableTiles()) { if (!IsFriendlyFire(tile)) { selectedTiles.Add(tileList[tile.gridPosition.x][tile.gridPosition.y]); } } } else if (targetingStyle == TargetingStyle.OBSTACLES) { if (map.tileCostReference.IsObstacle(mainTile.transform.position)) { selectedTiles.Add(mainTile); } } foreach (HighlightTile tile in selectedTiles) { tile.hover = true; } }