public static IEnumerator CheckForTurnEnd() { CombatLog.UpdateCombatLog("Action complete."); if (queuedActions < 1) { Debug.LogWarning("zero or less queued actions"); } if (queuedActions > 1) { queuedActions--; yield break; } else { OnActionTaken(currentUnit); actionUIManager.UpdateActions(currentUnit.GetComponent <TacticsMovement>()); queuedActions--; //yield return new WaitForSeconds(0.5f); if (currentUnit.remainingMove >= 1 || currentUnit.remainingActions > 0) { currentUnit.GetComponent <TacticsMovement>().BeginTurn(); yield break; } if (currentUnit.focusSwitched == false) { currentUnit.canFocusSwitch = true; yield break; } initiativeManager.StartCoroutine(EndTurn()); yield break; } }
public override void DoTask(NPC unit, Unit targetUnit = null, Tile targetTile = null) { //find a square to move to that isn't next to an enemy. if (unit.remainingMove > 0 && moved == false) { unit.FindSelectableTiles(); List <Tile> tiles = RangeFinder.FindTilesNotNextToEnemy(unit, unit.selectableTiles, Factions.players); int roll = Random.Range(0, tiles.Count); if (tiles[roll] != null) { Initiative.queuedActions++; CombatLog.UpdateCombatLog(unit.name + " moves toward opposing faction."); unit.MoveToTile(tiles[roll]); moved = true; return; } } //and defend if able. if (unit.remainingActions > 0) { unit.defend.ExecuteAction(ActionCost.main); CombatLog.UpdateCombatLog(unit.name + " defends."); flagEndofTurn = true; return; } flagEndofTurn = true; }
static void StartTurn() { currentUnit = order.Peek(); currentUnit.ResetActions(); order.Peek().BeginTurn(); GameObject selector = GameObject.FindGameObjectWithTag("selector"); selector.transform.SetParent(currentUnit.transform, false); actionUIManager.UpdateActions(currentUnit.GetComponent <TacticsMovement>()); CinemachineCamera.FollowUnit(currentUnit.GetComponent <TacticsMovement>()); OnTurnStart(currentUnit); CombatLog.UpdateCombatLog(currentUnit.name + "(" + currentUnit.gameObject.GetInstanceID() + ")" + " starts turn."); }
//This needs sorting out. public IEnumerator KO() { Initiative.queuedActions++; CombatLog.UpdateCombatLog(name + " KOed."); onKO(this); unitAnim.SetBool("dead", true); yield return(new WaitForSeconds(unitAnim.GetCurrentAnimatorStateInfo(0).length + 2)); gameObject.GetComponent <TacticsMovement>().currentTile.occupant = null; //Tell the initiative order to remove this unit. Initiative.RemoveUnit(this); }
public override void DoTask(NPC unit, Unit targetUnit = null, Tile targetTile = null) { //Attack the target if possible. if (unit.remainingActions > 0) { //unit.FindAdjacentUnits(); RangeFinder.FindAdjacentUnits(unit); if (target != null) { if (unit.adjacentUnits.Contains(target)) { foreach (Weapon.Target t in unit.mainWeapon.targets) { if (t.unitTargeted == target) { Initiative.queuedActions += 1; unit.mainWeapon.StartCoroutine("Attack", t); CombatLog.UpdateCombatLog(unit.name + " melee attacks " + target.name); flagEndofTurn = true; return; } } } } } //Dash if that's needed Tile tileToAttackFrom = RangeFinder.FindTileNextToTarget(unit, target.GetComponent <TacticsMovement>()); if (tileToAttackFrom == null) { if (unit.remainingActions > 0) { unit.dash.ExecuteAction(ActionCost.main); CombatLog.UpdateCombatLog(unit.name + " dashes."); dashed = true; } } //Move closer to the target if needed. if ((unit.remainingMove > 0 && unit.remainingActions > 0) || dashed == true) { unit.destination = target.gameObject; CombatLog.UpdateCombatLog(unit.name + " A* toward opposing faction."); dashed = false; } else { flagEndofTurn = true; } }
public override void DoTask(NPC unit, Unit targetUnit = null, Tile targetTile = null) { //Attack the target if possible. if (unit.remainingActions > 0) { RangeFinder.FindAdjacentUnits(unit); if (target != null) { if (unit.adjacentUnits.Contains(target)) { foreach (Weapon.Target t in unit.mainWeapon.targets) { if (t.unitTargeted == target) { Initiative.queuedActions++; CombatLog.UpdateCombatLog(unit.name + " melee attacks " + target.name); unit.mainWeapon.StartCoroutine("Attack", t); flagEndofTurn = true; return; } } } } } //Move closer to the target if needed. if (unit.remainingMove > 0 && unit.remainingActions > 0) { if (!movedCloser) { unit.destination = target.gameObject; CombatLog.UpdateCombatLog(unit.name + " A* toward opposing faction."); movedCloser = true; return; } } //Defend if you've not reached the target if (unit.remainingActions > 0) { CombatLog.UpdateCombatLog(unit.name + " defends."); unit.defend.ExecuteAction(ActionCost.main); return; } flagEndofTurn = true; }
public static IEnumerator EndTurn(bool delay = false) { CombatLog.UpdateCombatLog(currentUnit.name + "(" + currentUnit.gameObject.GetInstanceID() + ")" + " ends turn. \r\n"); currentUnit = null; TacticsMovement unit = order.Dequeue(); unit.EndTurn(); if (delay == true) { yield return(new WaitForSeconds(1f)); } order.Enqueue(unit); StartTurn(); yield break; }
IEnumerator PositioningUnits() { //Checks to see if there are present enemies in the scene. If there are it will block new enemies being bought in. GameObject presetEnemy = GameObject.FindGameObjectWithTag("character"); //This waits to give the player data time to catch up. Hopefully not needed once the player data persists between scenes. yield return(new WaitForSeconds(0.1f)); GetPlayers(); if (presetEnemy == null) { GetEnemies(); } yield return(new WaitForSeconds(0.1f)); ArenaBuilder.BuildArena(); SetPositions(); CombatLog.UpdateCombatLog("Units ready!"); yield break; }
public override void DoTask(NPC unit, Unit targetUnit = null, Tile targetTile = null) { //Dash if that's needed if (unit.remainingActions > 0 && dashed == false) { unit.dash.ExecuteAction(ActionCost.main); CombatLog.UpdateCombatLog(unit.name + " dashes."); dashed = true; return; } //Then run if (unit.remainingMove > 0) { unit.FindSelectableTiles(); Initiative.queuedActions++; CombatLog.UpdateCombatLog(unit.name + " moves away from opposing unit."); unit.MoveToTile(RangeFinder.FindTileFurthestFromOpponents(unit, unit.selectableTiles)); flagEndofTurn = true; } }
public override void DoTask(NPC unit, Unit targetUnit = null, Tile targetTile = null) { //Check to see if the target has been removed. If so, end turn. if (target == null && attacked == true) { flagEndofTurn = true; return; } //if a flank is available, move to it. if (!inFlankingPosition && !firstMoveDone) { unit.FindSelectableTiles(); Tile flankingTile = RangeFinder.FindFlankingTile(unit, unit.selectableTiles, target.GetComponent <TacticsMovement>()); if (flankingTile != null && unit.remainingMove > 0) { inFlankingPosition = true; Initiative.queuedActions++; CombatLog.UpdateCombatLog(unit.name + " moves to flank."); unit.MoveToTile(flankingTile); firstMoveDone = true; return; } } //Move as close as possible if main action is available and you're not next to the target. RangeFinder.FindAdjacentUnits(unit); if (!unit.adjacentUnits.Contains(target) && !firstMoveDone) { if (unit.remainingActions > 0 && unit.remainingMove > 0) { unit.destination = target.gameObject; CombatLog.UpdateCombatLog(unit.name + " A* toward opposing faction."); firstMoveDone = true; return; } } //Attack if in the right position if (unit.remainingActions > 0) { RangeFinder.FindAdjacentUnits(unit); if (unit.adjacentUnits.Contains(target)) { foreach (Weapon.Target t in unit.mainWeapon.targets) { if (t.unitTargeted == target) { Initiative.queuedActions += 1; unit.mainWeapon.StartCoroutine("Attack", t); CombatLog.UpdateCombatLog(unit.name + " attacks " + target.name); attacked = true; return; } } } } //Move away if you have move left if (unit.remainingMove >= 1) { unit.FindSelectableTiles(); //A Hack to solve the bug 'characters teleport rather than move, and can share spaces'. This isn't working. TacticsMovement targetT = target.GetComponent <TacticsMovement>(); targetT.GetCurrentTile(); if (unit.selectableTiles.Contains(targetT.currentTile)) { unit.selectableTiles.Remove(targetT.currentTile); } List <Tile> preferedTiles = RangeFinder.FindTilesNotNextToEnemy(unit, unit.selectableTiles, Factions.players); if (preferedTiles.Count > 0) { Initiative.queuedActions++; CombatLog.UpdateCombatLog(unit.name + " moves away."); unit.MoveToTile(preferedTiles[Random.Range(0, preferedTiles.Count)]); flagEndofTurn = true; return; } } //Defend if you've not reached the target if (unit.remainingActions > 0) { CombatLog.UpdateCombatLog(unit.name + " defends."); unit.defend.ExecuteAction(ActionCost.main); return; } flagEndofTurn = true; }
public override void DoTask(NPC unit, Unit targetUnit = null, Tile targetTile = null) { RangedWeapon weapon = unit.GetComponent <RangedWeapon>(); //Check to see if you've killed the enemy. if (target == null) { flagEndofTurn = true; return; } //check to see if an enemy is adjacent and then move. if (unit.remainingMove > 0) { RangeFinder.FindAdjacentUnits(unit); foreach (Unit u in unit.adjacentUnits) { if (u.unitInfo.faction != unit.unitInfo.faction) { List <Tile> tiles = RangeFinder.FindTilesWithLineOfSight(unit, unit.selectableTiles, target.GetComponent <TacticsMovement>()); tiles = RangeFinder.FindTilesNotNextToEnemy(unit, tiles, Factions.players); if (tiles.Count > 0) { Initiative.queuedActions++; CombatLog.UpdateCombatLog(unit.name + " moves away to avoid ranged hindrance."); unit.MoveToTile(tiles[Random.Range(0, tiles.Count)]); return; } } } } //Reload if required. if (weapon.rangedWeaponData.currentAmmo == 0) { if (weapon.rangedWeaponData.reloadSpeed == ActionCost.move && (unit.remainingMove == unit.unitInfo.currentMove)) { weapon.Reload(ActionCost.move); CombatLog.UpdateCombatLog(unit.name + " reloads as a move action."); flagEndofTurn = true; return; } else if (unit.remainingActions > 0) { weapon.Reload(ActionCost.main); CombatLog.UpdateCombatLog(unit.name + " reloads as a main action."); flagEndofTurn = true; return; } else { if (unit.remainingMove > 0) { Initiative.queuedActions++; CombatLog.UpdateCombatLog(unit.name + " moves as far from opposing faction as possible."); unit.MoveToTile(RangeFinder.FindTileFurthestFromOpponents(unit, unit.selectableTiles)); return; } } } //If you've not got line of sight, get it. if (!RangeFinder.LineOfSight(unit, target) && unit.remainingMove >= 1) { //Find a tile to move to that has LoS, ideally one that isn't next to an enemy. unit.FindSelectableTiles(); List <Tile> tiles = RangeFinder.FindTilesWithLineOfSight(unit, unit.selectableTiles, target.GetComponent <TacticsMovement>()); if (tiles.Count > 0) { List <Tile> preferedTiles = RangeFinder.FindTilesNotNextToEnemy(unit, tiles, Factions.players); Initiative.queuedActions++; CombatLog.UpdateCombatLog(unit.name + " moves to get line of sight."); if (preferedTiles.Count > 0) { unit.MoveToTile(tiles[Random.Range(0, preferedTiles.Count)]); } else { unit.MoveToTile(tiles[Random.Range(0, tiles.Count)]); } } else { //if you can't get to a place you can see from, A* toward the target. unit.destination = target.gameObject; CombatLog.UpdateCombatLog(unit.name + " A* toward opposing faction."); } return; } //If you've not got focus, get it. if (unit.focus == null) { if (RangeFinder.LineOfSight(unit, target)) { unit.SetFocus(target); flagEndofTurn = true; CombatLog.UpdateCombatLog(unit.name + " focuses on opposing faction."); return; } } //shoot if (RangeFinder.LineOfSight(unit, target) && unit.remainingActions > 0 && weapon.rangedWeaponData.currentAmmo > 0 && target == unit.focus) { Debug.Log("goes to attack"); foreach (Weapon.Target t in unit.mainWeapon.targets) { if (t.unitTargeted == target) { Initiative.queuedActions += 1; unit.mainWeapon.StartCoroutine("Attack", t); CombatLog.UpdateCombatLog(unit.name + " shoots at " + target.name); flagEndofTurn = true; return; } } } //and defend if able. if (unit.remainingActions > 0) { unit.defend.ExecuteAction(ActionCost.main); CombatLog.UpdateCombatLog(unit.name + " defends"); flagEndofTurn = true; return; } flagEndofTurn = true; }
//For now this will just be hitting or missing (no crits). //Crits and detailed attack data should probably be stored as variables on the attack manager, or even into seperate 'attackData' classes that are per attack. s public static Result AttackRoll(Unit _attacker, Unit _defender, int _bonuses = 0) { ResetValues(); attacker = _attacker; defender = _defender; attack += attacker.unitInfo.currentAttack; bonuses += _bonuses; OnAttack(attacker, defender); DecideDefence(attacker, defender); //check conditions if (defender.unitInfo.flagging) { bonuses++; } //check focus if (attacker.focus != defender) { attacker.gameObject.GetComponent <UnitPopUpManager>().AddPopUpInfo("Astray"); bonuses--; attacker.focus = defender; attacker.focusSwitched = true; } else if (defender.focus != attacker) { attacker.gameObject.GetComponent <UnitPopUpManager>().AddPopUpInfo("Blindsiding"); bonuses++; } //check for weight if (attacker.unitInfo.mainWeaponData.weight >= ItemData.Weight.medium) { attacker.UpdateBreath(-1, true); if (attacker.unitInfo.mainWeaponData.weight > ItemData.Weight.medium) { damage += (int)attacker.unitInfo.mainWeaponData.weight; } } AbilityCheck.CheckAbility(attack, defence, bonuses); attackRolled = true; //Work out criticals CriticalManager.Reset(); if (autocrit) { AbilityCheck.crits = Mathf.Max(AbilityCheck.crits, 1); } for (int count = 0; count < AbilityCheck.crits; count++) { CriticalManager.AddCritical(attacker.mainWeapon); } //Resolve all pre-damage criticals. foreach (Critical c in CriticalManager.criticalChain) { if (c.AfterDamage() == false) { c.CriticalEffect(); } } //Work out the result if (AbilityCheck.baseResult >= 0) { CombatLog.UpdateCombatLog(attacker.name + " attacks " + defender.name + " and scores a success."); return(Result.SUCCESS); } if (AbilityCheck.baseResult >= -9) { if (defenceType == DefenceType.DODGE) { defender.GetComponent <TacticsMovement>().Dodge(Result.PARTIAL); defender.gameObject.GetComponent <UnitPopUpManager>().AddPopUpInfo("dodged"); } if (defender.focus != attacker) { defender.SetFocus(attacker); } CombatLog.UpdateCombatLog(attacker.name + " attacks " + defender.name + " and scores a partial."); return(Result.PARTIAL); } else { if (defenceType == DefenceType.DODGE) { defender.GetComponent <TacticsMovement>().Dodge(Result.FAIL); defender.gameObject.GetComponent <UnitPopUpManager>().AddPopUpInfo("evaded"); } defender.gameObject.GetComponent <UnitPopUpManager>().AddPopUpInfo("miss"); CombatLog.UpdateCombatLog(attacker.name + " attacks " + defender.name + " and scores a fail."); return(Result.FAIL); } }