Exemplo n.º 1
0
    private void Start()
    {
        fsm         = new FSM("Cub AI");
        FleeState   = fsm.AddState("FleeState");
        FollowState = fsm.AddState("FollowState");

        FleeAction   = new FleeAction(FleeState);
        FollowAction = new FollowAction(FollowState);

        FollowState.AddAction(FollowAction);
        FleeState.AddAction(FleeAction);

        FollowState.AddTransition("ToFlee", FleeState);
        FleeState.AddTransition("ToFollow", FollowState);

        FollowAction.Init(this.transform, .1f, gameObject);
        FleeAction.Init(this.transform, .1f, gameObject);

        fsm.Start("FollowState");
    }
Exemplo n.º 2
0
    //The main loop for monster AI! This assumes
    public override IEnumerator DetermineAction()
    {
        if (monster.view == null)
        {
            Debug.LogError("Monster did not have a view available! If this happened during real gameplay, we have a problem. Eating its turn to be safe.");
            monster.UpdateLOS();
            nextAction = new WaitAction();
            yield break;
        }
        monster.view.CollectEntities(Map.current);

        List <Monster> enemies = monster.view.visibleMonsters.Where(x => (x.faction & monster.faction) == 0).ToList();

        if (enemies.Count == 0)
        {
            //Standard behavior

            //TODO: If someone is offering actions, look at their action and maybe take it

            //Else, try to go exploring!

            //Else, just wait?
            Debug.Log("Monster is just waiting!");
            nextAction = new WaitAction();
            yield break;
        }
        else
        {
            //We're majorly in combat!

            //Options
            //0 - Flee (Default)
            //1 - Fight
            //2 - Spell

            float flee     = fleeQuery.Evaluate(monster, monster.view.visibleMonsters, null, null);
            float approach = approachQuery.Evaluate(monster, monster.view.visibleMonsters, null, null);
            (int spellIndex, float spellValue) = (-1, -1);
            if (monster.abilities)
            {
                (spellIndex, spellValue) = monster.abilities.GetBestAbility();
            }

            //TODO: Determine if any items would be a good fit
            List <int> bestChoice = new List <int> {
                0
            };
            float bestVal = flee;

            //Fighting check
            if (approach > bestVal)
            {
                bestChoice.Clear();
                bestChoice.Add(1);
                bestVal = approach;
            }
            if (approach == bestVal)
            {
                bestChoice.Add(1);
            }

            //Ability check
            if (spellValue > bestVal)
            {
                bestChoice.Clear();
                bestChoice.Add(2);
                bestVal = spellValue;
            }
            if (spellValue == bestVal)
            {
                bestChoice.Add(2);
            }

            int choice = bestChoice[Random.Range(0, bestChoice.Count)];
            switch (bestChoice[Random.Range(0, bestChoice.Count)])
            {
            case 0:
                Debug.Log("Should flee!!");
                nextAction = new FleeAction();
                break;

            case 1:
                Debug.Log("Should Attack!!");
                enemies    = enemies.OrderBy(x => Vector2Int.Distance(monster.location, x.location)).ToList();
                nextAction = new PathfindAction(enemies[0].location);
                break;

            case 2:
                Debug.Log($"Should use spell {monster.abilities[spellIndex].displayName}");
                nextAction = new WaitAction();
                break;

            default:
                Debug.LogError($"Can't make choice {choice}, so waiting instead");
                nextAction = new WaitAction();
                break;
            }
        }
    }