public void PlayDefendSound(Unit selected) { if (selected is Soldier && selected.isPlayerUnit) { cue = soundBank.GetCue("SoldierDefend"); } else if (selected is Soldier && !selected.isPlayerUnit) { cue = soundBank.GetCue("ESoldierDefend"); } else if (selected is Ranger && selected.isPlayerUnit) { cue = soundBank.GetCue("RangerDefend"); } else if (selected is Ranger && !selected.isPlayerUnit) { cue = soundBank.GetCue("ERangerDefend"); } else if (selected is Defender && selected.isPlayerUnit) { cue = soundBank.GetCue("DefenderDefend"); } else { cue = soundBank.GetCue("EDefenderDefend"); } cue.Play(); }
public void PlayAttackSound(Unit attacker) { if (attacker is Soldier && attacker.isPlayerUnit) { cue = soundBank.GetCue("SoldierAttack"); } else if (attacker is Soldier && !attacker.isPlayerUnit) { cue = soundBank.GetCue("ESoldierAttack"); } else if (attacker is Ranger && attacker.isPlayerUnit) { cue = soundBank.GetCue("RangerAttack"); } else if (attacker is Ranger && !attacker.isPlayerUnit) { cue = soundBank.GetCue("ERangerAttack"); } else if (attacker is Defender && attacker.isPlayerUnit) { cue = soundBank.GetCue("DefenderAttack"); } else { cue = soundBank.GetCue("EDefenderAttack"); } cue.Play(); }
//basic attack method //return the amount of damage done to the defending unit public static int Attack(Unit attacker, Unit defender, List<int> combatModifiers) { Random rand = new Random(); int damage = attacker.Attack + (rand.Next(-6, 6)); //sum over all combat modifiers, such as flanking or status effects int mods = 0; foreach (int mod in combatModifiers) { mods += mod; } double defenseMod = (100.0 - (double)(defender.Defense)) / 100; damage += mods; double dDamage = (double)damage; double rawDamage = dDamage * defenseMod; //add the mods and reduce the damage by the defender's percentage if (rawDamage < 0) { rawDamage = 0; } damage = (int)Math.Round(rawDamage); //round and assign the final damage value return damage; }
public void PlayMoveSound(Unit mover) { if (mover is Soldier && mover.isPlayerUnit) { cue = soundBank.GetCue("SoldierMove"); } else if (mover is Soldier && !mover.isPlayerUnit) { cue = soundBank.GetCue("ESoldierMove"); } else if (mover is Ranger && mover.isPlayerUnit) { cue = soundBank.GetCue("RangerMove"); } else if (mover is Ranger && !mover.isPlayerUnit) { cue = soundBank.GetCue("ERangerMove"); } else if (mover is Defender && mover.isPlayerUnit) { cue = soundBank.GetCue("DefenderMove"); } else { cue = soundBank.GetCue("EDefenderMove"); } cue.Play(); }
public List<int[]> GetLegalMoveCoordinates(Unit selected) { List<int[]> legalmoves = new List<int[]>(); Tile location = GetTileAt(selected.Location[0], selected.Location[1]); int tileRange = selected.Speed / 25; List<Tile> reachableTiles = new List<Tile>(); for (int i = -tileRange; i <= tileRange; i++) { for (int j = -tileRange; j <= tileRange; j++) { if ((i + location.X) < Size[0] && (j + location.Y) < Size[1] && (i + location.X) >= 0 & (j + location.Y) >= 0) { reachableTiles.Add(GetTileAt(i + location.X, j + location.Y) ); } } } List<Tile> trueReachableTiles = new List<Tile>(); foreach (Tile tile in reachableTiles) { if ((Math.Abs(tile.X - location.X) + Math.Abs(tile.Y - location.Y)) <= tileRange && !tile.IsImpassible) { trueReachableTiles.Add(tile); } } //... List<Tile> tempTileList = new List<Tile>(); foreach (Tile tile in trueReachableTiles) { tile.IsRoot = false; tile.parentTile = null; tile.HScore = 0; tile.GScore = 0; tile.FScore = 0; if(AI.PathExists(location, tile, this, trueReachableTiles, selected.Speed)) { tempTileList.Add(tile); } } //... trueReachableTiles = tempTileList; //cleanup foreach (Tile tile in trueReachableTiles) { tile.IsRoot = false; tile.parentTile = null; tile.FScore = 0; tile.GScore = 0; tile.HScore = 0; tile.IsRedHighlighted = false; } foreach (Tile tile in trueReachableTiles) { legalmoves.Add(new int[] { tile.X, tile.Y }); } return legalmoves; }
public void PlayDieSound(Unit deadUnit) { if (deadUnit is Soldier && deadUnit.isPlayerUnit) { cue = soundBank.GetCue("SoldierDie"); } else if (deadUnit is Soldier && !deadUnit.isPlayerUnit) { cue = soundBank.GetCue("ESoldierDie"); } else if (deadUnit is Ranger && deadUnit.isPlayerUnit) { cue = soundBank.GetCue("RangerDie"); } else if (deadUnit is Ranger && !deadUnit.isPlayerUnit) { cue = soundBank.GetCue("ERangerDie"); } else if (deadUnit is Defender && deadUnit.isPlayerUnit) { cue = soundBank.GetCue("DefenderDie"); } else if (deadUnit is Defender && !deadUnit.isPlayerUnit) { cue = soundBank.GetCue("EDefenderDie"); } cue.Play(); }
//Move one Unit to a new spot on the map //Note there is no checking to make sure it is a legal move. This is done elsewhere public void Move(Unit mover, int X, int Y) { map[mover.Location[0]][mover.Location[1]].TileUnit = null; map[mover.Location[0]][mover.Location[1]].hasUnit = false; map[mover.Location[0]][mover.Location[1]].IsImpassible = false; map[X][Y].TileUnit = mover; mover.Location[0] = X; //update unit location mover.Location[1] = Y; map[X][Y].hasUnit = true; map[X][Y].IsImpassible = true; }
public static void MakeAIMove(Battle battle, Unit active) { Map map = battle.BattleMap; Tile location = map.GetTileAt(active.Location[0], active.Location[1]); //the AI favors nearby units with low health, preferrably out of range of enemies List<Unit> enemies = new List<Unit>(); foreach (Unit unit in battle.BattleQueue) { if (unit.isPlayerUnit) enemies.Add(unit); } Unit nearestEnemy = new Soldier(); int nearestEnemyDistance = 30000; Tile nearestLocation = new Tile(); //calculate the closest enemy foreach (Unit enemy in enemies) { Tile enemyTile = map.GetTileAt(enemy.Location[0], enemy.Location[1]); List<Tile> enemyAdjTiles = GetAdjacentLegalTiles(map, enemyTile); foreach (Tile adj in enemyAdjTiles) { List<Tile> path = GetPath(location, adj, map); foreach (Tile p in path) { int pathTotal = 0; p.FScore = 0; p.GScore = 0; p.HScore = 0; p.parentTile = null; pathTotal += p.MoveCost; if (pathTotal < nearestEnemyDistance) { nearestEnemyDistance = pathTotal; nearestEnemy = enemy; nearestLocation = adj; } } } } //calculate the best unit, if any, in range Unit attackEnemy; int range = active.Range; int x = active.Location[0]; int y = active.Location[1]; List<int[]> rangeSquare = new List<int[]>() ; for (int i = (range * -1); i <= range; i++) { for (int j = (range * -1); j <= range; j++) { if ((i + x) < map.Size[0] && (j + y) < map.Size[1] && (i + x) >= 0 & (j + y) >= 0) { rangeSquare.Add(new int[] { i + x, j + y }); } } } List<Tile> actualRange = new List<Tile>(); foreach (int[] tile in rangeSquare) { if ((Math.Abs(tile[0] - x) + Math.Abs(tile[1] - y)) <= range) { actualRange.Add(map.GetTileAt(tile[0], tile[1])); } } List<Unit> attackableUnits = new List<Unit>(); foreach (Tile tile in actualRange) { if (tile.hasUnit) { if (tile.TileUnit.isPlayerUnit) { attackableUnits.Add(tile.TileUnit); } } } //look for the enemy with the highest HP that can be killed in one or two hits if (attackableUnits.Count > 0) { int highestKillableHP = 0; Unit highestKillableUnit = new Soldier(); foreach (Unit enemy in attackableUnits) { if (AttackResolver.Attack(active, enemy, active.AttackModifiers) * active.AP > enemy.HP && enemy.HP > highestKillableHP) { highestKillableHP = enemy.HP; highestKillableUnit = enemy; } } int highestDamage = 0; Unit highestDamageUnit = new Soldier() ; //if no enemy is killable, find the one we can do the greatest damage to if (highestKillableHP == 0) { foreach (Unit enemy in attackableUnits) { int damage = AttackResolver.Attack(active, enemy, active.AttackModifiers); if (damage * active.AP > highestDamage) { highestDamage = damage * active.AP; highestDamageUnit = enemy; } } attackEnemy = highestDamageUnit; } else { attackEnemy = highestKillableUnit; } battle.GameUI.unitDamage = battle.Attack(attackEnemy); battle.GameUI.attackedUnitTrueX = attackEnemy.Location[0] * 55 - 13; battle.GameUI.attackedUnitTrueY = attackEnemy.Location[1] * 55 - 20; battle.GameUI.displayDamage = true; return; } //if the unit is weak, defend if(active.HP < active.MaxHP / 4 && active.AP == 1) { battle.SelectDefend(); return; } //now we check on which tile to move to List<int[]> reachableTilesAsInt = map.GetLegalMoveCoordinates(active); List<Tile> reachableTiles = new List<Tile>(); foreach (int[] coords in reachableTilesAsInt) { reachableTiles.Add(map.GetTileAt(coords[0], coords[1])); } Tile closest = map.GetTileAt(active.Location[0], active.Location[1]); int nearestTileToEnemy = 30000; foreach (Tile test in reachableTiles) { if (!test.hasUnit) { int pathCost = 0; List<Tile> path = GetPath(nearestLocation, test, map); foreach (Tile p in path) { pathCost += p.MoveCost; } if (pathCost < nearestTileToEnemy) { nearestTileToEnemy = pathCost; closest = test; } } } if (closest != map.GetTileAt(active.Location[0], active.Location[1])) { battle.StartMove(closest); return; } else { active.AP = 0; } }
//Remove units FROM THE PREGAME ROSTER public void DeleteUnit(Unit unit) { Units.Remove(unit); Points += unit.Price; if (Points > 1000) Points = 100; }
//carry out the attack, once the target is selected public int Attack(Unit target) { SelectEnabled = true; BattleMap.ClearHighlights(); List<int> combatMods = ActiveUnit.AttackModifiers; int storedDefense = target.Defense; //store the defender's defense temporarily //foreach (int mod in target.DefenseModifiers) //{ // target.Defense += mod; //temporarily add the defense modifiers to the base defense of defender //} int damage = AttackResolver.Attack(ActiveUnit, target, combatMods); GameUI.displayDamage = true; target.Defense = storedDefense; //restore defender base defense target.HP -= damage; //check if the unit is dead. if it is, turf it if (target.HP <= 0) { GameUI.sfx.PlayDieSound(target); //This is where a death animation would go IF WE HAD ONE RemoveUnit(target.Location[0], target.Location[1]); Units.Remove(target); BattleQueue.Remove(target); bool player1HasUnits = false; bool player2HasUnits = false; foreach (Unit unit in BattleQueue) { if (unit.isPlayerUnit) { player1HasUnits = true; } else { player2HasUnits = true; } } if (player1HasUnits && !player2HasUnits) { gameOver = true; GameUI.endWait = true; GameUI.p1win = true; GameUI.PlayWinMusic(); } if (player2HasUnits && !player1HasUnits) { GameUI.endWait = true; gameOver = true; GameUI.p2win = true; GameUI.PlayLoseMusic(); } } else { GameUI.sfx.PlayAttackSound(ActiveUnit); } AttackMode = false; ActiveUnit.AP--; if (ActiveUnit.AP == 0 && !GameUI.wait) NextPlayer(); return damage; }
//Add units to the pregame roster public void AddUnit(Unit unit) { if (Points - unit.Price >= 0) { Units.Add(unit); Points -= unit.Price; } }