private void comboBoxBoss_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!_loadingCalculationOptions)
            {
                _loadingCalculationOptions = true;
                CalculationsEnhance calcs = new CalculationsEnhance();
                BossHandler         boss  = bosslist.GetBossFromBetterName(comboBoxBoss.Text);
                _calcOpts.SetBoss(boss);
                CB_TargLvl.Text           = _calcOpts.TargetLevel.ToString();
                CB_TargArmor.Text         = _calcOpts.TargetArmor.ToString();
                cmbLength.Value           = (int)_calcOpts.FightLength;
                CK_InBack.Checked         = _calcOpts.InBack;
                CB_InBackPerc.Value       = _calcOpts.InBackPerc;
                CK_MultiTargs.Checked     = _calcOpts.MultipleTargets;
                CB_MultiTargsMax.Enabled  = CK_MultiTargs.Checked;
                CB_MultiTargsPerc.Enabled = CK_MultiTargs.Checked;
                CB_MultiTargsMax.Value    = _calcOpts.AdditionalTargets;
                CB_MultiTargsPerc.Value   = (int)(_calcOpts.AdditionalTargetPercent * 100 + .001f);

                Stats stats = calcs.GetCharacterStats(Character, null);
                TB_BossInfo.Text = boss.GenInfoString(
                    0,                                                                                             // The Boss' Damage bonuses against you (meaning YOU are debuffed)
                    StatConversion.GetArmorDamageReduction(_calcOpts.TargetLevel, stats.Armor, 0, 0, 0),           // Your Armor's resulting Damage Reduction
                    StatConversion.GetDRAvoidanceChance(Character, stats, HitResult.Miss, _calcOpts.TargetLevel),  // Your chance for Boss to Miss you
                    StatConversion.GetDRAvoidanceChance(Character, stats, HitResult.Dodge, _calcOpts.TargetLevel), // Your chance Dodge
                    StatConversion.GetDRAvoidanceChance(Character, stats, HitResult.Parry, _calcOpts.TargetLevel), // Your chance Parry
                    0,                                                                                             // Your Chance to Block
                    0);                                                                                            // How much you Block when you Block
                // Save the new names

                _loadingCalculationOptions = false;
                Character.OnCalculationsInvalidated();
            }
        }
Exemple #2
0
        public static float EffectiveTargetArmorReduction(Character character, Stats stats, int targetArmor, int targetLevel)
        {
            float effectiveTargetArmor = GetEffectiveTargetArmor(character.Level, targetArmor, 0.0f, stats.ArmorPenetration, stats.ArmorPenetrationRating);
            float damageReduction      = StatConversion.GetArmorDamageReduction(targetLevel, effectiveTargetArmor, 0f, 0f, 0f);

            return(damageReduction);
        }
Exemple #3
0
        public void UpdateCalcs()
        {
            float fightLength = _calcOpts.FightLength * 60f;

            float bloodlustUptime = ((float)Math.Floor(fightLength / 600f) * 40f + (float)Math.Min(fightLength % 600f, 40f)) / fightLength;
            float bloodlustHaste  = 1f + (CalcOpts.Bloodlust ? (bloodlustUptime * .3f) : 0f);

            float awUptime = (float)Math.Ceiling((fightLength - 20f) / (180f - _talents.SanctifiedWrath * 30f)) * 20f / fightLength;

            AvengingWrathMulti = 1f + awUptime * .2f;

            float targetArmor = StatConversion.NPC_ARMOR[CalcOpts.TargetLevel - 80];

            float dr     = StatConversion.GetArmorDamageReduction(Character.Level, targetArmor, Stats.ArmorPenetration, 0f, Stats.ArmorPenetrationRating);
            float drAW   = dr * ((1 - awUptime) + (1 - .25f * _talents.SanctifiedWrath) * awUptime);
            float drNoAW = dr;

            ArmorReduction = 1f - drAW;

            BaseWeaponSpeed = (_character.MainHand == null || _character.MainHand.Speed == 0.0f) ? 3.5f : _character.MainHand.Speed; // NOTE by Kavan: added a check against speed == 0, it can happen when item data is still being downloaded
            float baseWeaponDamage = _character.MainHand == null ? 371.5f : (_character.MainHand.MinDamage + _character.MainHand.MaxDamage) / 2f;

            AttackSpeed        = BaseWeaponSpeed / ((1f + _stats.PhysicalHaste) * bloodlustHaste);
            WeaponDamage       = baseWeaponDamage + _stats.AttackPower * BaseWeaponSpeed / 14f;
            NormalWeaponDamage = baseWeaponDamage + _stats.AttackPower * 3.3f / 14f;
        }
Exemple #4
0
        public static float TargetArmorReduction(Character character, Stats stats, int targetArmor)
        {
            float damageReduction = StatConversion.GetArmorDamageReduction(character.Level, targetArmor,
                                                                           stats.ArmorPenetration, 0f, stats.ArmorPenetrationRating);

            return(damageReduction);
        }
Exemple #5
0
        public ShotRotationCalculator(Character character, CharacterCalculationsHunter calculatedStats, CalculationOptionsHunter options, double totalStaticHaste, double effectiveRAPAgainstMob, double abilitiesCritDmgModifier, double yellowCritDmgModifier, double weaponDamageAverage, double ammoDamage, double talentModifiers)
        {
            ratings = new HunterRatings();

            this.character                = character;
            this.calculatedStats          = calculatedStats;
            this.options                  = options;
            this.hawkRAPBonus             = ratings.HAWK_BONUS_AP * (1.0 + 0.5 * character.HunterTalents.AspectMastery);
            this.totalStaticHaste         = totalStaticHaste;
            this.effectiveRAPAgainstMob   = effectiveRAPAgainstMob;
            this.abilitiesCritDmgModifier = abilitiesCritDmgModifier;
            this.yellowCritDmgModifier    = yellowCritDmgModifier;
            this.weaponDamageAverage      = weaponDamageAverage;
            this.ammoDamage               = ammoDamage;
            this.talentModifiers          = talentModifiers;

            int targetArmor = options.TargetArmor;

            this.armorReduction = 1f - StatConversion.GetArmorDamageReduction(character.Level, targetArmor,
                                                                              calculatedStats.BasicStats.ArmorPenetration, 0f, calculatedStats.BasicStats.ArmorPenetrationRating);
            //double targetArmor = (options.TargetArmor - calculatedStats.BasicStats.ArmorPenetration) * (1.0 - calculatedStats.BasicStats.ArmorPenetrationRating / (ratings.ARP_RATING_PER_PERCENT * 100.0));
            //this.armorReduction = 1.0 - (targetArmor / (467.5 * options.TargetLevel + targetArmor - 22167.5));

            //reducedArmor *= (1f - character.HunterTalents.PiercingShots * 0.02f);

            this.talentedArmorReduction = 1f - StatConversion.GetArmorDamageReduction(character.Level, targetArmor,
                                                                                      calculatedStats.BasicStats.ArmorPenetration, character.HunterTalents.PiercingShots * 0.02f,
                                                                                      calculatedStats.BasicStats.ArmorPenetrationRating);
            //this.talentedArmorReduction = 1.0 - (targetArmor / (467.5 * options.TargetLevel + targetArmor - 22167.5));
        }
Exemple #6
0
        public static float ArmorReduction(Character character, Stats stats)
        {
            CalculationOptionsProtWarr calcOpts = character.CalculationOptions as CalculationOptionsProtWarr;

            return(StatConversion.GetArmorDamageReduction(calcOpts.TargetLevel, stats.Armor, 0.0f, 0.0f, 0.0f));
            // return Math.Max(0.0f, Math.Min(0.75f, stats.Armor / (stats.Armor + (467.5f * calcOpts.TargetLevel - 22167.5f))));
        }
Exemple #7
0
        protected float CalcMeleeDamage(bool canGlance, float bonusDamage)
        {
            int level      = Mommy.Options.TargetLevel;
            int levelDelta = level - 80;

            float characterSheetDamage
                = BaseMeleeDamage
                  + DamagePerAttackPower * CalcAttackPower()
                  + bonusDamage;
            float combatTableModifier
                = CalcMeleeHitChance()
                  + CalcMeleeCrit()
                  - StatConversion.WHITE_DODGE_CHANCE_CAP[levelDelta];

            if (canGlance)
            {
                combatTableModifier
                    -= .3f * StatConversion.WHITE_GLANCE_CHANCE_CAP[levelDelta];
            }
            float armorModifier
                = 1
                  - StatConversion.GetArmorDamageReduction(
                      level,
                      StatConversion.NPC_ARMOR[levelDelta],
                      Stats.ArmorPenetration, // arpen debuffs
                      0f,                     // arpen buffs
                      0f);                    // arpen rating

            return(characterSheetDamage
                   * combatTableModifier
                   * armorModifier
                   * MeleeModifiers.GetFinalDirectMultiplier());
        }
Exemple #8
0
        public static float TargetArmorReduction(Character character, Stats stats, int targetArmor)
        {
            float ignoreArmor = 0.0f;

            if (character.MainHand != null && (character.MainHand.Type == ItemType.OneHandMace))
            {
                ignoreArmor += character.WarriorTalents.MaceSpecialization * 0.03f;
            }

            return(StatConversion.GetArmorDamageReduction(character.Level, targetArmor, stats.ArmorPenetration, ignoreArmor, stats.ArmorPenetrationRating));
        }
