Exemplo n.º 1
0
    public IEnumerator TurnCycle(Team team, Team team2)
    {
        // AI calculations list of commands
        // yield return execute calculated commands and moves
        yield return(new WaitForSeconds(5));

        Debug.Log("End Enemy turn");

        /*stategies:
         * Scoring nearby slots based on utility.
         * n^2 n = around 20 = 400 per character
         *
         */
        for (int i = 0; i < team.units.Count; i++)
        {
            Soldier unit = team.units[i];

            //Generate data for all slots in move range and for soldiers in range that can be attacked. taken move slots are excluded.
            GridSlot[]   slots          = GridSlot.GetAvaliableSlotsInMoveRange(unit.curPositionSlot, unit.fullMovementRange);
            Soldier[]    enemiesInRange = GridSlot.GetVisibleEnemySlots(unit, team2);
            AiSlotData[] moveData       = new AiSlotData[slots.Length];
            AiSlotData[] enemyData      = new AiSlotData[enemiesInRange.Length];
            moveScores  = new int[moveData.Length];
            enemyScores = new int[enemyData.Length];
            for (int j = 0; j < slots.Length; j++)
            {
                moveData[j] = new AiSlotData(slots[j].id);
            }
            for (int j = 0; j < enemyData.Length; j++)
            {
                enemyData[j] = new AiSlotData(enemiesInRange[j].soldierId);
            }
            // Calculations have to be remade for every slots for every enemy. Not good.
            // Utility score.
            // + when enemies are on slot. +100
            // + cover height +0 +50 +100
            // - distance to enemy (gt dist, less)
            //

            /* how to choose to move vs choose to attack
             * just distance
             * */
            // here we choose which actions will be prioritized, movement or shooting.
            int possibleMoveActions = 0;
            int attack = -1;
            if (enemiesInRange.Length == 0)
            {
                continue;
            }
            attack = 0; // shoot, when there are some enemies
            float dist = Vector3.Distance(enemiesInRange[0].transform.position, unit.transform.position);
            if (dist <= unit.movementRange1)
            {
                possibleMoveActions = 1;
            }
            if (enemiesInRange.Length == 0)
            {
                possibleMoveActions = 2;
                attack = -1;
            }

            int bestId = -1;
            int best   = 0;
            // calculates scores for movement slots
            for (int j = 0; j < moveData.Length; j++)
            {
                moveData[j].score = (int)(ClampedReverseDist(unit, unit.fullMovementRange, slots, j)
                                          * MapGrid.CoverScoreMultiplier(slots[j]));
                if (moveData[j].score > best)
                {
                    best   = moveData[j].score;
                    bestId = j;
                }
                moveScores[j] = moveData[j].score;
            }
            GameplayManager.m.moveScores = moveScores;
            int       bestMoveDataId = bestId;
            GridSlot  bestMove       = slots[bestMoveDataId];
            MapNode[] path           = Pathfinding.FindPathAStar(unit.curPositionSlot.transform.position, bestMove.transform.position, MapGrid.wholeMap);
            yield return(unit.StartCoroutine(MoveToSlot(team, team2, bestMove, path)));

            if (attack != -1)
            {
                // calculates scores for enemies
                bestId = -1;
                for (int j = 0; j < enemyData.Length; j++)
                {
                    enemyData[j].score = (int)(ClampedDist(enemiesInRange[j], 100, slots, j)
                                               * MapGrid.CoverScoreMultiplier(enemiesInRange[j].curPositionSlot));
                    if (enemyData[j].score > best)
                    {
                        best   = enemyData[j].score;
                        bestId = j;
                    }
                    enemyScores[j] = enemyData[j].score;
                }
                int bestEnemyDataId = bestId;
                if (bestEnemyDataId != -1)
                {
                    Soldier bestEnemy = enemiesInRange[bestEnemyDataId];

                    unit.AttackSlot(bestEnemy.curPositionSlot);
                    GameplayManager.m.enemyScores = enemyScores;
                }
                else
                {
                    Debug.Log("No enemies in range");
                }
            }

            team.ActiveSoldier.HandleCover();
            SwapSoldier(team);
        }
    }