//public void ResetAtThis() //{ // StartCoroutine(ResetTiles()); //} public override void OnUnitSelected(UnitProxy obj) { if (currentUnit == null) { UnHighlightTiles(); currentUnit = obj; //The maximum range in which a player has actions allTiles = BoardProxy.instance.GetAllVisitableNodes(obj, obj.GetMoveSpeed() > obj.GetAttackRange() ? obj.GetMoveSpeed() : obj.GetAttackRange(), true); //The attackable tiles attackableTiles = BoardProxy.instance.GetAllVisitableNodes(obj, obj.GetAttackRange(), true); //The visitable tiles visitableTiles = BoardProxy.instance.GetAllVisitableNodes(obj, obj.GetMoveSpeed()); HighlightTiles(obj); PanelController.SwitchChar(obj); } else { if (obj.GetData().GetTeam() != currentUnit.GetData().GetTeam() && allTiles.Contains(BoardProxy.instance.GetTileAtPosition(obj.GetPosition())) && currentUnit.GetData().GetTurnActions().CanAttack()) { if (obj.IsAttacked(currentUnit)) { //If the unit has died, remove it from the board and destroy the gameobject BoardProxy.instance.GetTileAtPosition(obj.GetPosition()).RemoveGridObjectProxy(obj); Destroy(obj.gameObject); ConditionTracker.instance.EvaluateGame(); //Turn off the tiles StartCoroutine(ResetTiles()); } OnDisable(); PanelController.SwitchChar(currentUnit); } } }
//public void ResetAtThis() //{ // StartCoroutine(ResetTiles()); //} public override void OnUnitSelected(UnitProxy obj) { if (!UnitMoving) { if (currentUnit == null) { toAttack = null; UnHighlightTiles(); currentUnit = obj; //The maximum range in which a player has actions allTiles = BoardProxy.instance.GetAllVisitableNodes(obj, obj.GetMoveSpeed() > obj.GetAttackRange() ? obj.GetMoveSpeed() : obj.GetAttackRange(), true); //The attackable tiles attackableTiles = BoardProxy.instance.GetAllVisitableNodes(obj, obj.GetAttackRange(), true); //The visitable tiles visitableTiles = BoardProxy.instance.GetAllVisitableNodes(obj, obj.GetMoveSpeed()); HighlightTiles(obj); PanelControllerNew.SwitchChar(obj); if (currentUnit.GetData().GetTeam() == TurnController.instance.currentTeam) { currentUnit.SaySomething(Skill.Actions.None); } CheckFocusAI(); } else { if (toAttack != obj && currentUnit != obj) { if (TurnController.instance.currentTeam == BoardProxy.PLAYER_TEAM && currentUnit.GetData().GetTeam() == BoardProxy.ENEMY_TEAM) { currentUnit = null; OnUnitSelected(obj); } else { toAttack = obj; UnitProxy player = currentUnit.GetData().GetTeam() == BoardProxy.PLAYER_TEAM ? currentUnit : toAttack; UnitProxy enemy = currentUnit.GetData().GetTeam() == BoardProxy.ENEMY_TEAM ? currentUnit : toAttack; PanelControllerNew.SwitchChar(player, enemy); } } else { if (obj.GetData().GetTeam() != currentUnit.GetData().GetTeam() && attackableTiles.Contains(BoardProxy.instance.GetTileAtPosition(obj.GetPosition())) && currentUnit.GetData().GetTurnActions().CanAttack() && !obj.GetData().IsDead()) { CheckFocusAI(); toAttack = null; bool charDead = obj.IsAttacked(currentUnit); if (currentUnit != null) { currentUnit.AcceptAction(Skill.Actions.DidAttack, obj); } if (charDead) { UnitProxy victor = BoardProxy.instance.GetTileAtPosition(currentUnit.GetPosition()).GetUnit(); victor.SaySomething(Skill.Actions.DidKill); obj.DelayedKill(obj, victor); StartCoroutine(ResetTiles()); } else { currentUnit.SaySomething(Skill.Actions.DidAttack); obj.SaySomething(Skill.Actions.DidDefend); } OnDisable(); PanelControllerNew.SwitchChar(currentUnit); } } } } }
//Vector2 ReturnIntersection(Vector3 left, Vector3 right, Vector3 up, Vector3 down){ // float A1 = right.y - left.y; // float B1 = left.x - right.x; // float C1 = A1 + B1; // float A2 = right.y - left.y; // float B2 = left.x - right.x; // float C2 = A2 + B2; // float delta = A1 * B2 - A2 * B1; // if ((int) delta == 0) // return Vector2.zero; // float x = (B2 * C1 - B1 * C2) / delta; // float y = (A1 * C2 - A2 * C1) / delta; // return new Vector2(x,y); //} //public void FocusOnUnit(UnitProxy unt){ // cam.orthographicSize = 3; // //BoardProxy.instance.transform.position = new Vector3(-1.5f,-1.5f,0); // BoardProxy.instance.transform.position = new Vector3(0,-1.5f,0); // Vector2Int dims = BoardProxy.instance.GetDimensions(); // Vector3 bLeft = BoardProxy.instance.GetTileAtPosition(new Vector3Int(0,dims[1]-1,0)).transform.position; // Vector3 bRight = BoardProxy.instance.GetTileAtPosition(new Vector3Int(dims[0]-1,0,0)).transform.position; // Vector3 bUp = BoardProxy.instance.GetTileAtPosition(new Vector3Int(dims[0]-1,dims[1]-1,0)).transform.position; // Vector3 bDown = BoardProxy.instance.GetTileAtPosition(new Vector3Int(0,0,0)).transform.position; // Vector3 bCenter = ReturnIntersection(bLeft, bRight, bUp, bDown); // Vector3 pos = unt.transform.position; // Vector3 diff = pos - bCenter; // Debug.Log("bCenter pos: " + bCenter.ToString()); // Debug.Log("pos pos: " + pos.ToString()); // Debug.Log("diff pos: " + diff.ToString()); // bCenter.x -= diff.x; // bCenter.y -= diff.y; // BoardProxy.instance.transform.position = bCenter; //} public IEnumerator BeginProcess() { yield return(new WaitForSeconds(.5f)); //List<UnitProxy> aiUnits = new List<UnitProxy>(BoardProxy.instance.GetUnits().Where(unit => unit.GetData().GetTeam() == BoardProxy.ENEMY_TEAM)); List <UnitProxy> opposingUnits = new List <UnitProxy>(BoardProxy.instance.GetUnits().Where(unit => unit.GetData().GetTeam() == BoardProxy.PLAYER_TEAM)); //Debug.Log("Beginning AI Turn"); ////Debug.Log("aiUnits: " + aiUnits.Count.ToString()); //Debug.Log("playerUnits: " + opposingUnits.Count.ToString()); Queue <UnitProxy> unitQueue = new Queue <UnitProxy>(BoardProxy.instance.GetUnits().Where(unit => unit.GetData().GetTeam() == BoardProxy.ENEMY_TEAM)); while (unitQueue.Count() > 0) { UnitProxy unit = unitQueue.Dequeue(); bool didSomething = true; while (didSomething && unit.IsAlive()) { if (!AnimationInteractionController.AllAnimationsFinished()) { yield return(new WaitForSeconds(AnimationInteractionController.ATK_WAIT)); } //Debug.Log("AI Char: " + unit.GetData().characterMoniker + " : " + unit.GetData().GetTurnActions().GetMoves() + //"/" + unit.GetData().GetTurnActions().GetAttacks()); didSomething = false; //Look at all the visitable tiles //List<TileProxy> visitableTiles = BoardProxy.instance.GetAllVisitableNodes(unit, unit.GetMoveSpeed(), true); //Look at all the attackable tiles List <TileProxy> attackableTiles = BoardProxy.instance.GetAllVisitableNodes(unit, unit.GetAttackRange(), true); //Look at all the tiles the opposing team is on from the visitable tiles List <TileProxy> opposingTeamTiles = new List <TileProxy>(attackableTiles.Where(tile => tile.HasUnit() && !tile.GetUnit().GetData().IsDead() && opposingUnits.Contains(tile.GetUnit()))); //Look at all the tiles in range List <TileProxy> validTiles = BoardProxy.instance.GetAllVisitableNodes(unit, unit.GetMoveSpeed()); if (opposingTeamTiles.Count > 0 && unit.GetData().GetTurnActions().CanAttack()) { //unit.FocusOnUnit(); //Unit in range. Attack! //Debug.Log("Trying to Attack"); TileProxy oppTile = BoardProxy.instance.GetTileAtPosition(opposingTeamTiles[0].GetPosition()); unit.OnSelected(); yield return(new WaitForSeconds(.1f)); oppTile.ForceHighlight(); yield return(new WaitForSeconds(.3f)); oppTile.UnHighlight(); opposingTeamTiles[0].GetUnit().OnSelected(); yield return(new WaitForSeconds(.5f)); opposingTeamTiles[0].GetUnit().OnSelected(); didSomething = true; bool zap = unit.GetData().GetSkills().Where(skll => skll.Contains("Force") || skll.Contains("Void") || skll.Contains("Warp")).Any(); if (zap) { yield return(new WaitForSeconds(AnimationInteractionController.AFTER_KILL)); } else { yield return(new WaitForSeconds(AnimationInteractionController.ATK_WAIT)); } } else if (opposingTeamTiles.Count == 0 && unit.GetData().GetTurnActions().CanMove()) { //FocusOnUnit(unit); //Debug.Log("Trying to Move"); TileProxy start = BoardProxy.instance.GetTileAtPosition(unit.GetPosition()); //Calculate a path from the unit to the first opposing unit (should be optimized) Path <TileProxy> path = BoardProxy.instance.GetPathAIConsideration(start, BoardProxy.instance.GetTileAtPosition(opposingUnits[0].GetPosition()), unit); if (path.Count() > 0 && path.Where(tile => validTiles.Contains(tile) && !tile.HasUnit()).Any()) { //See how many of those tiles are in the tiles we are allowed to move TileProxy dest = path.Where(tile => validTiles.Contains(tile) && !tile.HasUnit()).First(); //Get the path for highlighting path = BoardProxy.instance.GetPath(start, dest, unit); Debug.Log("Dest: " + dest.GetPosition().ToString() + " Start: " + start.GetPosition().ToString()); if (dest != start) { //unit.FocusOnUnit(); didSomething = true; foreach (TileProxy tl in path) { tl.ForceHighlight(); } yield return(new WaitForSeconds(.25f)); foreach (TileProxy tl in path) { tl.UnHighlight(); } unit.OnSelected(); yield return(new WaitForSeconds(.25f)); InteractivityManager.instance.OnTileSelected(dest); yield return(new WaitForSeconds(1f)); } else { Debug.Log("Dest not equal to start"); if (unitQueue.Count() > 0 && !unit.GetData().GetTurnActions().idle) { //If there are more ai units left to move and this ai hasn't been put in the back of the queue yet //Put unit at the end of the queue, wait for other units to move Debug.Log("Rotating AI"); unit.GetData().GetTurnActions().idle = true; unitQueue.Enqueue(unit); break; } else { Debug.Log("Removing Action"); //The unit has already failed to move twice. Stop trying. Move On. unit.GetData().GetTurnActions().Move(); didSomething = true; yield return(new WaitForSeconds(.25f)); } } } } yield return(new WaitForSeconds(.25f)); } } //yield return new WaitForSeconds(AnimationInteractionController.NO_ATK_WAIT); //No more actions, end turn TurnController.instance.EndTurn(); yield return(null); }
//Vector2 ReturnIntersection(Vector3 left, Vector3 right, Vector3 up, Vector3 down){ // float A1 = right.y - left.y; // float B1 = left.x - right.x; // float C1 = A1 + B1; // float A2 = right.y - left.y; // float B2 = left.x - right.x; // float C2 = A2 + B2; // float delta = A1 * B2 - A2 * B1; // if ((int) delta == 0) // return Vector2.zero; // float x = (B2 * C1 - B1 * C2) / delta; // float y = (A1 * C2 - A2 * C1) / delta; // return new Vector2(x,y); //} //public void FocusOnUnit(UnitProxy unt){ // cam.orthographicSize = 3; // //BoardProxy.instance.transform.position = new Vector3(-1.5f,-1.5f,0); // BoardProxy.instance.transform.position = new Vector3(0,-1.5f,0); // Vector2Int dims = BoardProxy.instance.GetDimensions(); // Vector3 bLeft = BoardProxy.instance.GetTileAtPosition(new Vector3Int(0,dims[1]-1,0)).transform.position; // Vector3 bRight = BoardProxy.instance.GetTileAtPosition(new Vector3Int(dims[0]-1,0,0)).transform.position; // Vector3 bUp = BoardProxy.instance.GetTileAtPosition(new Vector3Int(dims[0]-1,dims[1]-1,0)).transform.position; // Vector3 bDown = BoardProxy.instance.GetTileAtPosition(new Vector3Int(0,0,0)).transform.position; // Vector3 bCenter = ReturnIntersection(bLeft, bRight, bUp, bDown); // Vector3 pos = unt.transform.position; // Vector3 diff = pos - bCenter; // Debug.Log("bCenter pos: " + bCenter.ToString()); // Debug.Log("pos pos: " + pos.ToString()); // Debug.Log("diff pos: " + diff.ToString()); // bCenter.x -= diff.x; // bCenter.y -= diff.y; // BoardProxy.instance.transform.position = bCenter; //} public IEnumerator BeginProcess() { yield return(new WaitForSeconds(.5f)); //List<UnitProxy> aiUnits = new List<UnitProxy>(BoardProxy.instance.GetUnits().Where(unit => unit.GetData().GetTeam() == BoardProxy.ENEMY_TEAM)); //List<UnitProxy> opposingUnits = new List<UnitProxy>(BoardProxy.instance.GetUnits().Where(unit => unit.GetData().GetTeam() == BoardProxy.PLAYER_TEAM)); //Debug.Log("Beginning AI Turn"); ////Debug.Log("aiUnits: " + aiUnits.Count.ToString()); //Debug.Log("playerUnits: " + opposingUnits.Count.ToString()); Queue <UnitProxy> unitQueue = new Queue <UnitProxy>(BoardProxy.instance.GetUnits().Where(unit => unit.GetData().GetTeam() == BoardProxy.ENEMY_TEAM)); while (unitQueue.Count() > 0) { UnitProxy unit = unitQueue.Dequeue(); bool didSomething = true; while (didSomething && unit.IsAlive()) { if (!AnimationInteractionController.AllAnimationsFinished()) { yield return(new WaitForSeconds(AnimationInteractionController.ATK_WAIT)); } List <UnitProxy> opposingUnits = new List <UnitProxy>(BoardProxy.instance.GetUnits().Where(unt => unt.GetData().GetTeam() == BoardProxy.PLAYER_TEAM)); //Debug.Log("AI Char: " + unit.GetData().characterMoniker + " : " + unit.GetData().GetTurnActions().GetMoves() + //"/" + unit.GetData().GetTurnActions().GetAttacks()); didSomething = false; //Look at all the visitable tiles //List<TileProxy> visitableTiles = BoardProxy.instance.GetAllVisitableNodes(unit, unit.GetMoveSpeed(), true); //Look at all the attackable tiles List <TileProxy> attackableTiles = BoardProxy.instance.GetAllVisitableNodes(unit, unit.GetAttackRange(), true); //Look at all the tiles the opposing team is on from the visitable tiles List <TileProxy> opposingTeamTiles = new List <TileProxy>(attackableTiles.Where(tile => tile.HasUnit() && !tile.GetUnit().GetData().IsDead() && opposingUnits.Contains(tile.GetUnit()))); //Look at all the tiles in range List <TileProxy> validTiles = BoardProxy.instance.GetAllVisitableNodes(unit, unit.GetMoveSpeed()); bool coward = unit.GetData().LowHP() && HasHealthyUnits(); //Logic for when to wait in battle: //If you have multiple moves at the start of the turn with only one move left with more than one attack and nobody around. bool wait = false; wait = unit.GetData().GetSkills().Where(skll => skll.Contains("Wait")).Any(); wait = wait && unit.GetData().GetTurnActions().GetMoves() == 1 && unit.GetData().GetTurnActions().GetAttacks() >= 1 && opposingTeamTiles.Count == 0; //If you have multiple moves at the start of the turn with only one move left with more than one attack and nobody around. bool waitA = wait && unit.GetData().GetTurnMoves() > 1 && unit.GetData().GetTurnActions().GetMoves() == 1 && unit.GetData().GetTurnActions().GetAttacks() >= 1 && opposingTeamTiles.Count == 0; //If you didn't wait last turn, have a wait bonus, and are not somewhat injured, then go for bonus bool waitB = wait && unit.GetData().GetTurnActions().GetMoves() == 1 && unit.GetData().GetTurnActions().GetAttacks() == 1 && !unit.GetData().ModerateHP(); wait = waitA || waitB; if (waitB && unit.WaitedLastTurn()) { wait = false; unit.SetWaitedLastTurn(false); } else if (waitB) { unit.SetWaitedLastTurn(true); } if (!coward) { //If the ai can still move, but has used their attacks, move them away from the enemy team. //These are usually actions a scout would take, so we are trying to protect them here coward = !unit.GetData().GetTurnActions().CanAttack() && unit.GetData().GetTurnActions().CanMove(); } if (opposingTeamTiles.Count > 0 && unit.GetData().GetTurnActions().CanAttack() && !wait) { //unit.FocusOnUnit(); //Unit in range. Attack! TileProxy oppTile = BoardProxy.instance.GetTileAtPosition(opposingTeamTiles[0].GetPosition()); unit.OnSelected(); yield return(new WaitForSeconds(.1f)); oppTile.ForceHighlight(); yield return(new WaitForSeconds(.3f)); oppTile.UnHighlight(); opposingTeamTiles[0].GetUnit().OnSelected(); yield return(new WaitForSeconds(.5f)); opposingTeamTiles[0].GetUnit().OnSelected(); didSomething = true; bool zap = unit.GetData().GetSkills().Where(skll => skll.Contains("Force") || skll.Contains("Void") || skll.Contains("Warp")).Any(); if (zap) { yield return(new WaitForSeconds(AnimationInteractionController.AFTER_KILL)); } else { yield return(new WaitForSeconds(AnimationInteractionController.ATK_WAIT)); } } //If you need to move towards the enemies or run away, logic through here else if ((opposingTeamTiles.Count == 0 || coward) && unit.GetData().GetTurnActions().CanMove() && !wait) { //FocusOnUnit(unit); Debug.Log("Unit: " + unit.GetData().characterMoniker + " - Coward: " + coward.ToString()); TileProxy start = BoardProxy.instance.GetTileAtPosition(unit.GetPosition()); //Find the closest opposing unit UnitProxy nearestUnit = GetClosestUnit(unit, opposingUnits); //Calculate a path from the unit to the closest opposing unit Path <TileProxy> path = BoardProxy.instance.GetPathAIConsideration(start, BoardProxy.instance.GetTileAtPosition(nearestUnit.GetPosition()), unit); if (coward) { Debug.Log("Unit: " + unit.GetData().characterMoniker + " is trying to escape!"); TileProxy escapeTile = GetRetreatDest(unit, opposingUnits); if (escapeTile != null) { Debug.Log("Escape tile: " + escapeTile.GetPosition().ToString()); //Calculate a path from the unit to the closest opposing unit path = BoardProxy.instance.GetPath(start, escapeTile, unit); } } if (path.Count() > 0 && path.Where(tile => validTiles.Contains(tile) && !tile.HasUnit()).Any()) { //See how many of those tiles are in the tiles we are allowed to move TileProxy dest = path.Where(tile => validTiles.Contains(tile) && !tile.HasUnit()).First(); //if (unit.GetData().ModerateHP() && path.Where(tile => validTiles.Contains(tile) && !tile.HasUnit() && !tile.OnFire()).Any()) { // //Avoid bad tiles if we don't have too much hp // dest = path.Where(tile => validTiles.Contains(tile) && !tile.HasUnit() && !tile.OnFire()).First(); //} //If the unit is not trying to run away from battle if (!coward) { /* * If the ai is allowed to move to a tile and it has ranged, * you want to land it a bit further away from it's target. * If the dest and the original target are the same we need to * subtract moves from the path over 2 moves */ int atkDiff = unit.GetData().GetAtkRange() - 1; //The distance between the ai's destination and the enemy the ai is planning to attack in the future TileProxy[] rngPth = BoardProxy.instance.GetPath(dest, BoardProxy.instance.GetTileAtPosition(nearestUnit.GetPosition()), unit).ToArray(); if (atkDiff > 0 && rngPth.Count() <= atkDiff) { List <TileProxy> listPth = path.ToList(); int dstIdx = listPth.IndexOf(dest); if (dstIdx + atkDiff - 1 <= listPth.Count() - 1) { dest = listPth[dstIdx + atkDiff - 1]; } } } //Get the path for highlighting path = BoardProxy.instance.GetPath(start, dest, unit); if (dest != start) { //unit.FocusOnUnit(); didSomething = true; foreach (TileProxy tl in path) { tl.ForceHighlight(); } yield return(new WaitForSeconds(.25f)); foreach (TileProxy tl in path) { tl.UnHighlight(); } unit.OnSelected(); yield return(new WaitForSeconds(.25f)); InteractivityManager.instance.OnTileSelected(dest); yield return(new WaitForSeconds(1f)); if (path.Where(tl => tl.OnFire()).Any()) { yield return(new WaitForSeconds(1f)); } } else { if (unitQueue.Count() > 0 && !unit.GetData().GetTurnActions().idle) { //If there are more ai units left to move and this ai hasn't been put in the back of the queue yet //Put unit at the end of the queue, wait for other units to move unit.GetData().GetTurnActions().idle = true; unitQueue.Enqueue(unit); break; } else { //The unit has already failed to move twice. Stop trying. Move On. unit.GetData().GetTurnActions().Move(); didSomething = true; yield return(new WaitForSeconds(.25f)); } } } } yield return(new WaitForSeconds(.25f)); } } //yield return new WaitForSeconds(AnimationInteractionController.NO_ATK_WAIT); //No more actions, end turn TurnController.instance.EndTurn(); yield return(null); }