Exemple #9
0
        protected float CalcMeleeDamage(bool canGlance, float bonusDamage)
        {
            int level      = Mommy.CalcOpts.TargetLevel;
            int levelDelta = level - Mommy.CalcOpts.PlayerLevel;

            if (levelDelta > 3)
            {
                levelDelta = 3;
            }

            float characterSheetDamage = BaseMeleeDamage + DamagePerAttackPower * CalcAttackPower() + bonusDamage;
            float combatTableModifier  = CalcMeleeHitChance() + CalcMeleeCrit() - StatConversion.WHITE_DODGE_CHANCE_CAP[levelDelta];

            if (canGlance)
            {
                combatTableModifier -= .3f * StatConversion.WHITE_GLANCE_CHANCE_CAP[levelDelta];
            }
            float armorModifier = 1f - StatConversion.GetArmorDamageReduction(level, StatConversion.NPC_ARMOR[levelDelta], Stats.TargetArmorReduction, 0f);

            return(characterSheetDamage * combatTableModifier * armorModifier * MeleeModifiers.GetFinalDirectMultiplier());
        }
Exemple #10
0
        // Now returns damage per cast to allow adjustments for fight length
        private float DoTreeCalcs(CharacterCalculationsMoonkin calcs, int playerLevel, int bossLevel, float effectiveNatureDamage, float treantLifespan)
        {
            float sunderPercent = calcs.BasicStats.TargetArmorReduction;
            float meleeHit      = calcs.SpellHit * (StatConversion.WHITE_MISS_CHANCE_CAP[bossLevel - playerLevel] / StatConversion.GetSpellMiss(playerLevel - bossLevel, false));
            float physicalDamageMultiplierBonus = (1f + calcs.BasicStats.BonusDamageMultiplier) * (1f + calcs.BasicStats.BonusPhysicalDamageMultiplier);
            float physicalDamageMultiplierReduc = (1f - calcs.BasicStats.DamageTakenReductionMultiplier) * (1f - calcs.BasicStats.PhysicalDamageTakenReductionMultiplier);
            // 932 = base AP, 57% spell power scaling
            float attackPower = 932.0f + (float)Math.Floor(0.57f * effectiveNatureDamage);
            // 1.65 s base swing speed
            float baseAttackSpeed = 1.65f;
            float attackSpeed     = baseAttackSpeed / (1 + calcs.BasicStats.PhysicalHaste);
            // 580 = base DPS
            float damagePerHit = (580f + attackPower / 14.0f) * baseAttackSpeed;
            // 5% base crit rate, inherit crit debuffs
            // Remove crit depression, as it doesn't appear to have an effect (unless it's base ~10% crit rate)
            float critRate = 0.05f;
            // White hit glancing rate
            float glancingRate = StatConversion.WHITE_GLANCE_CHANCE_CAP[bossLevel - playerLevel];
            // Hit rate determined by the amount of melee hit, not by spell hit
            float missRate = Math.Max(0f, StatConversion.WHITE_MISS_CHANCE_CAP[bossLevel - playerLevel] - meleeHit);
            // Since the trees inherit expertise from their hit, scale their hit rate such that when they are hit capped, they are expertise capped
            float dodgeRate = Math.Max(0f, StatConversion.WHITE_DODGE_CHANCE_CAP[bossLevel - playerLevel] * (missRate / StatConversion.WHITE_MISS_CHANCE_CAP[bossLevel - playerLevel]));
            // Armor damage reduction, including Sunder
            float damageReduction = StatConversion.GetArmorDamageReduction(playerLevel, StatConversion.NPC_ARMOR[bossLevel - playerLevel] * (1f - sunderPercent), 0, 0);

            // Final normal damage per swing
            damagePerHit *= 1.0f - damageReduction;
            damagePerHit *= physicalDamageMultiplierReduc;
            damagePerHit *= physicalDamageMultiplierBonus;
            // Damage per swing, including crits/glances/misses
            // This is a cheesy approximation of a true combat table, but because crit/miss/dodge rates will all be fairly low, I don't need to do the whole thing
            damagePerHit = (critRate * damagePerHit * 2.0f) + (glancingRate * damagePerHit * 0.75f) + ((1 - critRate - glancingRate - missRate - dodgeRate) * damagePerHit);
            // Total damage done in their estimated lifespan
            float damagePerTree = (treantLifespan * 30.0f / attackSpeed) * damagePerHit;

            return(3 * damagePerTree);
        }
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string>    dictValues = new Dictionary <string, string>();
            CalculationOptionsShadowPriest calcOpts   = character.CalculationOptions as CalculationOptionsShadowPriest;
            BossOptions BossOpts  = character.BossOptions;
            Stats       baseStats = BaseStats.GetBaseStats(character.Level, character.Class, character.Race);
            bool        Ptr       = calcOpts.PTR;

            dictValues.Add("Health", BasicStats.Health.ToString());
            float ResilienceCap = 0.15f, ResilienceFromRating = StatConversion.GetCritReductionFromResilience(1);
            float Resilience = StatConversion.GetCritReductionFromResilience(BasicStats.Resilience);

            dictValues.Add("Resilience", string.Format("{0}*-{1}% Damage from DoT and Mana Drains\n\r-{1}% Chance to be crit\r\n-{2}% Damage from Crits.\r\n{3}",
                                                       BasicStats.Resilience.ToString(),
                                                       (Resilience * 100f).ToString("0.00"),
                                                       (Resilience * 100f * 2.2f).ToString("0.00"),
                                                       (Resilience > ResilienceCap) ? (string.Format("{0} rating above cap", ((float)Math.Floor((Resilience - ResilienceCap) / ResilienceFromRating)).ToString("0"))) : (string.Format("{0} rating below cap", ((float)Math.Ceiling((ResilienceCap - Resilience) / ResilienceFromRating)).ToString("0")))));
            dictValues.Add("Stamina", BasicStats.Stamina.ToString());
            dictValues.Add("Mana", BasicStats.Mana.ToString());
            dictValues.Add("Intellect", BasicStats.Intellect.ToString());
            dictValues.Add("Spirit", Math.Floor(BasicStats.Spirit).ToString("0"));
            dictValues.Add("Spell Power", String.Format("{0}*{1} Bonus Shadow\r\n{2} Bonus Holy\r\n{3} from Inner Fire",
                                                        Math.Floor(BasicStats.SpellPower),
                                                        Math.Floor(BasicStats.SpellPower + BasicStats.SpellShadowDamageRating),
                                                        Math.Floor(BasicStats.SpellPower /*+ BasicStats.SpellHolyDamageRating*/),
                                                        BasicStats.PriestInnerFire * CalculationsShadowPriest.GetInnerFireSpellPowerBonus(character)));
            dictValues.Add("Regen", String.Format("{0}*MP5: {1}\r\nOutFSR: {2}", RegenInFSR.ToString("0"), BasicStats.Mp5.ToString(), RegenOutFSR.ToString("0")));

            dictValues.Add("Crit", string.Format("{0}%*{1}% from {2} Spell Crit rating\r\n{3}% from Intellect\r\n{4}% from Focused Will\r\n{5}% from Base Crit\r\n{6}% from Buffs\r\n{7}% on Mind Blast, Mind Flay and Mind Sear.\r\n{8}% on VT, SW:P and DP\r\n{9}% on Smite, Holy Fire and Penance.",
                                                 (BasicStats.SpellCrit * 100f).ToString("0.00"),
                                                 (StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f).ToString("0.00"),
                                                 BasicStats.CritRating.ToString("0"),
                                                 (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f).ToString("0.00"),
                                                 character.PriestTalents.FocusedWill,
                                                 (baseStats.SpellCrit * 100f).ToString("0.00"),
                                                 (BasicStats.SpellCrit * 100f - StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f - StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f - baseStats.SpellCrit * 100f - character.PriestTalents.FocusedWill).ToString("0.00"),
                                                 (BasicStats.SpellCrit * 100f + character.PriestTalents.MindMelt * 2f).ToString("0.00"),
                                                 (BasicStats.SpellCrit * 100f + character.PriestTalents.MindMelt * 3f).ToString("0.00"),
                                                 (BasicStats.SpellCrit * 100f + character.PriestTalents.HolySpecialization * 1f).ToString("0.00")));

#if RAWR3 || SILVERLIGHT
            float Hit = 100 - (StatConversion.GetSpellMiss(character.Level - BossOpts.Level, false) * 100);
#else
            float Hit = 100 - (StatConversion.GetSpellMiss(-calcOpts.TargetLevel, false) * 100);
