public BattleResult DamageFormula(Unit Attacker, Squad AttackerSquad, float DamageModifier,
                                          Unit Defender, Squad DefenderSquad, Unit.BattleDefenseChoices DefenseChoice, bool CalculateCritical)
        {
            string  AttackerTerrainType;
            string  DefenderTerrainType;
            Terrain DefenderTerrain;

            if (AttackerSquad.IsFlying)
            {
                AttackerTerrainType = "Air";
            }
            else
            {
                AttackerTerrainType = GetTerrainType(AttackerSquad.X, AttackerSquad.Y, AttackerSquad.LayerIndex);
            }

            if (DefenderSquad.IsFlying)
            {
                DefenderTerrainType = "Air";
                DefenderTerrain     = null;
            }
            else
            {
                DefenderTerrainType = GetTerrainType(DefenderSquad.X, DefenderSquad.Y, DefenderSquad.LayerIndex);
                DefenderTerrain     = GetTerrain(DefenderSquad);
            }

            //Check if the Unit can counter the attack.
            bool NullifyAttack = CanNullifyAttack(Attacker.CurrentAttack, AttackerTerrainType, DefenderSquad.CurrentMovement, DefenderSquad, Defender.Boosts);

            int Attack  = AttackFormula(Attacker, AttackerTerrainType);
            int Defense = DefenseFormula(Defender, DefenderTerrainType, DefenderTerrain);

            BattleResult Result = DamageFormula(Attacker, DamageModifier, Attack, Defender, DefenseChoice, NullifyAttack, Defense, CalculateCritical);

            return(Result);
        }
Esempio n. 2
0
        public BattleResult DamageFormula(Unit Attacker, Squad AttackerSquad, float DamageModifier,
                                          int TargetPlayerIndex, int TargetSquadIndex, int TargetUnitIndex, Unit.BattleDefenseChoices DefenseChoice, bool CalculateCritical)
        {
            Squad DefenderSquad = ListPlayer[TargetPlayerIndex].ListSquad[TargetSquadIndex];
            Unit  Defender      = DefenderSquad[TargetUnitIndex];

            string  AttackerTerrainType;
            string  DefenderTerrainType;
            Terrain DefenderTerrain;

            if (AttackerSquad.IsFlying)
            {
                AttackerTerrainType = UnitStats.TerrainAir;
            }
            else
            {
                AttackerTerrainType = GetTerrainType(AttackerSquad.X, AttackerSquad.Y, (int)AttackerSquad.Z);
            }

            if (DefenderSquad.IsFlying)
            {
                DefenderTerrainType = UnitStats.TerrainAir;
                DefenderTerrain     = null;
            }
            else
            {
                DefenderTerrainType = GetTerrainType(DefenderSquad.X, DefenderSquad.Y, (int)DefenderSquad.Z);
                DefenderTerrain     = GetTerrain(DefenderSquad);
            }

            //Check if the Unit can counter the attack.
            bool NullifyAttack = CanNullifyAttack(Attacker.CurrentAttack, AttackerTerrainType, DefenderSquad.CurrentMovement, DefenderSquad, Defender.Boosts);

            int Attack  = AttackFormula(Attacker, AttackerTerrainType);
            int Defense = DefenseFormula(Defender, DefenderTerrainType, DefenderTerrain);

            BattleResult Result = DamageFormula(Attacker, DamageModifier, Attack, TargetPlayerIndex, TargetSquadIndex, TargetUnitIndex, Defender, DefenseChoice, NullifyAttack, Defense, CalculateCritical);

            return(Result);
        }
Esempio n. 3
0
        public int CalculateHitRate(Unit Attacker, Squad AttackerSquad, Unit Defender, Squad DefenderSquad, Unit.BattleDefenseChoices DefenseChoice)
        {
            string  AttackerTerrainType;
            string  DefenderTerrainType;
            Terrain DefenderTerrain;

            if (AttackerSquad.IsFlying)
            {
                AttackerTerrainType = UnitStats.TerrainAir;
            }
            else
            {
                AttackerTerrainType = GetTerrainType(AttackerSquad.X, AttackerSquad.Y, (int)AttackerSquad.Z);
            }

            if (DefenderSquad.IsFlying)
            {
                DefenderTerrainType = UnitStats.TerrainAir;
                DefenderTerrain     = null;
            }
            else
            {
                DefenderTerrainType = GetTerrainType(DefenderSquad.X, DefenderSquad.Y, (int)DefenderSquad.Z);
                DefenderTerrain     = GetTerrain(DefenderSquad);
            }

            return(CalculateHitRate(Attacker, AttackerTerrainType, Defender, DefenderTerrainType, DefenderTerrain, DefenseChoice));
        }
Esempio n. 4
0
        //(((Attacker Hit Rate + Defender Evasion) * Size Difference Multiplier) + Additive final hit rate effect) * Multiplying final hit rate effect
        public int CalculateHitRate(Unit Attacker, string AttackerTerrainType, Unit Defender, string DefenderTerrainType, Terrain DefenderTerrain, Unit.BattleDefenseChoices DefenseChoice)
        {
            int SizeCompare = Attacker.SizeValue - Defender.SizeValue;

            float BaseHitRate;

            //If the Attacker have an accuracy modifier, use it.
            if (Attacker.Boosts.AccuracyFixedModifier > 0)
            {
                BaseHitRate = Attacker.Boosts.AccuracyFixedModifier;
            }
            //If the Defender have an accuracy modifier, use it.
            else if (Defender.Boosts.EvasionFixedModifier > 0)
            {
                BaseHitRate = 100 - Defender.Boosts.EvasionFixedModifier;
            }
            //Force the defender to dodge the attack.
            else if (Defender.Boosts.AutoDodgeModifier)
            {
                BaseHitRate = 0;
            }
            else//No particular modifier, use basic hit rate formula.
            {
                BaseHitRate = (Accuracy(Attacker, AttackerTerrainType) - Evasion(Defender, DefenderTerrainType, DefenderTerrain)) * (1 + -SizeCompare / 100f);
                if (DefenseChoice == Unit.BattleDefenseChoices.Evade)
                {
                    BaseHitRate *= 0.5f;
                }
            }
            return((int)Math.Max(0, Math.Min(100, BaseHitRate)));
        }
        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);
        }