예제 #1
0
        private BattleResult GetBattleResult(Unit Attacker, Squad AttackerSquad, float DamageModifier,
                                             int TargetPlayerIndex, int TargetSquadIndex, int TargetUnitIndex, bool ActivateSkills, bool CalculateCritical)
        {
            Squad DefenderSquad = ListPlayer[TargetPlayerIndex].ListSquad[TargetSquadIndex];
            Unit  Defender      = DefenderSquad[TargetUnitIndex];

            ActivateAutomaticSkills(AttackerSquad, Attacker, DeathmatchSkillRequirement.BeforeAttackRequirementName, DefenderSquad, Defender);
            ActivateAutomaticSkills(DefenderSquad, Defender, DeathmatchSkillRequirement.BeforeGettingAttackedRequirementName, AttackerSquad, Attacker);

            BattleResult Result;

            int BaseHitRate;

            BaseHitRate = CalculateHitRate(Attacker, AttackerSquad, Defender, DefenderSquad, Defender.BattleDefenseChoice);

            bool AttackHit = RandomHelper.RandomActivationCheck(BaseHitRate);

            if (AttackHit)
            {
                if (ActivateSkills)
                {
                    ActivateAutomaticSkills(AttackerSquad, Attacker, DeathmatchSkillRequirement.BeforeHitRequirementName, DefenderSquad, Defender);
                    ActivateAutomaticSkills(DefenderSquad, Defender, DeathmatchSkillRequirement.BeforeGettingHitRequirementName, AttackerSquad, Attacker);
                }

                Result = DamageFormula(Attacker, AttackerSquad, DamageModifier, TargetPlayerIndex, TargetSquadIndex, TargetUnitIndex, Defender.BattleDefenseChoice, CalculateCritical);
            }
            else
            {
                if (ActivateSkills)
                {
                    ActivateAutomaticSkills(AttackerSquad, Attacker, DeathmatchSkillRequirement.BeforeMissRequirementName, DefenderSquad, Defender);
                    ActivateAutomaticSkills(DefenderSquad, Defender, DeathmatchSkillRequirement.BeforeGettingMissedRequirementName, AttackerSquad, Attacker);
                }

                Result = new BattleResult();
                Result.AttackDamage = 0;
                Result.AttackMissed = true;
                Result.SetTarget(TargetPlayerIndex, TargetSquadIndex, TargetUnitIndex, Defender);
            }

            Result.Accuracy = BaseHitRate;

            //Remove EN from the weapon cost.
            if (Attacker.CurrentAttack.ENCost > 0)
            {
                Result.AttackAttackerFinalEN = Math.Max(0, Attacker.EN - (Attacker.CurrentAttack.ENCost + Attacker.Boosts.ENCostModifier));
            }
            else
            {
                Result.AttackAttackerFinalEN = Attacker.EN;
            }

            GlobalBattleContext.Result = Result;

            if (ActivateSkills)
            {
                Attacker.UpdateSkillsLifetime(SkillEffect.LifetimeTypeOnAttack);
                Defender.UpdateSkillsLifetime(SkillEffect.LifetimeTypeOnEnemyAttack);

                if (AttackHit)
                {
                    Attacker.UpdateSkillsLifetime(SkillEffect.LifetimeTypeOnHit);
                    Defender.UpdateSkillsLifetime(SkillEffect.LifetimeTypeOnEnemyHit);

                    ActivateAutomaticSkills(AttackerSquad, Attacker, DeathmatchSkillRequirement.AfterHitRequirementName, DefenderSquad, Defender);
                    ActivateAutomaticSkills(DefenderSquad, Defender, DeathmatchSkillRequirement.AfterGettingHitRequirementName, AttackerSquad, Attacker);
                }
                else
                {
                    ActivateAutomaticSkills(AttackerSquad, Attacker, DeathmatchSkillRequirement.AfterMissRequirementName, DefenderSquad, Defender);
                    ActivateAutomaticSkills(DefenderSquad, Defender, DeathmatchSkillRequirement.AfterGettingMissedRequirementName, AttackerSquad, Attacker);
                }

                ActivateAutomaticSkills(AttackerSquad, Attacker, DeathmatchSkillRequirement.AfterAttackRequirementName, DefenderSquad, Defender);
                ActivateAutomaticSkills(DefenderSquad, Defender, DeathmatchSkillRequirement.AfterGettingAttackedRequirementName, AttackerSquad, Attacker);
            }

            return(Result);
        }