#endif
            float  BonusHit   = BasicStats.SpellHit * 100f;
            float  RacialHit  = 0;
            string RacialText = "";
            if (character.Race == CharacterRace.Draenei)
            {
                RacialHit  = 1;
                RacialText = "1% from Draenei Racial\r\n";
                if (!character.ActiveBuffsContains("Heroic Presence"))
                {
                    BonusHit += 1;
                }
            }
            float DebuffHit = character.PriestTalents.Misery * 1f;
            if (character.ActiveBuffsConflictingBuffContains("Spell Hit Chance Taken"))
            {
                DebuffHit = 3f;
            }
            else
            {
                BonusHit += DebuffHit;
            }

            float RHitRating     = 0.01f / StatConversion.GetSpellHitFromRating(1);
            float ShadowFocusHit = character.PriestTalents.ShadowFocus * 1f;
            float HitShadow      = Hit + BonusHit + ShadowFocusHit;
            float HitHoly        = Hit + BonusHit;
            dictValues.Add("Hit", string.Format("{0}%*{1}% from {2} Hit Rating\r\n{3}% from Buffs\r\n{4}% from {5} points in Misery\r\n{6}% from {7} points in Shadow Focus\r\n{8}{9}% Hit with Shadow spells, {10}\r\n{11}% Hit with Holy spells, {12}",
                                                BonusHit.ToString("0.00"),
                                                (StatConversion.GetSpellHitFromRating(BasicStats.HitRating) * 100f).ToString("0.00"), BasicStats.HitRating,
                                                (BonusHit - StatConversion.GetSpellHitFromRating(BasicStats.HitRating) * 100f - RacialHit - DebuffHit).ToString("0.00"),
                                                DebuffHit, character.PriestTalents.Misery,
                                                ShadowFocusHit, character.PriestTalents.ShadowFocus,
                                                RacialText,
                                                HitShadow.ToString("0.00"), (HitShadow > 100f) ? string.Format("{0} hit rating above cap", Math.Floor((HitShadow - 100f) * RHitRating)) : string.Format("{0} hit rating below cap", Math.Ceiling((100f - HitShadow) * RHitRating)),
                                                HitHoly.ToString("0.00"), (HitHoly > 100f) ? string.Format("{0} hit rating above cap", Math.Floor((HitHoly - 100f) * RHitRating)) : string.Format("{0} hit rating below cap", Math.Ceiling((100f - HitHoly) * RHitRating))));

            dictValues.Add("Haste", string.Format("{0}%*{1}% from {2} Haste rating\r\n{3}% ({6}) points in Enlightenment\r\n{4}% from Buffs\r\n{5}s Global Cooldown",
                                                  (BasicStats.SpellHaste * 100f).ToString("0.00"), (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating) * 100f).ToString("0.00"), BasicStats.HasteRating.ToString(), (character.PriestTalents.Enlightenment * 2).ToString("0"), (((1f + BasicStats.SpellHaste) / (1f + StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating)) / (1f + character.PriestTalents.Enlightenment * 0.02f) - 1f) * 100f).ToString("0.00"), Math.Max(1.0f, 1.5f / (1 + BasicStats.SpellHaste)).ToString("0.00"), character.PriestTalents.Enlightenment));
            dictValues.Add("Armor", string.Format("{0}*{1}% Damage Reduction.",
                                                  (BasicStats.Armor + BasicStats.BonusArmor).ToString("0"),
                                                  (StatConversion.GetArmorDamageReduction(80, (BasicStats.Armor + BasicStats.BonusArmor), 0f, 0f, 0f) * 100f).ToString("0.00")));

            float[] Resistances =
            {
                0,
                BasicStats.ArcaneResistance + BasicStats.ArcaneResistanceBuff,
                BasicStats.FireResistance + BasicStats.FireResistanceBuff,
                BasicStats.FrostResistance + BasicStats.FrostResistanceBuff,
                BasicStats.NatureResistance + BasicStats.NatureResistanceBuff,
                BasicStats.ShadowResistance + BasicStats.ShadowResistanceBuff,
            };

            string[] ResistanceNames =
            {
                "None",
                "Arcane",
                "Fire",
                "Frost",
                "Nature",
                "Shadow",
            };

            string ResistanceString = "*Resistances:";

            float MaxResist      = Resistances[0];
            int   MaxResistIndex = 0;
            float AvgResist      = 0f;
            for (int x = 1; x < Resistances.Length; x++)
            {
                AvgResist += Resistances[x];
                if (Resistances[x] > MaxResist)
                {
                    MaxResist      = Resistances[x];
                    MaxResistIndex = x;
                }
                ResistanceString += string.Format("\r\n{0} : {1}", ResistanceNames[x], Resistances[x]);
            }
            AvgResist /= (Resistances.Length - 1);

            if (AvgResist == 0)
            {
                ResistanceString = "None" + ResistanceString;
            }
            else
            {
                string ResistanceName = (MaxResist == AvgResist) ? "All" : ResistanceNames[MaxResistIndex];
                ResistanceString  = string.Format("{0} : {1}", ResistanceName, MaxResist.ToString("0")) + ResistanceString;
                ResistanceString += string.Format("\r\n\r\nResist ({0}):", ResistanceName);
                ResistanceString += string.Format("\r\n{0}", StatConversion.GetResistanceTableString(character.Level + 3, character.Level, MaxResist, 0));
            }

            dictValues.Add("Resistance", ResistanceString);

            SolverBase solver = GetSolver(character, BasicStats);
            solver.Calculate(this);

            dictValues.Add("Rotation", string.Format("{0}*{1}", solver.Name, solver.Rotation));
            if (solver.SpellSimulation != null)
            {
                String s = "Spell Cast List:";
                int    i = 0;
                foreach (Spell spell in solver.SpellSimulation)
                {
                    if (i++ % 10 == 0)
                    {
                        s += "\r\n";
                    }
                    s += ", " + spell.Name;
                }
                s += "\r\n---Repeat---";
                dictValues.Add("Castlist", string.Format("{0}*{1}", solver.SpellSimulation.Count, s));
            }
            else
            {
                dictValues.Add("Castlist", "Empty");
            }
            dictValues.Add("DPS", string.Format("{0}*Damage Pr Second", solver.DPS.ToString("0")));
            //dictValues.Add("SustainDPS", string.Format("{0}*Mana restrained DPS", solver.SustainDPS.ToString("0")));

            float baseMana = BaseStats.GetBaseStats(character).Mana;

            dictValues.Add("SW Pain", new ShadowWordPain(BasicStats, character, baseMana, Ptr).ToString());
            DevouringPlague dp = new DevouringPlague(BasicStats, character, baseMana, Ptr);
            dictValues.Add("Devouring Plague", dp.ToString());
            if (dp.ImprovedDP != null)
            {
                dictValues.Add("Imp. Devouring Plague", dp.ImprovedDP.ToString());
            }
            else
            {
                dictValues.Add("Imp. Devouring Plague", "- *No required talents");
            }
            dictValues.Add("SW Death", new ShadowWordDeath(BasicStats, character, baseMana, Ptr).ToString());
            dictValues.Add("Mind Blast", new MindBlast(BasicStats, character, baseMana, Ptr).ToString());
            dictValues.Add("PW Shield", new PowerWordShield(BasicStats, character, baseMana, Ptr).ToString());

            if (character.PriestTalents.VampiricTouch > 0)
            {
                dictValues.Add("Vampiric Touch", new VampiricTouch(BasicStats, character, baseMana, Ptr).ToString());
            }
            else
            {
                dictValues.Add("Vampiric Touch", "- *No required talents");
            }

            if (character.PriestTalents.MindFlay > 0)
            {
                dictValues.Add("Mind Flay", new MindFlay(BasicStats, character, baseMana, Ptr).ToString());
            }
            else
            {
                dictValues.Add("Mind Flay", "- *No required talents");
            }

            dictValues.Add("Shadowfiend", new Shadowfiend(BasicStats, character, baseMana, Ptr).ToString());

            dictValues.Add("Smite", new Smite(BasicStats, character, baseMana, Ptr).ToString());
            dictValues.Add("Holy Fire", new HolyFire(BasicStats, character, baseMana, Ptr).ToString());
            if (character.PriestTalents.Penance > 0)
            {
                dictValues.Add("Penance", new Penance(BasicStats, character, baseMana, Ptr).ToString());
            }
            else
            {
                dictValues.Add("Penance", "- *No required talents");
            }

            return(dictValues);
        }
