Beispiel #1
0
        public void Execute(IBattleParticipant target)
        {
            target.HpCurrent -= DamageAmount;

            if (Duration != 0)
            {
                Duration = (Duration == INFINITE) ? INFINITE : Duration - 1;
            }

            log.Debug($"Hit {target.Name} for {DamageAmount} damage ({target.HpCurrent}/{target.HpMax})");
        }
Beispiel #2
0
        private static IBattleParticipant FindSlowBoi(List <IBattleParticipant> bps)
        {
            IBattleParticipant slowboi = bps.First();

            foreach (IBattleParticipant bp in bps)
            {
                if (slowboi.TurnMeterIncreaseOnClockTick > bp.TurnMeterIncreaseOnClockTick)
                {
                    slowboi = bp;
                }
            }

            return(slowboi);
        }
Beispiel #3
0
        public AutoBattle(IBattleParticipant attacker, IBattleParticipant defender, CommandContext c)
        {
            log = Serilog.Log.ForContext <AutoBattle>();

            Attacker = attacker;
            Defender = defender;
            cmdCtx   = c;

            Round           = 0;
            CombatLog       = new List <string>();
            AttackerAttacks = new List <Attack>();
            DefenderAttacks = new List <Attack>();

            CombatId = Guid.NewGuid().ToString().Substring(0, 8);
        }
Beispiel #4
0
    public void Setup(IBattleParticipant a, IBattleParticipant b)
    {
        transform.position = a.position;
        this.a             = a;
        this.b             = b;
        Vector3 dir  = (b.position - a.position).normalized;
        float   sign = dir.x < 0? -1f: 1f;

        transform.rotation = Quaternion.Euler(0, 0, sign * Mathf.Asin(dir.y) * Mathf.Rad2Deg);
        if (sign < 0)
        {
            Transform tmp = defenderMorale;
            defenderMorale = attackerMorale;
            attackerMorale = tmp;
        }
        UpdateMorale(true);
        StartCoroutine(Fight());
    }
