예제 #1
0
        public override void ApplyOnAttack(AttackData attackData, CombatDamageModifier damageModifier)
        {
            if (!attackData.Attacker.IsRanged || (SkillLevel == SecondarySkillLevel.None))
            {
                return;
            }

            double bonus;

            if (SkillLevel == SecondarySkillLevel.Basic)
            {
                bonus = 0.1;
            }
            else if (SkillLevel == SecondarySkillLevel.Advanced)
            {
                bonus = 0.25;
            }
            else
            {
                bonus = 0.5;
            }

            if (IsSpecialized)
            {
                bonus *= (1.0 + 0.05 * HeroStats.Level);
            }

            damageModifier.DamageBonuses.Add(bonus);
        }
예제 #2
0
        public override void ApplyOnDefense(AttackData attackData, CombatDamageModifier damageModifier)
        {
            if (SkillLevel == SecondarySkillLevel.None)
            {
                return;
            }

            double reduction;

            if (SkillLevel == SecondarySkillLevel.Basic)
            {
                reduction = 0.05;
            }
            else if (SkillLevel == SecondarySkillLevel.Advanced)
            {
                reduction = 0.1;
            }
            else
            {
                reduction = 0.15;
            }

            if (IsSpecialized)
            {
                reduction *= (1.0 + 0.05 * HeroStats.Level);
            }

            damageModifier.DamageReductions.Add(reduction);
        }
예제 #3
0
 public override void ApplyOnAttack(AttackData attackData, CombatDamageModifier damageModifier)
 {
     if (CasterStats.IsSpecialized)
     {
         double bonus = 0.03 * (CasterStats.SpecializationLevel / attackData.Attacker.Level);
         damageModifier.DamageBonuses.Add(bonus);
     }
 }
예제 #4
0
        public override void ApplyOnDefense(AttackData attackData, CombatDamageModifier damageModifier)
        {
            if (!attackData.Attacker.IsRanged)
            {
                return;
            }

            if (CasterStats.SkillLevel <= SecondarySkillLevel.Basic)
            {
                damageModifier.DamageReductions.Add(0.25);
            }
            else
            {
                damageModifier.DamageReductions.Add(0.5);
            }
        }
예제 #5
0
        public void CalculateDamage(CombatDamageCalculatorInputData data, out int minDamage, out int maxDamage, out string notes)
        {
            if (data.AttackerCount == 0)
            {
                minDamage = 0;
                maxDamage = 0;
                notes = null;
                return;
            }

            CombatDamageModifier damageModifier = new CombatDamageModifier();
            AttackData attackData = new AttackData { Attacker = data.Attacker, Defender = data.Defender };

            List<ICombatUnitStatsModifier> attackerStatsModifiers = new List<ICombatUnitStatsModifier>();
            List<ICombatUnitStatsModifier> defenderStatsModifiers = new List<ICombatUnitStatsModifier>();
            List<ICombatDamageModifierProvider> attackerDamageModifierProviders = new List<ICombatDamageModifierProvider>();
            List<ICombatDamageModifierProvider> defenderDamageModifierProviders = new List<ICombatDamageModifierProvider>();

            if (data.Terrain != null)
            {
                attackerStatsModifiers.Add(data.Terrain);
                defenderStatsModifiers.Add(data.Terrain);
            }

            if (data.AttackerHeroStats != null)
            {
                attackerStatsModifiers.Add(data.AttackerHeroStats);
                attackerDamageModifierProviders.Add(data.AttackerHeroStats);
            }

            if (data.DefenderHeroStats != null)
            {
                defenderStatsModifiers.Add(data.DefenderHeroStats);
                defenderDamageModifierProviders.Add(data.DefenderHeroStats);
            }

            if (data.AttackerSpells != null)
            {
                attackerStatsModifiers.AddRange(data.AttackerSpells);
                attackerDamageModifierProviders.AddRange(data.AttackerSpells);
            }

            if (data.DefenderSpells != null)
            {
                defenderStatsModifiers.AddRange(data.DefenderSpells);
                defenderDamageModifierProviders.AddRange(data.DefenderSpells);
            }

            attackerStatsModifiers.Add(UnitUniqueTraitManager.Instance);
            defenderStatsModifiers.Add(UnitUniqueTraitManager.Instance);
            attackerDamageModifierProviders.Add(UnitUniqueTraitManager.Instance);
            defenderDamageModifierProviders.Add(UnitUniqueTraitManager.Instance);

            /////////////////////////

            UnitStats modifiedAttackerStats = data.Attacker.InitialStats.Copy();
            UnitStats modifiedDefenderStats = data.Defender.InitialStats.Copy();

            foreach (ICombatUnitStatsModifier modifier in attackerStatsModifiers)
            {
                modifier.ApplyPermanently(data.Attacker, modifiedAttackerStats);
                modifier.ApplyOnAttack(attackData, modifiedAttackerStats);
            }

            foreach (ICombatUnitStatsModifier modifier in defenderStatsModifiers)
            {
                modifier.ApplyPermanently(data.Defender, modifiedDefenderStats);
                modifier.ApplyOnDefense(attackData, modifiedDefenderStats);
            }

            int totalAttack = modifiedAttackerStats.Attack;
            int totalDefense = modifiedDefenderStats.Defense;

            if (totalAttack > totalDefense)
            {
                double primarySkillBonus = Math.Min((totalAttack - totalDefense) * 0.05, 3.0);
                damageModifier.DamageBonuses.Add(primarySkillBonus);
            }
            else if (totalAttack < totalDefense)
            {
                double primarySkillReduction = Math.Min((totalDefense - totalAttack) * 0.025, 0.7);
                damageModifier.DamageReductions.Add(primarySkillReduction);
            }

            /////////////////////////

            foreach (ICombatDamageModifierProvider provider in attackerDamageModifierProviders)
            {
                provider.ApplyOnAttack(attackData, damageModifier);
            }

            foreach (ICombatDamageModifierProvider provider in defenderDamageModifierProviders)
            {
                provider.ApplyOnDefense(attackData, damageModifier);
            }

            int minBaseDamage = data.AttackerCount * modifiedAttackerStats.MinDamage;
            int maxBaseDamage = data.AttackerCount * modifiedAttackerStats.MaxDamage;

            minDamage = PerformCalculation(minBaseDamage, damageModifier);
            maxDamage = PerformCalculation(maxBaseDamage, damageModifier);
            notes = GenerateNotes(data);
        }