예제 #2
0
        public BattleResult DamageFormula(Unit Attacker, float DamageModifier, int Attack,
                                          int TargetPlayerIndex, int TargetSquadIndex, int TargetUnitIndex, Unit Defender, Unit.BattleDefenseChoices DefenseChoice,
                                          bool NullifyAttack, int Defense, bool CalculateCritical = false)
        {
            //FINAL DAMAGE = (((ATTACK - DEFENSE) * (ATTACKED AND DEFENDER SIZE COMPARISON)) + Additive Final Damage Bonuses) * Final Damage Multiplier Bonuses
            BattleResult Result = new BattleResult();

            Result.SetTarget(TargetPlayerIndex, TargetSquadIndex, TargetUnitIndex, Defender);

            if (NullifyAttack)
            {
                Result.AttackDamage = 0;
            }
            else if (Defender.Boosts.FinalDamageTakenFixedModifier > 0)
            {
                Result.AttackDamage = Defender.Boosts.FinalDamageTakenFixedModifier;
            }
            else
            {
                Result.AttackWasCritical = false;
                int AttackerSize = Attacker.SizeValue;
                int DefenderSize = Defender.SizeValue;

                int   AttackerSizeComparison = AttackerSize - DefenderSize;
                float Damage = Math.Max(0, (int)(((Attack - Defense) * (1 + AttackerSizeComparison / 100f) + Attacker.Boosts.BaseDamageModifier) * (Attacker.Boosts.BaseDamageMultiplier * Defender.Boosts.BaseDamageTakenReductionMultiplier)));

                if (CalculateCritical && !Attacker.Boosts.CriticalAlwaysFail)
                {
                    //(((Attacker Skill Stat - Defender Skill Stat) + Weapon Critical Hit Rate) + Additive effect) * Multiplying effec
                    int Critical = (Attacker.PilotSKL - Defender.PilotSKL) + Attacker.CurrentAttack.Critical + Attacker.Boosts.CriticalHitRateModifier;
                    //Don't calculate critical if there is a damage multiplier.
                    if (Attacker.Boosts.BaseDamageMultiplier == 1)
                    {
                        if (Attacker.Boosts.CriticalAlwaysSucceed)
                        {
                            Critical = 100;
                        }
                    }
                    if (RandomHelper.Next(101) <= Critical)
                    {
                        float CriticalDamageMultiplier = 1.2f;
                        CriticalDamageMultiplier += Attacker.Boosts.CriticalBaseDamageMultiplier;
                        Damage += Attacker.Boosts.CriticalBaseDamageModifier;
                        Damage *= CriticalDamageMultiplier;
                        Damage *= Attacker.Boosts.CriticalFinalDamageMultiplier;
                        Damage += Attacker.Boosts.CriticalFinalDamageModifier;

                        Result.AttackWasCritical = true;
                    }
                }

                if (DefenseChoice == Unit.BattleDefenseChoices.Defend)
                {
                    Damage *= 0.5f;
                }

                Result.AttackDamage = (int)(Damage * DamageModifier) + Attacker.Boosts.FinalDamageModifier;

                Result.AttackDamage = (int)(Result.AttackDamage * Attacker.Boosts.FinalDamageMultiplier);
            }

            Result.AttackMissed = false;

            #region Sword Cut

            if (Result.AttackDamage > 0 && (Attacker.CurrentAttack.Sec & WeaponSecondaryProperty.SwordCut) == WeaponSecondaryProperty.SwordCut)
            {
                bool PilotSwordCut = false;
                bool UnitSwordCut  = Defender.Boosts.SwordCutModifier;

                if (UnitSwordCut)
                {
                    foreach (KeyValuePair <string, List <BaseEffect> > ActiveListEffect in Defender.Pilot.Effects.GetEffects())
                    {
                        if (Defender.ListIgnoreSkill.Contains(ActiveListEffect.Key))
                        {
                            continue;
                        }

                        for (int E = ActiveListEffect.Value.Count - 1; E >= 0 && !PilotSwordCut; --E)
                        {
                            if (ActiveListEffect.Value[E] is SwordCutEffect)
                            {
                                PilotSwordCut = true;
                            }
                        }
                    }
                    if (PilotSwordCut)
                    {
                        int SwordCutActivation = (Defender.PilotSKL - Attacker.PilotSKL) + 10;

                        bool SwordCutActivated = RandomHelper.RandomActivationCheck(SwordCutActivation);

                        if (SwordCutActivated)
                        {
                            Result.AttackMissed   = true;
                            Result.AttackSwordCut = true;
                        }
                    }
                }
            }

            #endregion

            #region Shoot Down

            if (Result.AttackDamage > 0 && (Attacker.CurrentAttack.Sec & WeaponSecondaryProperty.ShootDown) == WeaponSecondaryProperty.ShootDown)
            {
                bool PilotShootDown = false;
                bool UnitShootDown  = Defender.Boosts.ShootDownModifier;

                if (UnitShootDown)
                {
                    foreach (KeyValuePair <string, List <BaseEffect> > ActiveListEffect in Defender.Pilot.Effects.GetEffects())
                    {
                        if (Defender.ListIgnoreSkill.Contains(ActiveListEffect.Key))
                        {
                            continue;
                        }

                        for (int E = ActiveListEffect.Value.Count - 1; E >= 0 && !PilotShootDown; --E)
                        {
                            if (ActiveListEffect.Value[E] is ShootDownEffect)
                            {
                                PilotShootDown = true;
                            }
                        }
                    }
                    if (PilotShootDown)
                    {
                        int ShootDownActivation = (Defender.PilotSKL - Attacker.PilotSKL) + 10;

                        bool ShootDownActivated = RandomHelper.RandomActivationCheck(ShootDownActivation);

                        if (ShootDownActivated)
                        {
                            Result.AttackMissed    = true;
                            Result.AttackShootDown = true;
                        }
                    }
                }
            }

            #endregion

            #region Shield

            if (Result.AttackDamage > 0)
            {
                bool PilotShield = false;
                bool UnitShield  = Defender.Boosts.ShieldModifier;

                if (UnitShield)
                {
                    foreach (KeyValuePair <string, List <BaseEffect> > ActiveListEffect in Defender.Pilot.Effects.GetEffects())
                    {
                        if (Defender.ListIgnoreSkill.Contains(ActiveListEffect.Key))
                        {
                            continue;
                        }

                        for (int E = ActiveListEffect.Value.Count - 1; E >= 0 && !PilotShield; --E)
                        {
                            if (ActiveListEffect.Value[E] is ShieldEffect)
                            {
                                PilotShield = true;
                            }
                        }
                    }
                    if (PilotShield)
                    {
                        int ShieldActivation = (Defender.PilotSKL - Attacker.PilotSKL) + 10;

                        bool ShieldActivated = RandomHelper.RandomActivationCheck(ShieldActivation);

                        if (ShieldActivated)
                        {
                            Result.Shield = true;
                            if (DefenseChoice == Unit.BattleDefenseChoices.Defend)
                            {
                                Result.AttackDamage = (int)(Result.AttackDamage * 0.25f);
                            }
                            else
                            {
                                Result.AttackDamage = (int)(Result.AttackDamage * 0.5f);
                            }
                        }
                    }
                }
            }

            #endregion

            #region Barrier

            if (Result.AttackDamage > 0)
            {
                bool IsBarrierBreak  = false;
                bool IsBarrierActive = false;

                for (int C = Defender.ArrayCharacterActive.Length - 1; C >= 0 && !IsBarrierBreak && !IsBarrierActive; --C)
                {
                    foreach (KeyValuePair <string, List <BaseEffect> > ActiveListEffect in Defender.ArrayCharacterActive[C].Effects.GetEffects())
                    {
                        if (Defender.ListIgnoreSkill.Contains(ActiveListEffect.Key))
                        {
                            continue;
                        }

                        if (IsBarrierActive)
                        {
                            break;
                        }

                        for (int E = ActiveListEffect.Value.Count - 1; E >= 0 && !IsBarrierBreak && !IsBarrierActive; --E)
                        {
                            BarrierEffect ActiveBarrierEffect = ActiveListEffect.Value[E] as BarrierEffect;

                            if (ActiveBarrierEffect != null)
                            {
                                int ENCost = int.Parse(ActiveParser.Evaluate(ActiveBarrierEffect.ENCost), CultureInfo.InvariantCulture);

                                if (Result.AttackAttackerFinalEN > ENCost)
                                {
                                    Result.AttackAttackerFinalEN -= ENCost;
                                    int BreakingDamage = int.Parse(ActiveParser.Evaluate(ActiveBarrierEffect.BreakingDamage), CultureInfo.InvariantCulture);
                                    //Look for weapon breaker or damage breaker or if the Barrier can protect against that Attack.
                                    if ((ActiveBarrierEffect.EffectiveAttacks.Count > 0 && !ActiveBarrierEffect.EffectiveAttacks.Contains(Attacker.CurrentAttack.RelativePath)) ||
                                        ActiveBarrierEffect.BreakingAttacks.Contains(Attacker.CurrentAttack.RelativePath) ||
                                        Result.AttackDamage >= BreakingDamage)
                                    {
                                        IsBarrierBreak = true;
                                    }
                                    else
                                    {//Look for Skill breaker.
                                        for (int C2 = Attacker.ArrayCharacterActive.Length - 1; C2 >= 0 && !IsBarrierBreak; --C2)
                                        {
                                            foreach (KeyValuePair <string, List <BaseEffect> > AttackerListEffect in Attacker.ArrayCharacterActive[C2].Effects.GetEffects())
                                            {
                                                if (ActiveBarrierEffect.BreakingAttacks.Contains(AttackerListEffect.Key))
                                                {
                                                    IsBarrierBreak = true;
                                                    break;
                                                }
                                            }
                                        }
                                    }

                                    if (!IsBarrierBreak)
                                    {
                                        IsBarrierActive = true;
                                        Result.Barrier  = ActiveListEffect.Key;
                                        if (Result.AttackDamage <= 10)
                                        {
                                            if (ActiveBarrierEffect.BarrierType == BarrierEffect.BarrierTypes.Dodge)
                                            {
                                                Result.AttackMissed = true;
                                            }
                                            else if (ActiveBarrierEffect.BarrierType == BarrierEffect.BarrierTypes.Defend)
                                            {
                                                Result.AttackDamage = 0;
                                            }
                                        }
                                        else
                                        {
                                            if (ActiveBarrierEffect.BarrierType == BarrierEffect.BarrierTypes.Dodge)
                                            {
                                                Result.AttackMissed = true;
                                            }
                                            else if (ActiveBarrierEffect.BarrierType == BarrierEffect.BarrierTypes.Defend)
                                            {
                                                float DamageReduction = float.Parse(ActiveParser.Evaluate(ActiveBarrierEffect.DamageReduction), CultureInfo.InvariantCulture);
                                                if (ActiveBarrierEffect.NumberType == Operators.NumberTypes.Absolute)
                                                {
                                                    Result.AttackDamage = Math.Max(0, Result.AttackDamage - (int)DamageReduction);
                                                }
                                                else if (ActiveBarrierEffect.NumberType == Operators.NumberTypes.Relative)
                                                {
                                                    Result.AttackDamage = (int)(Result.AttackDamage * DamageReduction);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            #endregion

            return(Result);
        }