Exemple #12
0
        public void CritsAndResists()
        {
            #region Crits, Resists
            {
                // Attack Rolltable (DW):
                // 27.0% miss     (8.0% with 2H)
                //  6.5% dodge
                // 24.0% glancing (75% hit-dmg)
                // xx.x% crit
                // remaining = hit

                float targetArmor = calcOpts.BossArmor, totalArP = stats.ArmorPenetration;

                float arpBuffs = talents.BloodGorged * 2f / 100;

                physicalMitigation = 1f - StatConversion.GetArmorDamageReduction(character.Level, targetArmor,
                                                                                 stats.ArmorPenetration, arpBuffs, stats.ArmorPenetrationRating);

                calcs.EnemyMitigation = 1f - physicalMitigation;
                calcs.EffectiveArmor  = physicalMitigation;

                // Crit: Base .65%
                physCrits        = .0065f;
                physCrits       += StatConversion.GetPhysicalCritFromRating(stats.CritRating);
                physCrits       += StatConversion.GetPhysicalCritFromAgility(stats.Agility, CharacterClass.DeathKnight);
                physCrits       += .01f * (float)(talents.DarkConviction + talents.EbonPlaguebringer + talents.Annihilation);
                physCrits       += stats.PhysicalCrit;
                calcs.CritChance = physCrits;

                float chanceAvoided = 0.335f;

                float chanceDodged = StatConversion.WHITE_DODGE_CHANCE_CAP[calcOpts.TargetLevel - 80];

                calcs.DodgedMHAttacks = MH.chanceDodged;
                calcs.DodgedOHAttacks = OH.chanceDodged;

                if (character.MainHand != null)
                {
                    chanceDodged = MH.chanceDodged;
                }

                if (character.OffHand != null)
                {
                    if (DW)
                    {
                        chanceDodged += OH.chanceDodged;
                        chanceDodged /= 2;
                    }
                    else if (character.MainHand == null)
                    {
                        chanceDodged = OH.chanceDodged;
                    }
                }

                calcs.DodgedAttacks = chanceDodged;
                // Process White hits:
                float chanceMiss = DW ? StatConversion.WHITE_MISS_CHANCE_CAP_DW[calcOpts.TargetLevel - 80] : StatConversion.WHITE_MISS_CHANCE_CAP[calcOpts.TargetLevel - 80];
                chanceMiss -= StatConversion.GetPhysicalHitFromRating(stats.HitRating);
                chanceMiss -= hitBonus;
                chanceMiss -= stats.PhysicalHit;
                // Cap the Miss rate at 0%
                chanceMiss           = Math.Max(chanceMiss, 0f);
                calcs.MissedAttacks  = chanceMiss;
                whiteMiss            = chanceMiss;
                chanceAvoided        = chanceDodged + chanceMiss;
                calcs.AvoidedAttacks = chanceDodged + chanceMiss;

                // Process Yellow hits
                chanceMiss    = StatConversion.YELLOW_MISS_CHANCE_CAP[calcOpts.TargetLevel - 80];
                chanceMiss   -= StatConversion.GetPhysicalHitFromRating(stats.HitRating);
                chanceMiss   -= hitBonus;
                chanceMiss   -= stats.PhysicalHit;
                chanceMiss    = Math.Max(chanceMiss, 0f);
                chanceDodged  = MH.chanceDodged;
                missedSpecial = chanceMiss;
                dodgedSpecial = chanceDodged;
                // calcs.MissedAttacks = chanceMiss

                spellCrits            = 0f;
                spellCrits           += StatConversion.GetSpellCritFromRating(stats.CritRating);
                spellCrits           += stats.SpellCrit + stats.SpellCritOnTarget;
                spellCrits           += .01f * (float)(talents.DarkConviction + talents.EbonPlaguebringer);
                calcs.SpellCritChance = spellCrits;

                // Resists: Base 17%
                spellResist  = .17f;
                spellResist -= StatConversion.GetSpellHitFromRating(stats.HitRating);
                spellResist -= .01f * talents.Virulence;
                spellResist -= stats.SpellHit;
                if (spellResist < 0f)
                {
                    spellResist = 0f;
                }

                // Total physical misses
                totalMHMiss = calcs.DodgedMHAttacks + whiteMiss;
                totalOHMiss = calcs.DodgedOHAttacks + whiteMiss;
                double spellGCD    = (calcOpts.rotation.presence == CalculationOptionsDPSDK.Presence.Blood ? 1.5d / ((1 + (StatConversion.GetHasteFromRating(stats.HasteRating, CharacterClass.DeathKnight))) * (1d + stats.SpellHaste)) < 1d ? 1d : 1.5d / ((1 + (StatConversion.GetHasteFromRating(stats.HasteRating, CharacterClass.DeathKnight))) * (1d + stats.SpellHaste)): 1d);
                double physicalGCD = (calcOpts.rotation.presence == CalculationOptionsDPSDK.Presence.Blood ? 1.5d : 1d);
                float  minDuration = totalMeleeAbilities * (float)physicalGCD +
                                     totalSpellAbilities * (float)spellGCD;

                realDuration = (float)Math.Max(minDuration, calcOpts.rotation.CurRotationDuration);

                float dodgeMissPerRotation = (float)(totalMeleeAbilities - calcOpts.rotation.FrostStrike);
                chanceAvoided = chanceDodged + chanceMiss;
                double GChanceAvoided             = (1 / (1 - chanceAvoided)) - 1;
                double GSpellResist               = (1 / (1 - spellResist)) - 1;
                double ProbableGCDLossPerRotation = dodgeMissPerRotation * physicalGCD * GChanceAvoided +
                                                    (calcOpts.rotation.IcyTouch + calcOpts.rotation.Pestilence) * spellGCD * GSpellResist;

                realDuration += (float)(((minDuration + ProbableGCDLossPerRotation) / realDuration < 1 ? (minDuration + ProbableGCDLossPerRotation) / realDuration : 1) * ProbableGCDLossPerRotation);
                // This last line is a bit hackish, but basically the extra GCD is more inconvenient the closer we are to having a GCD-capped rotation; once we're GCD-capped, they cost the full value.
            }
            #endregion
        }
Exemple #13
0
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();
            Stats baseStats = BaseStats.GetBaseStats(character);

            dictValues.Add("Health", BasicStats.Health.ToString());
            dictValues.Add("Stamina", BasicStats.Stamina.ToString());
            float ResilienceCap = 0.15f, ResilienceFromRating = StatConversion.GetCritReductionFromResilience(1);
            float Resilience = StatConversion.GetCritReductionFromResilience(BasicStats.Resilience);

            dictValues.Add("Resilience", string.Format("{0}*-{1}% Damage from DoT and Mana Drains\n\r-{1}% Chance to be crit\r\n-{2}% Damage from Crits.\r\n{3}",
                                                       BasicStats.Resilience.ToString(),
                                                       (Resilience * 100f).ToString("0.00"),
                                                       (Resilience * 100f * 2.2f).ToString("0.00"),
                                                       (Resilience > ResilienceCap)?(string.Format("{0} rating above cap", ((float)Math.Floor((Resilience - ResilienceCap) / ResilienceFromRating)).ToString("0"))):(string.Format("{0} rating below cap", ((float)Math.Ceiling((ResilienceCap - Resilience) / ResilienceFromRating)).ToString("0")))));
            dictValues.Add("Mana", BasicStats.Mana.ToString());
            dictValues.Add("Intellect", BasicStats.Intellect.ToString());
            dictValues.Add("Spirit", Math.Floor(BasicStats.Spirit).ToString("0"));
            dictValues.Add("Spell Power", string.Format("{0}*{1} from Inner Fire",
                                                        Math.Floor(BasicStats.SpellPower).ToString("0"),
                                                        BasicStats.PriestInnerFire * CalculationsHealPriest.GetInnerFireSpellPowerBonus(character)));
            //dictValues.Add("Healing", Math.Floor(BasicStats.SpellPower * 1.88f).ToString("0"));
            dictValues.Add("In FSR MP5", string.Format("{0}*{1} from MP5\r\n{2} from Meditation\r\n{3} Outside FSR\r\n{4} OFSR w/MP5",
                                                       (BasicStats.Mp5 + RegenInFSR).ToString("0"),
                                                       BasicStats.Mp5.ToString("0"),
                                                       RegenInFSR.ToString("0"),
                                                       RegenOutFSR.ToString("0"),
                                                       (BasicStats.Mp5 + RegenOutFSR).ToString("0")));
            dictValues.Add("Spell Crit", string.Format("{0}%*{1}% from Intellect\r\n{2}% from {6} Crit rating\r\n{3}% from Focused Will\r\n{4}% Class Base\r\n{5}% from Buffs",
                                                       (BasicStats.SpellCrit * 100f).ToString("0.00"), (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f).ToString("0.00"), (StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f).ToString("0.00"), character.PriestTalents.FocusedWill.ToString("0"), (baseStats.SpellCrit * 100f).ToString("0.00"), (BasicStats.SpellCrit * 100f - baseStats.SpellCrit * 100f - StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f - StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f - character.PriestTalents.FocusedWill * 1f).ToString("0.00"), BasicStats.CritRating));
            dictValues.Add("Healing Crit", string.Format("{0}%*{1} ({1}%) points in Holy Specialization\r\n{2} ({3}%) points in Renewed Hope",
                                                         ((BasicStats.SpellCrit * 100f) + character.PriestTalents.HolySpecialization * 1f + character.PriestTalents.RenewedHope * 2f).ToString("0.00"),
                                                         character.PriestTalents.HolySpecialization, character.PriestTalents.RenewedHope, character.PriestTalents.RenewedHope * 2));
            dictValues.Add("Spell Haste", string.Format("{0}%*{1}% from {2} Haste rating\r\n{3}% ({6}) points in Enlightenment\r\n{4}% from Buffs\r\n{5}s Global Cooldown",
                                                        (BasicStats.SpellHaste * 100f).ToString("0.00"), (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating) * 100f).ToString("0.00"), BasicStats.HasteRating.ToString(), (character.PriestTalents.Enlightenment * 2).ToString("0"), (((1 + BasicStats.SpellHaste) / (1 + StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating)) / (1 + character.PriestTalents.Enlightenment * 0.02f) - 1) * 100f).ToString("0.00"), Math.Max(1.0f, 1.5f / (1 + BasicStats.SpellHaste)).ToString("0.00"), character.PriestTalents.Enlightenment));
            dictValues.Add("Armor", string.Format("{0}*{1}% Damage Reduction.",
                                                  (BasicStats.Armor + BasicStats.BonusArmor).ToString("0"),
                                                  (StatConversion.GetArmorDamageReduction(80, (BasicStats.Armor + BasicStats.BonusArmor), 0f, 0f, 0f) * 100f).ToString("0.00")));


            float[] Resistances =
            {
                0,
                BasicStats.ArcaneResistance + BasicStats.ArcaneResistanceBuff,
                BasicStats.FireResistance + BasicStats.FireResistanceBuff,
                BasicStats.FrostResistance + BasicStats.FrostResistanceBuff,
                BasicStats.NatureResistance + BasicStats.NatureResistanceBuff,
                BasicStats.ShadowResistance + BasicStats.ShadowResistanceBuff,
            };

            string[] ResistanceNames =
            {
                "None",
                "Arcane",
                "Fire",
                "Frost",
                "Nature",
                "Shadow",
            };

            string ResistanceString = "*Resistances:";

            float MaxResist      = Resistances[0];
            int   MaxResistIndex = 0;
            float AvgResist      = 0f;

            for (int x = 1; x < Resistances.Length; x++)
            {
                AvgResist += Resistances[x];
                if (Resistances[x] > MaxResist)
                {
                    MaxResist      = Resistances[x];
                    MaxResistIndex = x;
                }
                ResistanceString += string.Format("\r\n{0} : {1}", ResistanceNames[x], Resistances[x]);
            }
            AvgResist /= (Resistances.Length - 1);

            if (AvgResist == 0)
            {
                ResistanceString = "None" + ResistanceString;
            }
            else
            {
                string ResistanceName = (MaxResist == AvgResist) ? "All" : ResistanceNames[MaxResistIndex];
                ResistanceString  = string.Format("{0} : {1}", ResistanceName, MaxResist.ToString("0")) + ResistanceString;
                ResistanceString += string.Format("\r\n\r\nResist ({0}):", ResistanceName);
                ResistanceString += string.Format("\r\n{0}", StatConversion.GetResistanceTableString(character.Level + 3, character.Level, MaxResist, 0));
            }

            dictValues.Add("Resistance", ResistanceString);

            BaseSolver solver;

            if ((character.CalculationOptions as CalculationOptionsHealPriest).Role == eRole.CUSTOM)
            {
                solver = new AdvancedSolver(BasicStats, character);
            }
            else
            {
                solver = new Solver(BasicStats, character);
            }
            solver.Calculate(this);

            dictValues.Add("Role", string.Format("{0}*{1}", solver.Role, solver.ActionList));
            dictValues.Add("Burst", string.Format("{0}", HPSBurstPoints.ToString("0")));
            dictValues.Add("Sustained", string.Format("{0}", HPSSustainPoints.ToString("0")));

            dictValues.Add("Renew", new Renew(BasicStats, character).ToString());
            dictValues.Add("Flash Heal", new FlashHeal(BasicStats, character).ToString());
            dictValues.Add("Greater Heal", new Heal(BasicStats, character).ToString());
            dictValues.Add("PoH", new PrayerOfHealing(BasicStats, character).ToString());
            dictValues.Add("Binding Heal", new BindingHeal(BasicStats, character).ToString());
            dictValues.Add("Prayer of Mending", new PrayerOfMending(BasicStats, character).ToString());
            dictValues.Add("Power Word Shield", new PowerWordShield(BasicStats, character).ToString());
            dictValues.Add("Holy Nova", new HolyNova(BasicStats, character).ToString());

            if (character.PriestTalents.CircleOfHealing > 0)
            {
                dictValues.Add("CoH", new CircleOfHealing(BasicStats, character).ToString());
            }
            else
            {
                dictValues.Add("CoH", "- *No required talents");
            }

            if (character.PriestTalents.Lightwell > 0)
            {
                dictValues.Add("Lightwell", new Lightwell(BasicStats, character).ToString());
            }
            else
            {
                dictValues.Add("Lightwell", "- *No required talents");
            }

            if (character.PriestTalents.Penance > 0)
            {
                dictValues.Add("Penance", new Penance(BasicStats, character).ToString());
            }
            else
            {
                dictValues.Add("Penance", "- *No required talents");
            }

            if (Race == CharacterRace.Draenei)
            {
                dictValues.Add("Gift of the Naaru", new GiftOfTheNaaru(BasicStats, character).ToString());
            }
            else
            {
                dictValues.Add("Gift of the Naaru", "-");
            }
            dictValues.Add("Divine Hymn", new DivineHymn(BasicStats, character).ToString());
            dictValues.Add("Resurrection", new Resurrection(BasicStats, character).ToString());

            return(dictValues);
        }