예제 #6
0
 public virtual void ApplyOnDefense(AttackData attackData, CombatDamageModifier damageModifier)
 {
 }
예제 #7
0
파일: Unit.cs 프로젝트: nickynick/H3Calc
        public void ApplyOnDefense(AttackData attackData, UnitStats modifiedStats)
        {
            if (attackData.Attacker.Id == 110) // Behemoth
            {
                modifiedStats.Defense = (int)(modifiedStats.Defense * 0.6);
            }

            if (attackData.Attacker.Id == 111) // Ancient Behemoth
            {
                modifiedStats.Defense = (int)(modifiedStats.Defense * 0.2);
            }
        }
예제 #8
0
파일: Unit.cs 프로젝트: nickynick/H3Calc
        public void ApplyOnAttack(AttackData attackData, CombatDamageModifier damageModifier)
        {
            int attackerId = attackData.Attacker.Id;
            int defenderId = attackData.Defender.Id;

            int minUnitId = Math.Min(attackerId, defenderId);
            int maxUnitId = Math.Max(attackerId, defenderId);

            // Opposite elementals

            bool isOppositeElementalPair = false;

            isOppositeElementalPair |= (minUnitId == 114 || minUnitId == 115) && (maxUnitId == 120 || maxUnitId == 121); // air / earth
            isOppositeElementalPair |= (minUnitId == 116 || minUnitId == 117) && (maxUnitId == 118 || maxUnitId == 119); // water / fire

            if (isOppositeElementalPair)
            {
                damageModifier.DamageBonuses.Add(1.0);
            }

            // Hate pairs

            bool isHatePair = false;
            isHatePair |= (minUnitId == 12 || minUnitId == 13) && (maxUnitId == 82 || maxUnitId == 83); // angels / devils
            isHatePair |= (minUnitId == 36 || minUnitId == 37) && (maxUnitId == 80 || maxUnitId == 81); // genies / efreets
            isHatePair |= (minUnitId == 41) && (maxUnitId == 69); // titans / black dragons

            if (isHatePair)
            {
                damageModifier.DamageBonuses.Add(0.5);
            }

            // Attacker is Psychic Elemental, defender is immune to Mind spells

            if ((attackerId == 122) &&
                (
                 attackData.Defender.IsUndead ||
                 (defenderId == 32 || defenderId == 33 || defenderId == 134 || defenderId == 135) || // Golems
                 (defenderId == 40 || defenderId == 41) || // Giant / Titan
                 (defenderId == 69) || // Black Dragon
                 (defenderId >= 114 && defenderId <= 123) // Elementals
                ))
            {
                damageModifier.DamageReductions.Add(0.5);
            }

            // Magic Elemental vs Magic Elemental or Black Dragon

            if ((attackerId == 123) && (defenderId == 123 || defenderId == 69))
            {
                damageModifier.DamageReductions.Add(0.5);
            }
        }
예제 #9
0
파일: Unit.cs 프로젝트: nickynick/H3Calc
 public void ApplyOnAttack(AttackData attackData, UnitStats modifiedStats)
 {
 }
예제 #10
0
 public void ApplyOnDefense(AttackData attackData, CombatDamageModifier damageModifier)
 {
 }
