Ejemplo n.º 1
0
    //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);
    }
Ejemplo n.º 2
0
    //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);
    }
Ejemplo n.º 3
0
    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)
            {
                didSomething = false;
                //Look at all the visitable tiles
                List <TileProxy> visitableTiles = BoardProxy.instance.GetAllVisitableNodes(unit, unit.GetMoveSpeed(), true);
                //Look at all the tiles the opposing team is on from the visitable tiles
                List <TileProxy> opposingTeamTiles = new List <TileProxy>(visitableTiles.Where(tile => tile.HasUnit() &&
                                                                                               tile.GetUnit().GetData().GetTeam() != BoardProxy.ENEMY_TEAM));
                //Look at all the tiles in range
                List <TileProxy> validTiles = BoardProxy.instance.GetAllVisitableNodes(unit, unit.GetMoveSpeed());
                if (opposingTeamTiles.Count == 0 && unit.GetData().GetTurnActions().CanMove())
                {
                    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.GetPath(start, BoardProxy.instance.GetTileAtPosition(opposingUnits[0].GetPosition()), unit);
                    //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);
                    if (dest != start)
                    {
                        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
                    {
                        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));
                        }
                    }
                }
                else if (opposingTeamTiles.Count > 0 && unit.GetData().GetTurnActions().CanAttack())
                {
                    //Unit in range. Attack!
                    Debug.Log("Trying to Attack");
                    TileProxy oppTile = BoardProxy.instance.GetTileAtPosition(opposingTeamTiles[0].GetPosition());
                    unit.OnSelected();
                    yield return(new WaitForSeconds(.5f));

                    oppTile.ForceHighlight();
                    yield return(new WaitForSeconds(.25f));

                    oppTile.UnHighlight();
                    opposingTeamTiles[0].GetUnit().OnSelected();
                    didSomething = true;
                }
                yield return(new WaitForSeconds(.25f));
            }
        }
        //No more actions, end turn
        TurnController.instance.EndTurn();
        yield return(null);
    }