コード例 #1
0
    void RunBattleSimulation()
    {
        // 2 states - Select Action and Execute Action
        // on select action set the actor to the current
        // show the UI for where the default action will place them

        switch (state)
        {
        case BossBattleState.EndOfTurn:
            break;

        case BossBattleState.NewTurn:

            // Clean up the list of dead actors
            List <BattleActor> removeList = new List <BattleActor>();
            foreach (BattleActor actor in TurnOrder)
            {
                if (actor.Health <= 0f)
                {
                    actor.StopCast();
                    battleInterface.RemoveActorPortrait(actor);
                    removeList.Add(actor);
                    deadActors.Add(actor);
                    if (actor is BossActor)
                    {
                        ((BossActor)actor).handler.Die();
                    }
                    else
                    {
                        ((HeroActor)actor).handler.Die();
                    }
                }
            }

            bool bossKilled = false;
            foreach (BattleActor actor in removeList)
            {
                if (actor is BossActor)
                {
                    bossKilled = true;
                }

                TurnOrder.Remove(actor);
            }

            if (bossKilled)
            {
                // on allyDeathTrigger
                foreach (BattleActor actor in TurnOrder)
                {
                    if (actor is BossActor)
                    {
                        ((BossActor)actor).OnAllyDeath();
                    }
                }
            }

            currentActor = TurnOrder[0];
            selector.GoToTarget(currentActor.GetGameObject().transform.position);

            if (currentActor is HeroActor)
            {
                print(" --- [New Turn]\n   Hero Turn: " + currentActor.Name);
            }
            else
            {
                print(" --- [New Turn]\n   Boss Turn: " + currentActor.Name);
            }

            // Check if the current actor is stunned here and skip their turn
            if (currentActor.IsStunned())
            {
                // Spawn text displaying this actor is stunned then return to restart this turn and choose a new actor
                currentActor.UpdateStatusEffects(StatusTriggerTime.StartOfTurn);
                currentActor.UpdateStatusEffects(StatusTriggerTime.EndOfTurn);
                return;
            }

            // this position allows stun transitions to be delayed when stunned, we can move this above the stun code block to change this
            if (currentActor is BossActor)
            {
                ((BossActor)currentActor).UpdateTurnCount();
            }

            //Check for end of battle here
            if (IsBattleComplete())
            {
                state = BossBattleState.EndOfBattle;
            }
            else
            {
                // Check if the actor has a skill waiting to be used
                if (currentActor.HasQueuedSkill())
                {
                    // Skip straight to the use the skill part of a turn
                    SelectSkill(currentActor.QueuedSkill);
                    ExecuteSkill(currentActor.QueuedSkillTarget, true);
                    currentActor.QueuedSkill       = null;
                    currentActor.QueuedSkillTarget = null;
                }
                else
                {
                    state = BossBattleState.SelectAction;
                }
            }
            break;

        case BossBattleState.SelectAction:
            battleInterface.SetCurrentTurn(currentActor);
            currentActor.UpdateStatusEffects(StatusTriggerTime.StartOfTurn);

            // Load UI for the hero or hide it on enemy
            if (currentActor is HeroActor)
            {
                // Reduce skill cooldowns by a turn
                foreach (Skill skill in ((HeroActor)currentActor).hero.Skills)
                {
                    /*if (((HeroActor) currentActor).hero.Skills[skill] > 0)
                     *  ((HeroActor) currentActor).hero.Skills[skill] -= 1;*/
                    if (skill._cooldown > 0)
                    {
                        skill._cooldown--;
                    }
                }

                battleInterface.ShowMemberArea((HeroActor)currentActor);
                SelectSkill(((HeroActor)currentActor).hero.Skills[((HeroActor)currentActor).hero.Skills.Count - 1]);     // default skill selected

                bossTurn = false;
            }
            else
            {
                SelectSkill(((BossActor)currentActor).boss.Skills[0]);

                // Choose a skill based on how many targets
                int  targetCount   = 0;
                bool targetCasting = false;
                foreach (HeroActor actor in Party)
                {
                    if (actor.Health > 0)
                    {
                        targetCount++;
                    }
                    if (actor.QueuedSkill != null)
                    {
                        targetCasting = true;
                    }
                }

                Skill skillSelect = null;
                foreach (Skill skill in ((BossActor)currentActor).boss.Skills)
                {
                    if (skill._cooldown < 1 && skill.CanInterrupt)
                    {
                        skillSelect = skill;
                    }
                }
                // TODO put the interrupt AI chance on the boss data it self, current set to 25% of the time
                if (targetCasting && Random.Range(0f, 1f) < 0.25f && skillSelect != null)
                {
                    // Choose the skill that can interrupt
                    SelectSkill(skillSelect);
                }
                else if (targetCount > 2)
                {
                    // It can be an AOE skill
                    bool hasAOE = false;
                    foreach (Skill skill in ((BossActor)currentActor).boss.Skills)
                    {
                        if (skill._cooldown < 1 && skill.TargetType != SkillTargetType.SingleTarget)
                        {
                            hasAOE = true;
                            SelectSkill(skill);
                            continue;
                        }
                    }

                    if (!hasAOE)
                    {
                        foreach (Skill skill in ((BossActor)currentActor).boss.Skills)
                        {
                            if (skill._cooldown < 1)
                            {
                                SelectSkill(skill);
                                continue;
                            }
                        }
                    }
                }
                else
                {
                    // Not AOE skill
                    foreach (Skill skill in ((BossActor)currentActor).boss.Skills)
                    {
                        if (skill._cooldown < 1)
                        {
                            SelectSkill(skill);
                            continue;
                        }
                    }
                }


                // if target count is >= 3 then you can use an AOE skill
                // otherwise use your best ability thats not an attack
                // if no other abilities then use an attack

                bossTurn = true;
            }

            state = BossBattleState.WaitForAction;
            break;

        case BossBattleState.ExecuteAction:
            //print("Execute Action");
            // Do Queued Actions then (if there is a heal on multiple members or an attack that hits multiple targets etc)

            if (!PlayerPrefs.HasKey("tutorial_boss_battle_castable_skill"))
            {
                foreach (BattleActor actor in TurnOrder)
                {
                    if (actor is BossActor && ((BossActor)actor).QueuedSkill != null)
                    {
                        StoryManager.Instance.DisplayStory("story_tutorial_boss_battle_interrupt");

                        PlayerPrefs.SetInt("tutorial_boss_battle_castable_skill", 1);
                    }
                }
            }
            // go to the next actor
            currentActor.UpdateStatusEffects(StatusTriggerTime.EndOfTurn);
            //state = BossBattleState.NewTurn;
            StartEndOfTurn();
            break;

        case BossBattleState.WaitForAction:

            // Update the turn order position based on selected skill
            if (bossTurn && bossActionRoutine == null)
            {
                AIActionSelect();
            }

            // Select skill from UI
            // on target select add the ability to the queue and
            if (Input.GetMouseButtonDown(0) && !bossTurn && executeActionRoutine == null)
            {
                // see what we tapped, but for now just use the action
                RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
                //fctLocation = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                if (hit.collider != null)
                {
                    BattleActor target = null;
                    //Debug.Log("Target Position: " + hit.collider.gameObject.transform.position + " | hit: " + hit.collider.gameObject.name);

                    CharacterHandler h_handler = hit.collider.gameObject.GetComponent <CharacterHandler>();
                    if (h_handler != null)
                    {
                        print("Have CharacterHandler");
                        // Is a hero
                        foreach (BattleActor hA in TurnOrder)
                        {
                            if (hA is HeroActor)
                            {
                                if (((HeroActor)hA).handler == h_handler)
                                {
                                    target = hA;
                                }
                            }
                        }
                        print(target);
                        if (target != null)
                        {
                            ExecuteSkill(target);
                        }
                    }
                    MonsterHandler m_handler = hit.collider.gameObject.GetComponent <MonsterHandler>();
                    if (m_handler != null)
                    {
                        // Is a monster
                        foreach (BattleActor bA in TurnOrder)
                        {
                            if (bA is BossActor)
                            {
                                if (((BossActor)bA).handler == m_handler)
                                {
                                    target = bA;
                                }
                            }
                        }
                        //print(target);
                        if (target != null)
                        {
                            ExecuteSkill(target);
                        }
                    }
                }
            }
            break;

        case BossBattleState.EndOfBattle:
            bool heroStillExists = false;
            bool bossStillExists = false;
            foreach (BattleActor actor in TurnOrder)
            {
                if (actor is HeroActor)
                {
                    heroStillExists = true;
                }
                if (actor is BossActor)
                {
                    bossStillExists = true;
                }
            }

            ActiveExploration activeZone = playerMan.SelectedBattle;

            if (!bossStillExists)
            {
                // Player won
                float chance = 0.2f + Mathf.Min((activeZone.TreasureFind / 3000f), 0.75f) * 0.8f;
                for (int i = 0; i < dataMan.globalData.GetGlobalAsInt(GlobalProps.ZONE_MONSTER_COUNT); i++)
                {
                    if (Random.Range(0f, 1f) <= chance)
                    {
                        LootCrateScreenInterface.GenerateLootCrate(activeZone, MagicFindBoostMultiplier: playerMan.GetBoost(BoostType.MagicFind));
                    }
                }
                for (int i = 0; i < activeZone.ChestsEarned; i++)
                {
                    LootCrateScreenInterface.GenerateLootCrate(activeZone, MagicFindBoostMultiplier: playerMan.GetBoost(BoostType.MagicFind));
                }
                LootCrateScreenInterface.GenerateLootCrate(activeZone, TriggerInterfaceAfterLootCratesAdded, true, playerMan.GetBoost(BoostType.MagicFind));
            }
            else if (!heroStillExists)
            {
                // Player was defeated
                StartCoroutine(ResurrectForGems(activeZone));
            }

            playerMan.CurrentLeaderSkill = null;
            state = BossBattleState.ShowResults;

            break;

        case BossBattleState.ShowResults:
            break;
        }
    }