예제 #11
0
 public void ApplyOnAttack(AttackData attackData, UnitStats modifiedStats)
 {
 }
예제 #12
0
 public void ApplyOnDefense(AttackData attackData, UnitStats modifiedStats)
 {
 }
예제 #13
0
        public override void ApplyOnAttack(AttackData attackData, UnitStats modifiedStats)
        {
            List<int> affectedUnitIds = new List<int>();

            affectedUnitIds.Add(26); // Green Dragon
            affectedUnitIds.Add(27); // Gold Dragon
            affectedUnitIds.Add(54); // Bone Dragon
            affectedUnitIds.Add(55); // Ghost Dragon
            affectedUnitIds.Add(68); // Red Dragon
            affectedUnitIds.Add(69); // Black Dragon
            affectedUnitIds.Add(96); // Hydra
            affectedUnitIds.Add(97); // Chaos Hydra
            affectedUnitIds.Add(110); // Behemoth
            affectedUnitIds.Add(111); // Ancient Behemoth
            affectedUnitIds.Add(124); // Firebird
            affectedUnitIds.Add(125); // Phoenix
            affectedUnitIds.Add(137); // Fairy Dragon
            affectedUnitIds.Add(138); // Rust Dragon
            affectedUnitIds.Add(139); // Crystal Dragon
            affectedUnitIds.Add(140); // Azure Dragon

            if (CasterStats.SkillLevel >= SecondarySkillLevel.Advanced)
            {
                affectedUnitIds.Add(12); // Angel
                affectedUnitIds.Add(13); // Archangel
                affectedUnitIds.Add(82); // Devil
                affectedUnitIds.Add(83); // Archdevil
            }

            if (CasterStats.SkillLevel == SecondarySkillLevel.Expert)
            {
                affectedUnitIds.Add(40); // Giant
                affectedUnitIds.Add(41); // Titan
            }

            if (affectedUnitIds.Contains(attackData.Defender.Id))
            {
                int bonus = 8;

                if (CasterStats.IsSpecialized)
                {
                    switch (attackData.Attacker.Level)
                    {
                        case 1:
                            bonus += 4;
                            break;
                        case 2:
                            bonus += 3;
                            break;
                        case 3:
                            bonus += 2;
                            break;
                        case 4:
                            bonus += 1;
                            break;
                    }
                }

                modifiedStats.Attack += bonus;
            }
        }
예제 #14
0
 public virtual void ApplyOnDefense(AttackData attackData, UnitStats modifiedStats)
 {
 }
예제 #15
0
 public virtual void ApplyOnAttack(AttackData attackData, CombatDamageModifier damageModifier)
 {
 }
예제 #16
0
        public override void ApplyOnAttack(AttackData attackData, UnitStats modifiedStats)
        {
            List <int> affectedUnitIds = new List <int>();

            affectedUnitIds.Add(26);  // Green Dragon
            affectedUnitIds.Add(27);  // Gold Dragon
            affectedUnitIds.Add(54);  // Bone Dragon
            affectedUnitIds.Add(55);  // Ghost Dragon
            affectedUnitIds.Add(68);  // Red Dragon
            affectedUnitIds.Add(69);  // Black Dragon
            affectedUnitIds.Add(96);  // Hydra
            affectedUnitIds.Add(97);  // Chaos Hydra
            affectedUnitIds.Add(110); // Behemoth
            affectedUnitIds.Add(111); // Ancient Behemoth
            affectedUnitIds.Add(124); // Firebird
            affectedUnitIds.Add(125); // Phoenix
            affectedUnitIds.Add(137); // Fairy Dragon
            affectedUnitIds.Add(138); // Rust Dragon
            affectedUnitIds.Add(139); // Crystal Dragon
            affectedUnitIds.Add(140); // Azure Dragon

            if (CasterStats.SkillLevel >= SecondarySkillLevel.Advanced)
            {
                affectedUnitIds.Add(12); // Angel
                affectedUnitIds.Add(13); // Archangel
                affectedUnitIds.Add(82); // Devil
                affectedUnitIds.Add(83); // Archdevil
            }

            if (CasterStats.SkillLevel == SecondarySkillLevel.Expert)
            {
                affectedUnitIds.Add(40); // Giant
                affectedUnitIds.Add(41); // Titan
            }

            if (affectedUnitIds.Contains(attackData.Defender.Id))
            {
                int bonus = 8;

                if (CasterStats.IsSpecialized)
                {
                    switch (attackData.Attacker.Level)
                    {
                    case 1:
                        bonus += 4;
                        break;

                    case 2:
                        bonus += 3;
                        break;

                    case 3:
                        bonus += 2;
                        break;

                    case 4:
                        bonus += 1;
                        break;
                    }
                }

                modifiedStats.Attack += bonus;
            }
        }