void PopulatePlayer(TileProxy[] sideTiles) { PlayerMeta player = BaseSaver.GetPlayer(); //Queue<TileProxy> validTls = new Queue<TileProxy>(GetSideTiles(BoardProxy.PLAYER_TEAM)); Queue <TileProxy> validTls = new Queue <TileProxy>(sideTiles); List <UnitProxy> units = new List <UnitProxy>(); List <Unit> roster = new List <Unit>(player.characters); roster.Reverse(); //Debug.Log("PopulatePlayer: " + validTls.Count.ToString()); List <Unit> inactiveUnits = new List <Unit>(); for (int i = 3; i < roster.Count; i++) { inactiveUnits.Add(roster[i]); } for (int i = 0; i < roster.Count && i < 3; i++) { Unit cMeta = new Unit(roster[i]); //UnitProxy goodGuy = Instantiate(glossary.GetComponent<Glossary>().units[PLAYER_TEAM], transform); UnitProxy goodGuy = Instantiate(ClassNode.ComputeClassBaseUnit(cMeta.GetFactionType(), cMeta.GetUnitType(), glossary.GetComponent <Glossary>()), transform); units.Add(goodGuy); cMeta = ClassNode.ApplyClassBonusesBattle(cMeta, inactiveUnits.ToArray()); goodGuy.PutData(cMeta); goodGuy.Init(); TileProxy popTile = validTls.Dequeue(); popTile.ReceiveGridObjectProxy(goodGuy); goodGuy.SnapToCurrentPosition(); //Debug.Log("goodGuy placed at: " + popTile.GetPosition().ToString()); } }
IEnumerator GenerateAttackAnims(UnitProxy oppUnit, GameObject baseProj, Vector3 start, Vector3 finish) { TileProxy dTile = BoardProxy.instance.GetTileAtPosition(GetPosition()); dTile.CreateAnimation(Glossary.GetAtkFx(oppUnit.GetData().GetFactionType(), oppUnit.GetData().GetUnitType()), AnimationInteractionController.NO_WAIT); yield return(null); }
public Path <TileProxy> GetPathAIConsideration(TileProxy from, TileProxy to, UnitProxy thingToMove, bool allTiles = false) { return(PathGenerator.FindPath(from, to, GetDistanceFunctionAI(thingToMove, allTiles), GetEstimationFunction(to, thingToMove)));//might not want to use a list }
TileProxy CreateTile(Tile tile) { Vector3 position = grid.CellToLocal(new Vector3Int(tile.position.x, tile.position.y, 0)); TileProxy nTile = Instantiate(prefab, position, Quaternion.identity, tileMap.transform); nTile.Init(tile); return(nTile); }
TileProxy CreateTile(Tile tile) { Vector3 position = grid.CellToLocal(new Vector3Int(tile.position.x, tile.position.y, 0)); TileProxy nTile = Instantiate(prefab, position, Quaternion.identity, tileMap.transform); Glossary glossy = glossary.GetComponent <Glossary>(); nTile.Init(tile, glossy.GetGrassTile(BaseSaver.GetPlayer().world), glossy.fireTile, glossy.wallTile, glossy.divineTile, glossy.snowTile); return(nTile); }
Func <TileProxy, double> GetEstimationFunction(TileProxy destination, UnitProxy thingToMove) { return((t) => { Vector3Int t1Pos = t.GetPosition(); Vector3Int t2Pos = destination.GetPosition(); int xdiff = Mathf.Abs(t1Pos.x - t2Pos.x); int ydiff = Mathf.Abs(t1Pos.y - t2Pos.y); return xdiff + ydiff; }); }
public virtual IEnumerator CreatePathToTileAndLerpToPosition(TileProxy destination, Action callback) { var currentTile = BoardProxy.instance.GetTileAtPosition(GetPosition()); var path = BoardProxy.instance.GetPath(currentTile, destination, this); yield return(StartCoroutine(SetPathAndLerpToEnd(path))); if (callback != null) { callback(); } }
public void EvalDeath(UnitProxy unit) { TileProxy tle = BoardProxy.instance.GetTileAtPosition(unit.GetPosition()); tle.CreateAnimation(Glossary.fx.bloodExplosions); //tle.FloatUp(Skill.Actions.None,"Death", Color.red,"Character died"); AnimationInteractionController.InteractionAnimationGameobject( BoardProxy.instance.glossary.GetComponent <Glossary>().skull, tle.gameObject, AnimationInteractionController.NO_WAIT, true); tle.RemoveGridObjectProxy(unit); Destroy(unit.gameObject); EvaluateGame(); }
public override void OnTileSelected(TileProxy tile) { if (currentUnit != null && visitableTiles.Contains(tile)) { TileProxy startTile = BoardProxy.instance.GetTileAtPosition(currentUnit.GetPosition()); if (startTile != tile) { UnitProxy unit = startTile.GetUnit(); if (unit.GetData().GetTurnActions().CanMove()) { unit.GetData().GetTurnActions().Move(); PanelController.SwitchChar(unit); StartCoroutine(currentUnit.CreatePathToTileAndLerpToPosition(tile, () => { tile.ReceiveGridObjectProxy(currentUnit); startTile.RemoveGridObjectProxy(currentUnit); UnHighlightTiles(); InteractivityManager.instance.EnterDefaultMode(); })); } else { Debug.Log("Out of actions. Send signal to player they can't move unit."); } } else { StartCoroutine(currentUnit.CreatePathToTileAndLerpToPosition(tile, () => { StartCoroutine(ResetTiles()); })); } } else if (currentUnit != null) { //Select all the tiles with opp team in all tiles //List<TileProxy> visitableTiles = allTiles.Where(tl => tl.GetUnit().GetData().GetTeam() != currentUnit.GetData().GetTeam()).ToList<TileProxy>(); if (!allTiles.Where(tl => tl.HasUnit() && (tl.GetUnit().GetData().GetTeam() != currentUnit.GetData().GetTeam())).ToList <TileProxy>().Contains(tile)) { BoardProxy.instance.FlushTiles(); PanelController.SwitchChar(null); } ////Player clicked out of unit range, reset tiles/UI so player can click somewhere else instead //BoardProxy.instance.FlushTiles(); //PanelController.SwitchChar(null); } }
IEnumerator WaitForZap(TileProxy newTl, TileProxy oldTl, string actStr) { yield return(new WaitForSeconds(AnimationInteractionController.ANIMATION_WAIT_TIME_LIMIT)); newTl.ReceiveGridObjectProxy(this); //newTl.FloatUp(Skill.Actions.None, "whabam!", Color.blue, actStr); newTl.CreateAnimation(Glossary.fx.laser, 0); oldTl.RemoveGridObjectProxy(this); //oldTl.FloatUp(Skill.Actions.None, "poof", Color.cyan, actStr); oldTl.CreateAnimation(Glossary.fx.laser, 0); SetPosition(newTl.GetPosition()); SnapToCurrentPosition(); }
IEnumerator PopulateSkeleton(Vector3Int pos, UnitProxy unit, int team, int val) { yield return(new WaitForSeconds(2.2f)); TileProxy tl = tiles[pos.x, pos.y]; //if (!tl.HasUnit()) { UnitProxy newUnit = Instantiate(unit, transform); //newUnit.Init(); newUnit.PutData(Unit.BuildInitial(Unit.FactionType.Cthulhu, Unit.UnitType.Soldier, team, new CthulhuBaseWisp(), val)); newUnit.Init(); newUnit.GetData().SetSummoned(true); tl.ReceiveGridObjectProxy(newUnit); newUnit.SnapToCurrentPosition(); //} }
void PopulateEnemies() { Queue <TileProxy> validTls = new Queue <TileProxy>(GetSideTiles(BoardProxy.ENEMY_TEAM)); Debug.Log("PopulateEnemies: " + validTls.Count.ToString()); for (int i = 0; i < boardMeta.enemies.Length && i < height; i++) { //Unit cMeta = new Unit(boardMeta.enemies[i].name + i.ToString(),1); UnitProxy badGuy = Instantiate(glossary.GetComponent <Glossary>().units[ENEMY_TEAM], transform); badGuy.PutData(new Unit("e" + i.ToString(), "Snoopy Bot" + i.ToString(), 1, ENEMY_TEAM, 3, 1, 3, 3, 1, 1)); badGuy.Init(); TileProxy popTile = validTls.Dequeue(); popTile.ReceiveGridObjectProxy(badGuy); badGuy.SnapToCurrentPosition(); } }
public virtual IEnumerator LerpToTile(TileProxy tile, float time) { Vector3 start = transform.position; Vector3 end = BoardProxy.GetWorldPosition(tile.GetPosition()); float timer = 0f; while (timer < time) { // Debug.Log(transform.position); transform.position = Vector3.Lerp(start, end, timer / time); timer += Time.deltaTime; yield return(0f); } data.SetPosition(tile.GetPosition()); }
public override void DidWait(UnitProxy unit) { TileProxy uTile = BoardProxy.instance.GetTileAtPosition(unit.GetPosition()); foreach (TileProxy tl in BoardProxy.instance.GetAllVisitableNodes(unit, value + 1, true)) { bool isAttacker = tl == uTile; if (!isAttacker) { tl.FloatUp(Skill.Actions.DidAttack, "enfeeble", Color.grey, "Player enfeebled from atk"); if (tl.HasUnit() && tl.GetUnit().GetData().GetTeam() != unit.GetData().GetTeam()) { tl.GetUnit().SetEnfeebled(value); } } } }
void PopulatePlayer() { PlayerMeta player = BaseSaver.GetPlayer(); Queue <TileProxy> validTls = new Queue <TileProxy>(GetSideTiles(BoardProxy.PLAYER_TEAM)); Debug.Log("PopulatePlayer: " + validTls.Count.ToString()); for (int i = 0; i < player.characters.Length && i < height; i++) { Unit cMeta = new Unit(player.characters[i]); UnitProxy goodGuy = Instantiate(glossary.GetComponent <Glossary>().units[PLAYER_TEAM], transform); goodGuy.PutData(cMeta); goodGuy.Init(); TileProxy popTile = validTls.Dequeue(); popTile.ReceiveGridObjectProxy(goodGuy); goodGuy.SnapToCurrentPosition(); } }
public override void DidWait(UnitProxy unit) { TileProxy uTile = BoardProxy.instance.GetTileAtPosition(unit.GetPosition()); foreach (TileProxy tl in BoardProxy.instance.GetAllVisitableNodes(unit, value + 1, true)) { bool isAttacker = tl == uTile; if (!isAttacker) { tl.FloatUp(Skill.Actions.DidAttack, "nullified", Color.grey, "Unit's skills are nullified"); if (tl.HasUnit() && tl.GetUnit().GetData().GetTeam() != unit.GetData().GetTeam()) { //tl.GetUnit().GetData().SetNullified(true); tl.GetUnit().SetNullified(true); } } } }
public override void DidAttack(UnitProxy attacker, UnitProxy defender) { List <TileProxy> availableTiles = BoardProxy.instance.GetOpenTiles(); HelperScripts.Shuffle(availableTiles); if (availableTiles.Count > 0) { TileProxy oldTile = BoardProxy.instance.GetTileAtPosition(defender.GetPosition()); availableTiles.Remove(oldTile); defender.ZapToTile(availableTiles[0], oldTile, "WarpAtk"); //availableTiles[0].FloatUp(Skill.Actions.None, "whabam!", Color.blue, "WarpAtk"); //availableTiles[0].ReceiveGridObjectProxy(defender); //oldTile.FloatUp(Skill.Actions.None, "poof", Color.cyan, "WarpAtk"); //oldTile.RemoveGridObjectProxy(defender); defender.SnapToCurrentPosition(); } }
public UnitProxy GetClosestUnit(UnitProxy unit, List <UnitProxy> enemies) { //TileProxy //Path<TileProxy> path = BoardProxy.instance.GetPath(start, BoardProxy.instance.GetTileAtPosition(nearestUnit.GetPosition()), unit); TileProxy start = BoardProxy.instance.GetTileAtPosition(unit.GetPosition()); int min = int.MaxValue; UnitProxy closest = null; foreach (UnitProxy enemy in enemies) { TileProxy end = BoardProxy.instance.GetTileAtPosition(enemy.GetPosition()); Path <TileProxy> path = BoardProxy.instance.GetPath(start, end, unit); if (path.Count() < min) { min = path.Count(); closest = enemy; } } return(closest); }
public override void DidAttack(UnitProxy attacker, UnitProxy defender) { TileProxy defTile = BoardProxy.instance.GetTileAtPosition(defender.GetPosition()); TileProxy atkTile = BoardProxy.instance.GetTileAtPosition(attacker.GetPosition()); Path <TileProxy> path = BoardProxy.instance.GetPath(atkTile, defTile, defender, true); foreach (TileProxy tl in path) { if (tl != defTile && tl != atkTile) { defender.ZapToTile(tl, defTile, "VoidAtk"); //tl.FloatUp(Skill.Actions.None, "whabam!", Color.blue, "VoidAtk"); //tl.ReceiveGridObjectProxy(defender); //defTile.FloatUp(Skill.Actions.None, "poof", Color.cyan, "VoidAtk"); //defTile.RemoveGridObjectProxy(defender); //defender.SnapToCurrentPosition(); break; } } }
/* * We are trying to turn the computer into the biggest dick possible here. * If the computer can kill a unit, they will kill the unit with the highest lvl * If they cannot, they will attack the unit with the lowest level; */ public UnitProxy GetWeakestUnit(UnitProxy unit, List <UnitProxy> enemies) { TileProxy start = BoardProxy.instance.GetTileAtPosition(unit.GetPosition()); int maxLvl = int.MaxValue; List <UnitProxy> killableUnits = new List <UnitProxy>(); UnitProxy weakestUnit = null; int atk = unit.GetData().GetAttack(); foreach (UnitProxy enemy in enemies) { int currHP = enemy.GetData().GetCurrHealth(); if (atk >= currHP) { killableUnits.Add(enemy); } if (enemy.GetData().GetLvl() < maxLvl) { maxLvl = enemy.GetData().GetLvl(); weakestUnit = enemy; } } if (killableUnits.Count() > 0) { maxLvl = int.MinValue; foreach (UnitProxy enemy in killableUnits) { if (enemy.GetData().GetLvl() > maxLvl) { maxLvl = enemy.GetData().GetLvl(); weakestUnit = enemy; } } } return(weakestUnit); }
public static void InteractionDialogGameobject(Skill.Actions interaction, TileProxy tile, string msg, Color color) { //Debug.Log("Animation reason: " + animDesc); instance.StartCoroutine(instance.DialogAnim(msg, color, ReturnWaitTimeDialog(interaction), tile.GetUnit().transform)); //instance.timeLeft = ANIMATION_WAIT_TIME_LIMIT; }
public override void OnTileUnHovered(TileProxy tile) { tile.UnHighlight(); }
public override void OnClear(TileProxy tile) { tile.UnHighlight(); currentUnit = null; }
public override void OnTileUnHovered(TileProxy tile) { }
//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); }
public override void OnClear(TileProxy tile) { tile.UnHighlight(); }
public override void OnTileSelected(TileProxy tile) { // in default mode, look to select a character if possible. Then an item, etc. //tile.HighlightSelected(); }
//Something is happening with the tile that needs an animation public static void InteractionAnimation(Skill.Actions interaction, TileProxy tile, string msg, Color color, string animDesc) { //Debug.Log("Animation reason: " + animDesc); instance.StartCoroutine(instance.FloatUpAnim(msg, color, ReturnWaitTime(interaction), tile.transform)); //instance.timeLeft = ANIMATION_WAIT_TIME_LIMIT; }
/* * This returns the corner of the board furthest from the most enemies */ public TileProxy GetRetreatDest(UnitProxy unit, List <UnitProxy> enemies) { TileProxy start = BoardProxy.instance.GetTileAtPosition(unit.GetPosition()); Vector2Int dims = BoardProxy.instance.GetDimensions(); Debug.Log("Dims: " + dims); List <TileProxy> divines = BoardProxy.instance.GetDivineTiles(); int maxPths = int.MaxValue; TileProxy bestDivine = null; foreach (TileProxy divine in divines) { if (divine != null && !divine.HasObstruction()) { int pthScore = 0; Path <TileProxy> path = BoardProxy.instance.GetPath(start, divine, unit); pthScore += path.Count(); //rageatk doesnt work //attack doesn't happen after a move Debug.Log("Pos: " + divine.GetPosition() + " score: " + pthScore.ToString()); if (pthScore < maxPths) { maxPths = pthScore; bestDivine = divine; } } } if (bestDivine != null) { return(bestDivine); } List <TileProxy> corners = new List <TileProxy>(new TileProxy[] { BoardProxy.instance.GetTileAtPosition(new Vector3Int(0, 0, 0)), BoardProxy.instance.GetTileAtPosition(new Vector3Int(dims[0] - 1, 0, 0)), BoardProxy.instance.GetTileAtPosition(new Vector3Int(0, dims[1] - 1, 0)), BoardProxy.instance.GetTileAtPosition(new Vector3Int(dims[0] - 1, dims[1] - 1, 0)) }); //int maxPths = -1; TileProxy bestCorner = null; foreach (TileProxy corner in corners) { if (corner != null && !corner.HasObstruction()) { int pthScore = 0; foreach (UnitProxy enemy in enemies) { TileProxy end = BoardProxy.instance.GetTileAtPosition(enemy.GetPosition()); Path <TileProxy> path = BoardProxy.instance.GetPath(corner, end, unit); pthScore += path.Count(); } Debug.Log("Pos: " + corner.GetPosition() + " score: " + pthScore.ToString()); if (pthScore > maxPths) { maxPths = pthScore; bestCorner = corner; } } } return(bestCorner); }
//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); }