Exemple #14
0
        public DRW(CombatTable combatTable, CharacterCalculationsDPSDK calcs, CalculationOptionsDPSDK calcOpts, Stats stats,
                   Character character, DeathKnightTalents talents)
        {
            bool DW = false;

            float dpsWhite              = 0f;
            float dpsBCB                = 0f;
            float dpsNecrosis           = 0f;
            float dpsDeathCoil          = 0f;
            float dpsIcyTouch           = 0f;
            float dpsPlagueStrike       = 0f;
            float dpsFrostFever         = 0f;
            float dpsBloodPlague        = 0f;
            float dpsDeathStrike        = 0f;
            float dpsHeartStrike        = 0f;
            float dpsWPFromFF           = 0f;
            float dpsWPFromBP           = 0f;
            float dpsWhiteMinusGlancing = 0f;
            float dpsWhiteBeforeArmor   = 0f;

            float IcyTouchAPMult    = 0.1f;
            float FrostFeverAPMult  = 0.055f;
            float BloodPlagueAPMult = 0.055f;
            float DeathCoilAPMult   = 0.15f;

            float OHMult = 0.5f;

            int   targetLevel = calcOpts.TargetLevel;
            float arpBuffs    = talents.BloodGorged * 2f / 100;
            float mitigation  = StatConversion.GetArmorDamageReduction(character.Level, calcOpts.BossArmor, stats.ArmorPenetration, arpBuffs, stats.ArmorPenetrationRating);

            mitigation = 1 - mitigation;
            float MHDPS = 0f, OHDPS = 0f;

            #region White Dmg
            {
                #region Main Hand
                {
                    float dpsMHglancing    = (StatConversion.WHITE_GLANCE_CHANCE_CAP[targetLevel - 80] * combatTable.MH.DPS) * 0.7f;
                    float dpsMHBeforeArmor = ((combatTable.MH.DPS * (1f - calcs.AvoidedAttacks - StatConversion.WHITE_GLANCE_CHANCE_CAP[targetLevel - 80])) * (1f + combatTable.physCrits)) + dpsMHglancing;
                    dpsWhiteMinusGlancing = dpsMHBeforeArmor - dpsMHglancing;
                    dpsWhiteBeforeArmor   = dpsMHBeforeArmor;
                    MHDPS = dpsMHBeforeArmor * mitigation;
                }
                #endregion

                #region Off Hand
                if (DW || (character.MainHand == null && character.OffHand != null))
                {
                    float dpsOHglancing    = (StatConversion.WHITE_GLANCE_CHANCE_CAP[targetLevel - 80] * combatTable.OH.DPS) * 0.7f;
                    float dpsOHBeforeArmor = ((combatTable.OH.DPS * (1f - calcs.AvoidedAttacks - StatConversion.WHITE_GLANCE_CHANCE_CAP[targetLevel - 80])) * (1f + combatTable.physCrits)) + dpsOHglancing;
                    dpsOHBeforeArmor      *= OHMult;
                    dpsWhiteMinusGlancing += dpsOHBeforeArmor - dpsOHglancing;
                    dpsWhiteBeforeArmor   += dpsOHBeforeArmor;
                    OHDPS = dpsOHBeforeArmor * mitigation;
                }
                #endregion

                dpsWhite = MHDPS + OHDPS;
            }
            #endregion

            #region Necrosis
            {
                dpsNecrosis = dpsWhiteMinusGlancing * (.04f * (float)talents.Necrosis); // doesn't proc off Glancings
            }
            #endregion

            #region Blood Caked Blade
            {
                float dpsMHBCB = 0f;
                if (combatTable.MH.damage != 0)
                {
                    float MHBCBDmg = (float)(combatTable.MH.damage * (.25f + .125f * calcOpts.rotation.AvgDiseaseMult));
                    dpsMHBCB = MHBCBDmg / combatTable.MH.hastedSpeed;
                }
                dpsBCB  = dpsMHBCB;
                dpsBCB *= .1f * (float)talents.BloodCakedBlade;
            }
            #endregion

            #region Death Coil
            {
                if (calcOpts.rotation.DeathCoil > 0f)
                {
                    float DCCD  = 1;
                    float DCDmg = 443f + (DeathCoilAPMult * stats.AttackPower);
                    dpsDeathCoil = DCDmg / DCCD;
                    float DCCritDmgMult = .5f * (2f + stats.BonusCritMultiplier);
                    float DCCrit        = 1f + ((combatTable.spellCrits + stats.BonusDeathCoilCrit) * DCCritDmgMult);
                    dpsDeathCoil *= DCCrit;

                    dpsDeathCoil *= 1f + (.05f * (float)talents.Morbidity);
                }
            }
            #endregion

            #region Icy Touch
            {
                if (calcOpts.rotation.IcyTouch > 0f)
                {
                    float ITCD  = 1;
                    float ITDmg = 236f + (IcyTouchAPMult * stats.AttackPower) + stats.BonusIcyTouchDamage;
                    ITDmg      *= 1f + .1f * (float)talents.ImprovedIcyTouch;
                    dpsIcyTouch = ITDmg / ITCD;
                    float ITCritDmgMult = .5f * (2f + stats.CritBonusDamage + stats.BonusCritMultiplier);
                    float ITCrit        = 1f + (Math.Min((combatTable.spellCrits + (.05f * (float)talents.Rime)), 1f) * ITCritDmgMult);
                    dpsIcyTouch *= ITCrit;
                }
            }
            #endregion

            #region Plague Strike
            {
                if (calcOpts.rotation.PlagueStrike > 0f)
                {
                    float PSCD  = 1;
                    float PSDmg = (combatTable.MH.baseDamage + ((stats.AttackPower / 14f) *
                                                                combatTable.normalizationFactor)) * 0.5f + 189f;
                    dpsPlagueStrike = PSDmg / PSCD;
                    float PSCritDmgMult = 1f + (.15f * (float)talents.ViciousStrikes) + stats.BonusCritMultiplier;
                    float PSCrit        = 1f + ((combatTable.physCrits + (.03f * (float)talents.ViciousStrikes) +
                                                 stats.BonusPlagueStrikeCrit) * PSCritDmgMult);

                    dpsPlagueStrike *= PSCrit;
                    dpsPlagueStrike *= 1f + (.1f * (float)talents.Outbreak);
                }
            }
            #endregion

            #region Frost Fever
            {
                if (calcOpts.rotation.IcyTouch > 0f ||
                    (talents.GlyphofHowlingBlast && calcOpts.rotation.HowlingBlast > 0f) ||
                    (talents.GlyphofDisease && calcOpts.rotation.Pestilence > 0f))
                {
                    float FFDmg = FrostFeverAPMult * stats.AttackPower + 25.6f;
                    dpsFrostFever  = FFDmg;
                    dpsFrostFever *= 1.15f;     // Patch 3.2: Diseases hit 15% harder.
                    dpsWPFromFF    = dpsFrostFever * combatTable.physCrits;
                }
            }
            #endregion

            #region Blood Plague
            {
                if (calcOpts.rotation.PlagueStrike > 0f || talents.GlyphofDisease)
                {
                    float BPDmg = BloodPlagueAPMult * stats.AttackPower + 31.1f;
                    dpsBloodPlague  = BPDmg;
                    dpsBloodPlague *= 1.15f; // Patch 3.2: Diseases hit 15% harder.
                    dpsWPFromBP     = dpsBloodPlague * combatTable.physCrits;
                }
            }
            #endregion

            #region Death Strike
            {
                if (calcOpts.rotation.DeathStrike > 0f)
                {
                    float DSCD = 1;
                    // TODO: This should be changed to make use of the new glyph stats:
                    float DSDmg = ((combatTable.MH.baseDamage + ((stats.AttackPower / 14f) * combatTable.normalizationFactor)) * 0.75f) + 222.75f;
                    DSDmg         *= 1f + 0.15f * (float)talents.ImprovedDeathStrike;
                    dpsDeathStrike = DSDmg / DSCD;
                    float DSCritDmgMult = 1f + (.15f * (float)talents.MightOfMograine) + stats.BonusCritMultiplier;
                    float DSCrit        = 1f + ((combatTable.physCrits +
                                                 (.03f * (float)talents.ImprovedDeathStrike) +
                                                 stats.BonusDeathStrikeCrit) * DSCritDmgMult);
                    dpsDeathStrike *= DSCrit;
                }
            }
            #endregion

            #region Heart Strike
            {
                if (talents.HeartStrike > 0 && calcOpts.rotation.HeartStrike > 0f)
                {
                    float HSCD  = 1;
                    float HSDmg = ((combatTable.MH.baseDamage + ((stats.AttackPower / 14f) * combatTable.normalizationFactor)) *
                                   0.5f) + 368f;
                    HSDmg         *= 1f + 0.1f * (float)calcOpts.rotation.AvgDiseaseMult * (1f + stats.BonusPerDiseaseHeartStrikeDamage);
                    dpsHeartStrike = HSDmg / HSCD;
                    //float HSCrit = 1f + combatTable.physCrits + ( .03f * (float)talents.Subversion );
                    float HSCritDmgMult = 1f + (.15f * (float)talents.MightOfMograine) + stats.BonusCritMultiplier;
                    float HSCrit        = 1f + ((combatTable.physCrits + (.03f * (float)talents.Subversion)) * HSCritDmgMult);
                    dpsHeartStrike  = (dpsHeartStrike) * HSCrit;
                    dpsHeartStrike *= 1f + (.15f * (float)talents.BloodyStrikes);
                }
            }
            #endregion

            float BCBMult          = 1f;
            float BloodPlagueMult  = 1f;
            float DeathCoilMult    = 1f;
            float FrostFeverMult   = 1f;
            float HeartStrikeMult  = 1f;
            float IcyTouchMult     = 1f;
            float NecrosisMult     = 1f;
            float DeathStrikeMult  = 1f;
            float PlagueStrikeMult = 1f;
            float WhiteMult        = 1f;

            float spellPowerMult      = 1f + stats.BonusSpellPowerMultiplier;
            float frostSpellPowerMult = 1f + stats.BonusSpellPowerMultiplier + Math.Max((stats.BonusFrostDamageMultiplier - stats.BonusShadowDamageMultiplier), 0f);
            float partialResist       = 0.94f;
            float physPowerMult       = 1f;

            #region Apply Physical Mitigation
            {
                float physMit = mitigation;
                physMit *= 1f + (!DW ? .02f * talents.TwoHandedWeaponSpecialization : 0f);

                dpsBCB           *= physMit;
                dpsHeartStrike   *= physMit;
                dpsDeathStrike   *= physMit;
                dpsPlagueStrike  *= physMit;
                WhiteMult        += physPowerMult - 1f;
                BCBMult          += physPowerMult - 1f;
                HeartStrikeMult  += physPowerMult - 1f;
                DeathStrikeMult  += physPowerMult - 1f;
                PlagueStrikeMult += physPowerMult - 1f;
            }
            #endregion

            #region Apply Magical Mitigation
            {
                // some of this applies to necrosis, I wonder if it is ever accounted for
                float magicMit = partialResist /** combatTable.spellResist*/;
                // magicMit = 1f - magicMit;

                dpsNecrosis    *= magicMit;
                dpsBloodPlague *= magicMit;
                dpsDeathCoil   *= magicMit * (1f - combatTable.spellResist);
                dpsFrostFever  *= magicMit;
                dpsIcyTouch    *= magicMit;


                NecrosisMult    += spellPowerMult - 1f;
                BloodPlagueMult += spellPowerMult - 1f;
                DeathCoilMult   += spellPowerMult - 1f;
                FrostFeverMult  += frostSpellPowerMult - 1f;
                IcyTouchMult    += frostSpellPowerMult - 1f;
            }
            #endregion


            #region Apply Multi-Ability Talent Multipliers
            {
                float BloodyVengeanceMult = .03f * (float)talents.BloodyVengeance;
                BCBMult          *= 1 + BloodyVengeanceMult;
                HeartStrikeMult  *= 1 + BloodyVengeanceMult;
                DeathStrikeMult  *= 1 + BloodyVengeanceMult;
                PlagueStrikeMult *= 1 + BloodyVengeanceMult;
                WhiteMult        *= 1 + BloodyVengeanceMult;

                float HysteriaCoeff = .2f / 2f; // current uptime is 50% for now
                float HysteriaMult  = HysteriaCoeff * (float)talents.Hysteria;
                BCBMult          *= 1 + HysteriaMult;
                HeartStrikeMult  *= 1 + HysteriaMult;
                DeathStrikeMult  *= 1 + HysteriaMult;
                PlagueStrikeMult *= 1 + HysteriaMult;
                WhiteMult        *= 1 + HysteriaMult;

                float BlackIceMult = .02f * (float)talents.BlackIce;
                FrostFeverMult  *= 1 + BlackIceMult;
                IcyTouchMult    *= 1 + BlackIceMult;
                DeathCoilMult   *= 1 + BlackIceMult;
                BloodPlagueMult *= 1 + BlackIceMult;

                float CryptFeverMult = .1f * (float)talents.CryptFever;
                float CryptFeverBuff = stats.BonusDiseaseDamageMultiplier;
                CryptFeverMult   = Math.Max(CryptFeverMult, CryptFeverBuff);
                FrostFeverMult  *= 1 + CryptFeverMult;
                BloodPlagueMult *= 1 + CryptFeverMult;
            }
            #endregion



            dpsDancingRuneWeapon = dpsWhite * WhiteMult * 17f +
                                   dpsBCB * BCBMult * 17f +
                                   dpsNecrosis * NecrosisMult * 17f +
                                   dpsDeathCoil * DeathCoilMult +
                                   dpsIcyTouch * IcyTouchMult +
                                   dpsPlagueStrike * PlagueStrikeMult +
                                   dpsFrostFever * (5f + talents.Epidemic) * FrostFeverMult +
                                   dpsBloodPlague * (5f + talents.Epidemic) * BloodPlagueMult +
                                   dpsDeathStrike * DeathStrikeMult * (talents.GlyphofDancingRuneWeapon ? 1f : 0f) +
                                   dpsHeartStrike * HeartStrikeMult * (5f + (talents.GlyphofDancingRuneWeapon ? 2f : 0f));
            dpsDancingRuneWeapon *= 0.5f;
        }