Beispiel #5
0
        private IEnumerable <List <ClanBossBattleResult> > Run(bool exploreAllSequences, bool failOnKill)
        {
            Queue <CBBState> battleStates = new Queue <CBBState>();

            battleStates.Enqueue(this.initialState);

            // While the queue isn't empty
            // run all possible next turns for the head of the queue state and enqueue those states
            // If someone is killed after the last unkillable turn, the run fails (no more enqueues)
            // If clan boss has turn 50, the run succeeds (return the result)
            while (battleStates.Count > 0)
            {
                CBBState state         = battleStates.Dequeue();
                bool     returnResults = false;

                // Advance turn meter for each battle participant
                foreach (IBattleParticipant participant in state.BattleParticipants)
                {
                    participant.ClockTick();
                }

                // See who has the most turn meter
                double maxTurnMeter = double.MinValue;
                foreach (IBattleParticipant participant in state.BattleParticipants)
                {
                    maxTurnMeter = Math.Max(maxTurnMeter, participant.TurnMeter);
                }

                // See if anybody has a full turn meter
                if (maxTurnMeter <= Constants.TurnMeter.Full)
                {
                    // Nothing to do this time, re-enqueue this state.
                    battleStates.Enqueue(state);
                }
                else
                {
                    // Champion with the fullest turn meter takes a turn!
                    IBattleParticipant maxTMChamp = state.BattleParticipants.First(bp => bp.TurnMeter == maxTurnMeter);

                    foreach (Skill passive in maxTMChamp.GetPassiveSkills())
                    {
                        if (passive.TurnAction.EffectsToApply != null)
                        {
                            foreach (EffectToApply effect in passive.TurnAction.EffectsToApply)
                            {
                                if (effect.WhenToApply == Constants.TimeInTurn.Beginning)
                                {
                                    if (effect.Target == Constants.Target.Self)
                                    {
                                        maxTMChamp.ApplyEffect(effect.Effect);
                                    }
                                    else if (effect.Target == Constants.Target.AllAllies)
                                    {
                                        foreach (IBattleParticipant bp in state.BattleParticipants.Where(p => !p.IsClanBoss && p != maxTMChamp))
                                        {
                                            bp.ApplyEffect(effect.Effect);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    IEnumerable <Skill> skillsToRun;
                    Skill nextAISkill = maxTMChamp.NextAISkill();
                    if (exploreAllSequences && state.BattleParticipants.Where(bp => bp.IsClanBoss).First().TurnCount < AutoAfterClanBossTurn)
                    {
                        skillsToRun = maxTMChamp.AllAvailableSkills();
                    }
                    else
                    {
                        skillsToRun = new List <Skill>()
                        {
                            maxTMChamp.NextAISkill()
                        };
                    }

                    CBBState currentState = state;
                    foreach (Skill skill in skillsToRun)
                    {
                        state = new CBBState(currentState);
                        IBattleParticipant champ = state.BattleParticipants.Where(bp => bp.Name == maxTMChamp.Name).First();
                        List <ClanBossBattleResult.Attack> additionalAttacks = new List <ClanBossBattleResult.Attack>();

                        champ.TakeTurn(skill);

                        if (!champ.IsClanBoss)
                        {
                            TurnAction action = skill.TurnAction;
                            additionalAttacks = ApplyTurnActions(
                                skill,
                                champ,
                                state.BattleParticipants.Where(p => !p.IsClanBoss && p != champ),
                                state.BattleParticipants.Where(p => !p.IsClanBoss),
                                state.BattleParticipants.Where(p => p.IsClanBoss),
                                state.BattleParticipants.Where(p => p.IsClanBoss).First()
                                );

                            battleStates.Enqueue(state);
                        }
                        else
                        {
                            // Clan boss turn!
                            TurnAction action          = skill.TurnAction;
                            bool       enqueueNewState = true;
                            List <IBattleParticipant> additionalAttackers = new List <IBattleParticipant>();

                            if (action.AttackTarget == Constants.Target.AllEnemies)
                            {
                                foreach (IBattleParticipant bp in state.BattleParticipants.Where(p => !p.IsClanBoss))
                                {
                                    bp.GetAttacked(action.AttackCount);

                                    if (bp.ActiveBuffs.ContainsKey(Constants.Buff.Counterattack) &&
                                        !bp.ActiveDebuffs.ContainsKey(Constants.Debuff.Stun))
                                    {
                                        additionalAttackers.Add(bp);
                                    }

                                    if (champ.TurnCount > LastKillableTurn && !bp.ActiveBuffs.ContainsKey(Constants.Buff.Unkillable))
                                    {
                                        enqueueNewState = !failOnKill;
                                    }
                                }
                            }
                            else if (action.AttackTarget == Constants.Target.OneEnemy)
                            {
                                IBattleParticipant stunTarget = this.GetStunTarget(state.BattleParticipants);

                                stunTarget.GetAttacked(action.AttackCount);

                                if (champ.TurnCount > LastKillableTurn && !stunTarget.ActiveBuffs.ContainsKey(Constants.Buff.Unkillable))
                                {
                                    enqueueNewState = !failOnKill;
                                }

                                if (action.DebuffsToApply != null)
                                {
                                    stunTarget.ApplyDebuff(action.DebuffsToApply.First());
                                }

                                if (stunTarget.ActiveBuffs.ContainsKey(Constants.Buff.Counterattack) &&
                                    !stunTarget.ActiveDebuffs.ContainsKey(Constants.Debuff.Stun))
                                {
                                    additionalAttackers.Add(stunTarget);
                                }
                            }

                            foreach (IBattleParticipant bp in additionalAttackers)
                            {
                                bp.AdditionalAttack();
                                additionalAttacks.Add(new ClanBossBattleResult.Attack(bp.Name, bp.TurnCount, bp.TurnMeter, Constants.SkillId.A1, bp.GetA1().Name, Constants.SkillId.A1));
                            }

                            if (champ.TurnCount == MaxClanBossTurns)
                            {
                                // End of the run!
                                enqueueNewState = false;
                                returnResults   = true;
                            }

                            if (enqueueNewState)
                            {
                                battleStates.Enqueue(state);
                            }
                        }

                        List <ClanBossBattleResult.BattleParticipantStats> bpStats = new List <ClanBossBattleResult.BattleParticipantStats>();
                        foreach (IBattleParticipant bp in state.BattleParticipants)
                        {
                            ClanBossBattleResult.BattleParticipantStats bpStat = new ClanBossBattleResult.BattleParticipantStats(bp.Name, bp.IsClanBoss, bp.TurnMeter, new Dictionary <Constants.Buff, int>(bp.ActiveBuffs), new Dictionary <Constants.Debuff, int>(bp.ActiveDebuffs), bp.GetSkillToCooldownMap());
                            bpStats.Add(bpStat);
                        }

                        ClanBossBattleResult.Attack attackDetails = new ClanBossBattleResult.Attack(champ.Name, champ.TurnCount, maxTurnMeter, skill.Id, skill.Name, nextAISkill.Id);
                        ClanBossBattleResult        result        = new ClanBossBattleResult(state.BattleParticipants.First(p => p.IsClanBoss).TurnCount, attackDetails, bpStats, additionalAttacks);
                        state.Results.Add(result);

                        if (returnResults)
                        {
                            yield return(state.Results);
                        }
                    }
                }
            }
        }
Beispiel #6
0
        private static List <ClanBossBattleResult.Attack> ApplyTurnActions(
            Skill skill,
            IBattleParticipant active,
            IEnumerable <IBattleParticipant> allies,
            IEnumerable <IBattleParticipant> fullTeam,
            IEnumerable <IBattleParticipant> enemies,
            IBattleParticipant singleTargetEnemy)
        {
            List <ClanBossBattleResult.Attack> attacks = new List <ClanBossBattleResult.Attack>();

            TurnAction action = skill.TurnAction;

            if (action.BuffsToApply != null)
            {
                foreach (BuffToApply buff in action.BuffsToApply)
                {
                    if (buff.Target == Constants.Target.Self)
                    {
                        active.ApplyBuff(buff);
                    }
                    else if (buff.Target == Constants.Target.AllAllies)
                    {
                        foreach (IBattleParticipant bp in allies)
                        {
                            bp.ApplyBuff(buff);
                        }
                    }
                    else if (buff.Target == Constants.Target.FullTeam)
                    {
                        foreach (IBattleParticipant bp in fullTeam)
                        {
                            bp.ApplyBuff(buff);
                        }
                    }
                }
            }

            if (action.DebuffsToApply != null)
            {
                foreach (DebuffToApply debuff in action.DebuffsToApply)
                {
                    if (debuff.Target == Constants.Target.AllEnemies)
                    {
                        foreach (IBattleParticipant bp in enemies)
                        {
                            bp.ApplyDebuff(debuff);
                        }
                    }
                    else if (debuff.Target == Constants.Target.OneEnemy)
                    {
                        singleTargetEnemy.ApplyDebuff(debuff);
                    }
                }
            }

            if (action.EffectsToApply != null)
            {
                foreach (EffectToApply effect in action.EffectsToApply)
                {
                    if (effect.Effect == Constants.Effect.AllyAttack)
                    {
                        foreach (IBattleParticipant bp in allies)
                        {
                            if (effect.Target == Constants.Target.ThreeRandomAllies && bp.LeaveOutOfAllyAttack)
                            {
                                continue;
                            }

                            bp.AdditionalAttack();
                            Skill a1 = bp.GetA1();
                            attacks.Add(new ClanBossBattleResult.Attack(bp.Name, bp.TurnCount, bp.TurnMeter, a1.Id, a1.Name, Constants.SkillId.A1));
                            attacks.AddRange(ApplyTurnActions(
                                                 a1,
                                                 bp,
                                                 fullTeam.Where(p => p != bp),
                                                 fullTeam,
                                                 enemies,
                                                 singleTargetEnemy));
                        }
                    }
                    else
                    {
                        if (effect.Target == Constants.Target.Self)
                        {
                            active.ApplyEffect(effect.Effect);
                        }
                        else if (effect.Target == Constants.Target.AllAllies)
                        {
                            foreach (IBattleParticipant bp in allies)
                            {
                                bp.ApplyEffect(effect.Effect);
                            }
                        }
                    }
                }
            }

            foreach (Skill passive in active.GetPassiveSkills())
            {
                if (passive.TurnAction.EffectsToApply != null)
                {
                    foreach (EffectToApply effect in passive.TurnAction.EffectsToApply)
                    {
                        if (effect.WhenToApply == Constants.TimeInTurn.End)
                        {
                            if (effect.Target == Constants.Target.Self)
                            {
                                active.ApplyEffect(effect.Effect);
                            }
                            else if (effect.Target == Constants.Target.AllAllies)
                            {
                                foreach (IBattleParticipant bp in allies)
                                {
                                    bp.ApplyEffect(effect.Effect);
                                }
                            }
                        }
                    }
                }
            }

            return(attacks);
        }