Exemple #15
0
 public static float EffectiveTargetArmorReduction(float armorPenetration, int targetArmor, int targetLevel)
 {
     return(StatConversion.GetArmorDamageReduction(targetLevel, targetArmor, 0f, armorPenetration, 0f));
 }
Exemple #16
0
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            dictValues.Add("Single Target Points", SingleTargetPoints.ToString());
            dictValues.Add("Sustained Points", SustainedPoints.ToString());
            dictValues.Add("Survival Points", SurvivalPoints.ToString());
            dictValues.Add("Overall Points", OverallPoints.ToString());

            dictValues.Add("Base Health", BasicStats.Health.ToString());
            dictValues.Add("Base Armor", Math.Round(BasicStats.Armor, 0) + "*Reduces damage taken by " + Math.Round(StatConversion.GetArmorDamageReduction(83, BasicStats.Armor, 0, 0, 0) * 100.0f, 2) + "%");
            dictValues.Add("Base Mana", BasicStats.Mana.ToString());
            dictValues.Add("Base Stamina", BasicStats.Stamina.ToString());
            dictValues.Add("Base Intellect", BasicStats.Intellect.ToString());
            dictValues.Add("Base Spirit", BasicStats.Spirit.ToString());
            dictValues.Add("Base Spell Power", (BasicStats.SpellPower).ToString() + "*" + BasicStats.Spirit * LocalCharacter.DruidTalents.ImprovedTreeOfLife * 0.05f + " from Improved Tree of Life");
            dictValues.Add("Base Spell Crit", BasicStats.SpellCrit.ToString());

            float speed_from_hr = (1f + StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating));
            float speed_from_sh = (1f + BasicStats.SpellHaste);
            float speed         = speed_from_hr * speed_from_sh;
            float hard          = (1.5f / (1f * speed_from_sh) - 1) * StatConversion.RATING_PER_SPELLHASTE;
            float untilcap      = hard - BasicStats.HasteRating;

            dictValues.Add("Base Spell Haste", Math.Round((speed - 1.0f) * 100.0f, 2) + "%*" + Math.Round((speed_from_sh - 1.0f) * 100.0f, 2) + "% from spell effects and talents\n" + Math.Round((speed_from_hr - 1.0f) * 100.0f, 2) + "% from " + BasicStats.HasteRating + " haste rating");
            // Use Nourish cast time to equal normal GCD
            Spell spell = new Nourish(LocalCharacter, BasicStats);

            dictValues.Add("Base Global CD", Math.Round(spell.gcd, 2) + " sec*" + Math.Ceiling(untilcap).ToString() + " Haste Rating until hard gcd cap");

            dictValues.Add("Health", CombatStats.Health.ToString());
            dictValues.Add("Armor", Math.Round(CombatStats.Armor, 0) + "*Reduces damage taken by " + Math.Round(StatConversion.GetArmorDamageReduction(83, CombatStats.Armor, 0, 0, 0) * 100.0f, 2) + "%");
            dictValues.Add("Mana", CombatStats.Mana.ToString());
            dictValues.Add("Stamina", CombatStats.Stamina.ToString());
            dictValues.Add("Intellect", CombatStats.Intellect.ToString());
            dictValues.Add("Spirit", CombatStats.Spirit.ToString());
            dictValues.Add("Spell Power", (CombatStats.SpellPower).ToString() + "*" + CombatStats.Spirit * LocalCharacter.DruidTalents.ImprovedTreeOfLife * 0.05f + " from Improved Tree of Life");
            dictValues.Add("Spell Crit", CombatStats.SpellCrit.ToString());

            speed_from_hr = (1f + StatConversion.GetSpellHasteFromRating(CombatStats.HasteRating));
            speed_from_sh = (1f + CombatStats.SpellHaste);
            speed         = speed_from_hr * speed_from_sh;
            hard          = (1.5f / (1f * speed_from_sh) - 1) * StatConversion.RATING_PER_SPELLHASTE;
            untilcap      = hard - CombatStats.HasteRating;

            dictValues.Add("Spell Haste", Math.Round((speed - 1.0f) * 100.0f, 2) + "%*" + Math.Round((speed_from_sh - 1.0f) * 100.0f, 2) + "% from spell effects and talents\n" + Math.Round((speed_from_hr - 1.0f) * 100.0f, 2) + "% from " + CombatStats.HasteRating + " haste rating");
            // Use Nourish cast time to equal normal GCD
            spell = Sustained.spellMix.nourish[0];
            dictValues.Add("Global CD", Math.Round(spell.gcd, 2) + " sec*" + Math.Ceiling(untilcap).ToString() + " Haste Rating until soft gcd cap");

            dictValues.Add("Total Time", Math.Round(Sustained.TotalTime, 2).ToString());
            dictValues.Add("Time until OOM (unreduced)", Math.Round(Sustained.TimeToOOM_unreduced, 2).ToString());
            dictValues.Add("Time until OOM", Math.Round(Sustained.TimeToOOM, 2).ToString());
            dictValues.Add("Total healing done", Math.Round(Sustained.TotalTime * SustainedHPS, 2).ToString()); // Has extra component from procs
            dictValues.Add("Sustained HPS", Math.Round(SustainedHPS, 2).ToString());
            dictValues.Add("Single Target HPS", Math.Round(SingleTargetHPS, 2).ToString());
            dictValues.Add("Mana regen per second", Math.Round(Sustained.ManaRegen, 2).ToString());
            dictValues.Add("Mana from innervates", Math.Round(Sustained.InnervateMana, 2).ToString());
            dictValues.Add("Average casts per minute", Math.Round(Sustained.spellMix.CastsPerMinute, 2).ToString());
            dictValues.Add("Average crits per minute", Math.Round(Sustained.spellMix.CritsPerMinute, 2).ToString());
            dictValues.Add("Average heals per minute", Math.Round(Sustained.spellMix.HealsPerMinute, 2).ToString());
            dictValues.Add("Rejuvenation casts per minute", Math.Round(Sustained.spellMix.RejuvCPM, 2).ToString());
            dictValues.Add("Rejuvenation average up", Math.Round(Sustained.spellMix.RejuvAvg, 2).ToString());
            dictValues.Add("Regrowth casts per minute", Math.Round(Sustained.spellMix.RegrowthCPM, 2).ToString());
            dictValues.Add("Regrowth average up", Math.Round(Sustained.spellMix.RegrowthAvg, 2).ToString());
            dictValues.Add("Lifebloom (stack) casts per minute", Math.Round(Sustained.spellMix.LifebloomStackCPM, 2).ToString());
            dictValues.Add("Lifebloom (stack) average up", Math.Round(Sustained.spellMix.LifebloomStackAvg, 2).ToString());
            dictValues.Add("Lifebloom (stack) method", LifebloomMethod_ToString(3, Sustained.rotSettings.lifeBloomType));
            dictValues.Add("Lifebloom casts per minute", Math.Round(Sustained.spellMix.LifebloomCPM, 2).ToString());
            dictValues.Add("Lifebloom average up", Math.Round(Sustained.spellMix.LifebloomAvg, 2).ToString());
            dictValues.Add("Nourish casts per minute", Math.Round(Sustained.spellMix.NourishCPM, 2).ToString());
            //dictValues.Add("Healing Touch casts per minute", Math.Round(, 2).ToString());
            dictValues.Add("Swiftmend casts per minute", Math.Round(Sustained.spellMix.SwiftmendCPM, 2).ToString());
            dictValues.Add("Wild Growth casts per minute", Math.Round(Sustained.spellMix.WildGrowthCPM, 2).ToString());
            dictValues.Add("Revitalize procs per minute", Math.Round(Sustained.spellMix.RevitalizeProcsPerMinute, 2).ToString());

            dictValues.Add("RJ Heal per tick", Math.Round(Sustained.spellMix.rejuvenate.PeriodicTickwithCrit, 2).ToString());
            dictValues.Add("RJ Tick time", Math.Round(Sustained.spellMix.rejuvenate.PeriodicTickTime, 2).ToString());
            dictValues.Add("RJ HPS", Math.Round(Sustained.spellMix.rejuvenate.HPS, 2).ToString());
            dictValues.Add("RJ HPM", Math.Round(Sustained.spellMix.rejuvenate.HPM, 2).ToString());
            dictValues.Add("RJ HPCT", Math.Round(Sustained.spellMix.rejuvenate.HPCT, 2).ToString());

            dictValues.Add("RG Heal", Sustained.spellMix.regrowth.ToString());
            dictValues.Add("RG Tick", Math.Round(Sustained.spellMix.regrowth.PeriodicTickwithCrit, 2).ToString());
            dictValues.Add("RG HPS", Math.Round(Sustained.spellMix.regrowth.HPS, 2).ToString());
            dictValues.Add("RG HPS (HoT only)", Math.Round(Sustained.spellMix.regrowth.HPS_HOT, 2).ToString());
            dictValues.Add("RG HPM", Math.Round(Sustained.spellMix.regrowth.HPM, 2).ToString());
            dictValues.Add("RG HPCT", Math.Round(Sustained.spellMix.regrowth.HPCT, 2).ToString());
            dictValues.Add("RG Heal (spam)", Sustained.spellMix.regrowthAgain.ToString());
            dictValues.Add("RG HPS (spam)", Math.Round(Sustained.spellMix.regrowthAgain.HPCT_DH, 2).ToString());
            dictValues.Add("RG HPM (spam)", Math.Round(Sustained.spellMix.regrowthAgain.HPM_DH, 2).ToString());
            dictValues.Add("RG HPCT (spam)", Math.Round(Sustained.spellMix.regrowthAgain.HPCT_DH, 2).ToString());

            dictValues.Add("LB Tick", Math.Round(Sustained.spellMix.lifebloom.PeriodicTick, 2).ToString());
            dictValues.Add("LB Bloom Heal", Math.Round(Sustained.spellMix.lifebloom.AverageHealingwithCrit, 2).ToString());
            dictValues.Add("LB HPS", Math.Round(Sustained.spellMix.lifebloom.HPS, 2).ToString());
            dictValues.Add("LB HPS (HoT only)", Math.Round(Sustained.spellMix.lifebloom.HPS_HOT, 2).ToString());
            dictValues.Add("LB HPM", Math.Round(Sustained.spellMix.lifebloom.HPM, 2).ToString());
            dictValues.Add("LB HPCT", Math.Round(Sustained.spellMix.lifebloom.HPCT, 2).ToString());

            dictValues.Add("LBx2 (fast stack) HPS", Math.Round(Sustained.spellMix.lifebloomFast2Stack.HPS, 2).ToString());
            dictValues.Add("LBx2 (fast stack) HPM", Math.Round(Sustained.spellMix.lifebloomFast2Stack.HPM, 2).ToString());
            dictValues.Add("LBx2 (fast stack) HPCT", Math.Round(Sustained.spellMix.lifebloomFast2Stack.HPCT, 2).ToString());
            dictValues.Add("LBx3 (fast stack) HPS", Math.Round(Sustained.spellMix.lifebloomFastStack.HPS, 2).ToString());
            dictValues.Add("LBx3 (fast stack) HPM", Math.Round(Sustained.spellMix.lifebloomFastStack.HPM, 2).ToString());
            dictValues.Add("LBx3 (fast stack) HPCT", Math.Round(Sustained.spellMix.lifebloomFastStack.HPCT, 2).ToString());
            dictValues.Add("LBx2 (slow stack) HPS", Math.Round(Sustained.spellMix.lifebloomSlow2Stack.HPS, 2).ToString());
            dictValues.Add("LBx2 (slow stack) HPM", Math.Round(Sustained.spellMix.lifebloomSlow2Stack.HPM, 2).ToString());
            dictValues.Add("LBx2 (slow stack) HPCT", Math.Round(Sustained.spellMix.lifebloomSlow2Stack.HPCT, 2).ToString());
            dictValues.Add("LBx3 (slow stack) HPS", Math.Round(Sustained.spellMix.lifebloomSlowStack.HPS, 2).ToString());
            dictValues.Add("LBx3 (slow stack) HPM", Math.Round(Sustained.spellMix.lifebloomSlowStack.HPM, 2).ToString());
            dictValues.Add("LBx3 (slow stack) HPCT", Math.Round(Sustained.spellMix.lifebloomSlowStack.HPCT, 2).ToString());
            dictValues.Add("LBx3 (rolling) Tick", Math.Round(Sustained.spellMix.lifebloomRollingStack.PeriodicTick, 2).ToString());
            dictValues.Add("LBx3 (rolling) HPS", Math.Round(Sustained.spellMix.lifebloomRollingStack.HPS, 2).ToString());
            dictValues.Add("LBx3 (rolling) HPM", Math.Round(Sustained.spellMix.lifebloomRollingStack.HPM, 2).ToString());
            dictValues.Add("LBx3 (rolling) HPCT", Math.Round(Sustained.spellMix.lifebloomRollingStack.HPCT, 2).ToString());

            dictValues.Add("HT Heal", Sustained.spellMix.healingTouch.ToString());
            dictValues.Add("HT HPS", Math.Round(Sustained.spellMix.healingTouch.HPCT_DH, 2).ToString());
            dictValues.Add("HT HPM", Math.Round(Sustained.spellMix.healingTouch.HPM_DH, 2).ToString());
            dictValues.Add("HT HPCT", Math.Round(Sustained.spellMix.healingTouch.HPCT_DH, 2).ToString());

            dictValues.Add("WG first Tick", Math.Round(Sustained.spellMix.wildGrowth.Tick[0], 2).ToString());
            dictValues.Add("WG HPS(single target)", Math.Round(Sustained.spellMix.wildGrowth.HPS, 2).ToString());
            dictValues.Add("WG HPM(single target)", Math.Round(Sustained.spellMix.wildGrowth.HPM, 2).ToString());
            dictValues.Add("WG HPS(max)", Math.Round(Sustained.spellMix.wildGrowth.HPS * Sustained.spellMix.wildGrowth.maxTargets, 2).ToString());
            dictValues.Add("WG HPM(max)", Math.Round(Sustained.spellMix.wildGrowth.HPM * Sustained.spellMix.wildGrowth.maxTargets, 2).ToString());

            dictValues.Add("N Heal", Sustained.spellMix.nourish[0].ToString());
            dictValues.Add("N HPM", Math.Round(Sustained.spellMix.nourish[0].HPM_DH, 2).ToString());
            dictValues.Add("N HPS", Math.Round(Sustained.spellMix.nourish[0].HPCT_DH, 2).ToString());
            dictValues.Add("N HPCT", Math.Round(Sustained.spellMix.nourish[0].HPCT_DH, 2).ToString());
            dictValues.Add("N (1 HoT) Heal", Sustained.spellMix.nourish[1].ToString());
            dictValues.Add("N (1 HoT) HPM", Math.Round(Sustained.spellMix.nourish[1].HPM_DH, 2).ToString());
            dictValues.Add("N (1 HoT) HPS", Math.Round(Sustained.spellMix.nourish[1].HPCT_DH, 2).ToString());
            dictValues.Add("N (1 HoT) HPCT", Math.Round(Sustained.spellMix.nourish[1].HPCT_DH, 2).ToString());
            dictValues.Add("N (2 HoTs) Heal", Sustained.spellMix.nourish[2].ToString());
            dictValues.Add("N (2 HoTs) HPM", Math.Round(Sustained.spellMix.nourish[2].HPM_DH, 2).ToString());
            dictValues.Add("N (2 HoTs) HPS", Math.Round(Sustained.spellMix.nourish[2].HPCT_DH, 2).ToString());
            dictValues.Add("N (2 HoTs) HPCT", Math.Round(Sustained.spellMix.nourish[2].HPCT_DH, 2).ToString());
            dictValues.Add("N (3 HoTs) Heal", Sustained.spellMix.nourish[3].ToString());
            dictValues.Add("N (3 HoTs) HPM", Math.Round(Sustained.spellMix.nourish[3].HPM_DH, 2).ToString());
            dictValues.Add("N (3 HoTs) HPS", Math.Round(Sustained.spellMix.nourish[3].HPCT_DH, 2).ToString());
            dictValues.Add("N (3 HoTs) HPCT", Math.Round(Sustained.spellMix.nourish[3].HPCT_DH, 2).ToString());
            dictValues.Add("N (4 HoTs) Heal", Sustained.spellMix.nourish[4].ToString());
            dictValues.Add("N (4 HoTs) HPM", Math.Round(Sustained.spellMix.nourish[4].HPM_DH, 2).ToString());
            dictValues.Add("N (4 HoTs) HPS", Math.Round(Sustained.spellMix.nourish[4].HPCT_DH, 2).ToString());
            dictValues.Add("N (4 HoTs) HPCT", Math.Round(Sustained.spellMix.nourish[4].HPCT_DH, 2).ToString());

            Swiftmend swift = new Swiftmend(LocalCharacter, CombatStats, new Rejuvenation(LocalCharacter, CombatStats), null);

            dictValues.Add("SM Rejuv Heal", swift.ToString());
            dictValues.Add("SM Rejuv HPM", Math.Round(swift.HPM, 2).ToString());
            dictValues.Add("SM Rejuv Lost Ticks", Math.Round(swift.rejuvTicksLost, 2).ToString());
            swift = new Swiftmend(LocalCharacter, BasicStats, null, new Regrowth(LocalCharacter, BasicStats));
            dictValues.Add("SM Regrowth Heal", swift.ToString());
            dictValues.Add("SM Regrowth HPM", Math.Round(swift.HPM, 2).ToString());
            dictValues.Add("SM Regrowth Lost Ticks", Math.Round(swift.regrowthTicksLost, 2).ToString());
            swift = new Swiftmend(LocalCharacter, BasicStats, new Rejuvenation(LocalCharacter, BasicStats), new Regrowth(LocalCharacter, BasicStats));
            dictValues.Add("SM Both Heal", swift.ToString());
            dictValues.Add("SM Both HPM", Math.Round(swift.HPM, 2).ToString());
            dictValues.Add("SM Both Rejuv Lost Ticks", Math.Round(swift.rejuvTicksLost, 2).ToString());
            dictValues.Add("SM Both Regrowth Lost Ticks", Math.Round(swift.regrowthTicksLost, 2).ToString());

            return(dictValues);
        }
Exemple #17
0
 public static float ArmorReduction(Player player)
 {
     return(StatConversion.GetArmorDamageReduction(player.BossOpts.Level, player.Stats.Armor, 0f, 0f));
 }
Exemple #18
0
 public static float TargetArmorReduction(Player player)
 {
     return(StatConversion.GetArmorDamageReduction(player.Character.Level, player.BossOpts.Armor,
                                                   player.Stats.TargetArmorReduction, 0.0f));
 }
Exemple #19
0
 public static float TargetArmorReduction(int attackerLevel, float armorPenetration, int targetArmor)
 {
     return(StatConversion.GetArmorDamageReduction(attackerLevel, targetArmor, armorPenetration, 0f, 0f));
 }
Exemple #20
0
 public static float ArmorReduction(Character character, Stats stats, int targetLevel)
 {
     return(StatConversion.GetArmorDamageReduction(targetLevel, stats.Armor, 0.0f, 0.0f, 0.0f));
 }