Exemple #1
0
        public override float GetOptimizableCalculationValue(string calculation)
        {
            switch (calculation)
            {
            case "Health": return(BasicStats.Health);

            case "Avoided Attacks %": return(AvoidedAttacks);

            case "Hit Rating": return(BasicStats.HitRating);

            case "Hit Rating %": return(StatConversion.GetPhysicalHitFromRating(BasicStats.HitRating) * 100);

            case "Expertise Rating": return(BasicStats.ExpertiseRating);

            case "Expertise": return(StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating));

            case "Expertise Rating %": return(StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating) * 0.25f);

            case "Nature Resist": return(BasicStats.NatureResistance);

            case "Fire Resist": return(BasicStats.FireResistance);

            case "Frost Resist": return(BasicStats.FrostResistance);

            case "Shadow Resist": return(BasicStats.ShadowResistance);

            case "Arcane Resist": return(BasicStats.ArcaneResistance);
                //case "Custom Rotation DPS": return CustomRotation.DPS;
            }
            return(0f);
        }
Exemple #2
0
        private void ConvertRatings(Stats stats, PaladinTalents talents, CalculationOptionsHealadin calcOpts)
        {
            stats.Stamina *= 1f + stats.BonusStaminaMultiplier;

            // Intellect is used to calculate initial mana pool.
            // To avoid temporary intellect from highest stat procs changing initial mana pool
            // we track temporary intellect separatly in HighestStat property and combine it with intellect
            // when needed.
            // TODO: However this doesn't help to deal with pure temporary intellect procs (if there are any).
            // NOTE: If we add highest stat to intellect after we calculate mana, the only visible change
            // will be the displayed intellect for the character.
            stats.Intellect   *= (1f + stats.BonusIntellectMultiplier);
            stats.HighestStat *= (1f + stats.BonusIntellectMultiplier);

            stats.SpellCrit = stats.SpellCrit +
                              StatConversion.GetSpellCritFromIntellect(
                stats.Intellect + stats.HighestStat,
                CharacterClass.Paladin) +
                              StatConversion.GetSpellCritFromRating(stats.CritRating, CharacterClass.Paladin);

            // I want to track haste before talent seperately, going to use RangedHaste for that.
            // I plan to use this on the "Stats" page so I can report sources of haste seperatly
            stats.RangedHaste = (1f + stats.SpellHaste) *
                                (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin))
                                - 1f;

            // calculating physical haste for use in melee attacks, which will generate mana
            // can also divide spellhaste / physicalhaste to get orignal value of spellhaste, which is from buffs as far as I can tell
            stats.PhysicalHaste = (1f + talents.JudgementsOfThePure * 0.03f) *
                                  (1f + talents.SpeedOfLight * 0.01f) *
                                  (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin))
                                  - 1f;

            stats.SpellHaste = (1f + talents.JudgementsOfThePure * 0.03f) *
                               (1f + talents.SpeedOfLight * 0.01f) *
                               (1f + stats.SpellHaste) *
                               (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin))
                               - 1f;

            // GetManaFromIntellect/GetHealthFromStamina account for the fact
            // that the first 20 Int/Sta only give 1 Mana/Health each.
            stats.Mana += StatConversion.GetManaFromIntellect(stats.Intellect, CharacterClass.Paladin) *
                          (1f + stats.BonusManaMultiplier);
            stats.Health += StatConversion.GetHealthFromStamina(stats.Stamina, CharacterClass.Paladin);

            stats.PhysicalHit += StatConversion.GetPhysicalHitFromRating(
                stats.HitRating,
                CharacterClass.Paladin);
        }
        private void ConvertRatings(Stats stats, PaladinTalents talents, CalculationOptionsHealadin calcOpts)
        {
            stats.Stamina *= 1f + stats.BonusStaminaMultiplier;

            // Intellect is used to calculate initial mana pool.
            // To avoid temporary intellect from highest stat procs changing initial mana pool
            // we track temporary intellect separatly in HighestStat property and combine it with intellect
            // when needed.
            // TODO: However this doesn't help to deal with pure temporary intellect procs (if there are any).
            // NOTE: If we add highest stat to intellect after we calculate mana, the only visible change
            // will be the displayed intellect for the character.
            stats.Intellect   *= (1f + stats.BonusIntellectMultiplier) * (1f + talents.DivineIntellect * .02f);
            stats.HighestStat *= (1f + stats.BonusIntellectMultiplier) * (1f + talents.DivineIntellect * .02f);

            stats.SpellPower += 0.04f * (stats.Intellect + stats.HighestStat) * talents.HolyGuidance;
            stats.SpellCrit   = stats.SpellCrit +
                                StatConversion.GetSpellCritFromIntellect(
                stats.Intellect + stats.HighestStat,
                CharacterClass.Paladin) +
                                StatConversion.GetSpellCritFromRating(stats.CritRating, CharacterClass.Paladin) +
                                talents.SanctityOfBattle * .01f +
                                talents.Conviction * .01f;

            stats.SpellHaste = (1f + talents.JudgementsOfThePure * (calcOpts.JotP ? .03f : 0f)) *
                               (1f + stats.SpellHaste) *
                               (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin))
                               - 1f;

            // GetManaFromIntellect/GetHealthFromStamina account for the fact
            // that the first 20 Int/Sta only give 1 Mana/Health each.
            stats.Mana += StatConversion.GetManaFromIntellect(stats.Intellect, CharacterClass.Paladin) *
                          (1f + stats.BonusManaMultiplier);
            stats.Health += StatConversion.GetHealthFromStamina(stats.Stamina, CharacterClass.Paladin);

            stats.PhysicalHit += StatConversion.GetPhysicalHitFromRating(
                stats.HitRating,
                CharacterClass.Paladin);
        }
Exemple #4
0
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            float critRating = BasicStats.CritRating;
            float hitRating  = BasicStats.HitRating;

            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            dictValues.Add("Health", BasicStats.Health.ToString("N0"));
            dictValues.Add("Strength", BasicStats.Strength.ToString("N0"));
            dictValues.Add("Agility", string.Format("{0:0}*Provides {1:P} crit chance", BasicStats.Agility, StatConversion.GetCritFromAgility(BasicStats.Agility, CharacterClass.DeathKnight)));
            dictValues.Add("Attack Power", BasicStats.AttackPower.ToString("N0"));
            dictValues.Add("Crit Rating", string.Format("{0:0}*Provides {1:P} crit chance", critRating, StatConversion.GetCritFromRating(critRating, CharacterClass.DeathKnight)));
            dictValues.Add("Hit Rating", string.Format("{0:0}*Negates {1:P} melee miss / {2:P} spell miss", hitRating, StatConversion.GetPhysicalHitFromRating(hitRating, CharacterClass.DeathKnight), StatConversion.GetSpellHitFromRating(hitRating, CharacterClass.DeathKnight)));
            dictValues.Add("Expertise", string.Format("{0:0.00} / {1:0.00}*Negates {2:P} / {3:P} dodge chance", MHExpertise, OHExpertise, StatConversion.GetDodgeParryReducFromExpertise(MHExpertise), StatConversion.GetDodgeParryReducFromExpertise(OHExpertise)));
            dictValues.Add("Haste Rating", string.Format("{0:0}*Increases attack speed by {1:P}", BasicStats.HasteRating, StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.DeathKnight)));

            dictValues.Add("Armor", BasicStats.Armor.ToString("N0"));
            dictValues.Add("Resilience", BasicStats.Resilience.ToString("F0"));
            dictValues.Add("Mastery", string.Format("{0:N0}*Rating: {1:N0}", BasicStats.Mastery, BasicStats.MasteryRating));

            dictValues.Add("Weapon Damage", MHWeaponDamage.ToString("N2") + " / " + OHWeaponDamage.ToString("N2"));
            dictValues.Add("Attack Speed", MHAttackSpeed.ToString("N2") + " / " + OHAttackSpeed.ToString("N2"));
            dictValues.Add("Crit Chance", string.Format("{0:P}", BasicStats.PhysicalCrit));
            dictValues.Add("Avoided Attacks", string.Format("{0:P}*{1:P} Dodged, {2:P} Missed", AvoidedAttacks, DodgedAttacks, MissedAttacks));
            dictValues.Add("Enemy Mitigation", string.Format("{0:P}*{1:0} effective enemy armor", EnemyMitigation, EffectiveArmor));

            dictValues.Add("White HitChance", string.Format("{0:P}*Include Glance & Crit Chance", WhiteHitChance));
            dictValues.Add("Yellow HitChance", string.Format("{0:P}", YellowHitChance));

            foreach (int i in EnumHelper.GetValues(typeof(DKability)))
            {
                dictValues.Add(Enum.GetName(typeof(DKability), i), string.Format("{0:N2}*{1:P}", dpsSub[i], (dpsSub[i] / DPSPoints)));
            }
            dictValues.Add("Total DPS", DPSPoints.ToString("N2"));

            dictValues.Add("Rotation Duration", RotationTime.ToString() + " secs");
            dictValues.Add("Blood", Blood.ToString());
            dictValues.Add("Frost", Frost.ToString());
            dictValues.Add("Unholy", Unholy.ToString());
            dictValues.Add("Death", Death.ToString());
            dictValues.Add("Runic Power", Death.ToString());
            dictValues.Add("RE Runes", FreeRERunes.ToString("N2"));
            dictValues.Add("Rune Cooldown", m_RuneCD.ToString("N2"));

            PopulateSingleUseValues(dictValues, "BB", DKability.BloodBoil);
            PopulateSingleUseValues(dictValues, "BP", DKability.BloodPlague);
            PopulateSingleUseValues(dictValues, "BS", DKability.BloodStrike);
            PopulateSingleUseValues(dictValues, "DC", DKability.DeathCoil);
            PopulateSingleUseValues(dictValues, "DnD", DKability.DeathNDecay);
            PopulateSingleUseValues(dictValues, "DS", DKability.DeathStrike);
            PopulateSingleUseValues(dictValues, "Fest", DKability.FesteringStrike);
            PopulateSingleUseValues(dictValues, "FF", DKability.FrostFever);
            PopulateSingleUseValues(dictValues, "FS", DKability.FrostStrike);
            PopulateSingleUseValues(dictValues, "HS", DKability.HeartStrike);
            PopulateSingleUseValues(dictValues, "HB", DKability.HowlingBlast);
            PopulateSingleUseValues(dictValues, "IT", DKability.IcyTouch);
            PopulateSingleUseValues(dictValues, "NS", DKability.NecroticStrike);
            PopulateSingleUseValues(dictValues, "OB", DKability.Obliterate);
            PopulateSingleUseValues(dictValues, "PS", DKability.PlagueStrike);
            PopulateSingleUseValues(dictValues, "RS", DKability.RuneStrike);
            PopulateSingleUseValues(dictValues, "SS", DKability.ScourgeStrike);
            return(dictValues);
        }
Exemple #5
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 #6
0
 public static float BonusHitPercentage(Character character, Stats stats)
 {
     return(StatConversion.GetPhysicalHitFromRating(stats.HitRating, CharacterClass.Warrior) + stats.PhysicalHit);
     //return ((stats.HitRating * ProtWarr.HitRatingToHit) / 100.0f) + stats.PhysicalHit;
 }
Exemple #7
0
 public static float BonusHitPercentage(Player player)
 {
     return(StatConversion.GetPhysicalHitFromRating(player.Stats.HitRating, CharacterClass.Warrior) + player.Stats.PhysicalHit);
 }
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            float critRating = BasicStats.CritRating;

            float hitRating = BasicStats.HitRating;

            float armorPenetrationRating = BasicStats.ArmorPenetrationRating;

            float attackPower = BasicStats.AttackPower;

            if (ActiveBuffs.Contains(Buff.GetBuffByName("Improved Hunter's Mark")))
            {
                attackPower -= 110f * (1f + BasicStats.BonusAttackPowerMultiplier);
            }

            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            dictValues.Add("Health", BasicStats.Health.ToString("N0"));
            dictValues.Add("Strength", BasicStats.Strength.ToString("N0"));
            dictValues.Add("Agility", string.Format("{0:0}*Provides {1:P} crit chance", BasicStats.Agility, StatConversion.GetCritFromAgility(BasicStats.Agility, CharacterClass.DeathKnight)));
            dictValues.Add("Attack Power", attackPower.ToString("N0"));
            dictValues.Add("Crit Rating", string.Format("{0:0}*Provides {1:P} crit chance", critRating, StatConversion.GetCritFromRating(critRating, CharacterClass.DeathKnight)));
            dictValues.Add("Hit Rating", string.Format("{0:0}*Negates {1:P} melee miss / {2:P} spell miss", hitRating, StatConversion.GetPhysicalHitFromRating(hitRating, CharacterClass.DeathKnight), StatConversion.GetSpellHitFromRating(hitRating, CharacterClass.DeathKnight)));
            dictValues.Add("Expertise", string.Format("{0:0.00} / {1:0.00}*Negates {2:P} / {3:P} dodge chance", MHExpertise, OHExpertise, StatConversion.GetDodgeParryReducFromExpertise(MHExpertise), StatConversion.GetDodgeParryReducFromExpertise(OHExpertise)));
            dictValues.Add("Haste Rating", string.Format("{0:0}*Increases attack speed by {1:P}", BasicStats.HasteRating, StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.DeathKnight)));
            dictValues.Add("Armor Penetration Rating", armorPenetrationRating.ToString("N0"));
            dictValues.Add("Armor", BasicStats.Armor.ToString("N0"));
            dictValues.Add("Resilience", BasicStats.Resilience.ToString("F0"));

            dictValues.Add("Weapon Damage", MHWeaponDamage.ToString("N2") + " / " + OHWeaponDamage.ToString("N2"));
            dictValues.Add("Attack Speed", MHAttackSpeed.ToString("N2") + " / " + OHAttackSpeed.ToString("N2"));
            dictValues.Add("Crit Chance", string.Format("{0:P}", CritChance));
            dictValues.Add("Avoided Attacks", string.Format("{0:P}*{1:P} Dodged, {2:P} Missed", AvoidedAttacks, DodgedAttacks, MissedAttacks));
            dictValues.Add("Enemy Mitigation", string.Format("{0:P}*{1:0} effective enemy armor", EnemyMitigation, EffectiveArmor));

            dictValues.Add("BCB", string.Format("{0:N2}*{1:P}", BCBDPS, (float)BCBDPS / DPSPoints));
            dictValues.Add("Blood Plague", string.Format("{0:N2}*{1:P}", BloodPlagueDPS, (float)BloodPlagueDPS / DPSPoints));
            dictValues.Add("Blood Strike", string.Format("{0:N2}*{1:P}", BloodStrikeDPS, (float)BloodStrikeDPS / DPSPoints));
            dictValues.Add("Death Coil", string.Format("{0:N2}*{1:P}", DeathCoilDPS, (float)DeathCoilDPS / DPSPoints));
            dictValues.Add("DRW", string.Format("{0:N2}*{1:P}, wait for " + DRWStats + " proc", DRWDPS, (float)DRWDPS / DPSPoints));
            dictValues.Add("Frost Fever", string.Format("{0:N2}*{1:P}", FrostFeverDPS, (float)FrostFeverDPS / DPSPoints));
            dictValues.Add("Frost Strike", string.Format("{0:N2}*{1:P}", FrostStrikeDPS, (float)FrostStrikeDPS / DPSPoints));
            dictValues.Add("Gargoyle", string.Format("{0:N2}*{1:P}", GargoyleDPS, (float)GargoyleDPS / DPSPoints));
            dictValues.Add("Heart Strike", string.Format("{0:N2}*{1:P}", HeartStrikeDPS, (float)HeartStrikeDPS / DPSPoints));
            dictValues.Add("Howling Blast", string.Format("{0:N2}*{1:P}", HowlingBlastDPS, (float)HowlingBlastDPS / DPSPoints));
            dictValues.Add("Icy Touch", string.Format("{0:N2}*{1:P}", IcyTouchDPS, (float)IcyTouchDPS / DPSPoints));
            dictValues.Add("Necrosis", string.Format("{0:N2}*{1:P}", NecrosisDPS, (float)NecrosisDPS / DPSPoints));
            dictValues.Add("Obliterate", string.Format("{0:N2}*{1:P}", ObliterateDPS, (float)ObliterateDPS / DPSPoints));
            dictValues.Add("Death Strike", string.Format("{0:N2}*{1:P}", DeathStrikeDPS, (float)DeathStrikeDPS / DPSPoints));
            dictValues.Add("Plague Strike", string.Format("{0:N2}*{1:P}", PlagueStrikeDPS, (float)PlagueStrikeDPS / DPSPoints));
            dictValues.Add("Scourge Strike", string.Format("{0:N2}*{1:P}", ScourgeStrikeDPS, (float)ScourgeStrikeDPS / DPSPoints));
            dictValues.Add("Unholy Blight", string.Format("{0:N2}*{1:P}", UnholyBlightDPS, (float)UnholyBlightDPS / DPSPoints));
            dictValues.Add("Wandering Plague", string.Format("{0:N2}*{1:P}", WanderingPlagueDPS, (float)WanderingPlagueDPS / DPSPoints));
            dictValues.Add("White", string.Format("{0:N2}*{1:P}", WhiteDPS, (float)WhiteDPS / DPSPoints));
            dictValues.Add("Ghoul", string.Format("{0:N2}*{1:P}", GhoulDPS, (float)GhoulDPS / DPSPoints));
            dictValues.Add("Bloodworms", string.Format("{0:N2}*{1:P}", BloodwormsDPS, (float)BloodwormsDPS / DPSPoints));
            dictValues.Add("Other", string.Format("{0:N2}*{1:P}", OtherDPS, (float)OtherDPS / DPSPoints));
            dictValues.Add("Total DPS", DPSPoints.ToString("N2"));


            return(dictValues);
        }
Exemple #9
0
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            try
            {
                dictValues.Add("Overall Points", OverallPoints.ToString());
                dictValues.Add("DPS Points", DPSPoints.ToString());
                dictValues.Add("Survivability Points", SurvivabilityPoints.ToString());

                float baseMiss  = StatConversion.WHITE_MISS_CHANCE_CAP[TargetLevel - 85] - BasicStats.PhysicalHit;
                float baseDodge = StatConversion.WHITE_DODGE_CHANCE_CAP[TargetLevel - 85] - StatConversion.GetDodgeParryReducFromExpertise(BasicStats.Expertise);
                float capMiss   = (float)Math.Ceiling(baseMiss * StatConversion.RATING_PER_PHYSICALHIT);
                float capDodge  = (float)Math.Ceiling(baseDodge * 400f * StatConversion.RATING_PER_EXPERTISE);

                string tipMiss = string.Empty;
                if (BasicStats.HitRating > capMiss)
                {
                    tipMiss = string.Format("*Hit Rating %: {0}%\nOver the cap by {1} Hit Rating", StatConversion.GetPhysicalHitFromRating(BasicStats.HitRating) * 100, BasicStats.HitRating - capMiss);
                }
                else if (BasicStats.HitRating < capMiss)
                {
                    tipMiss = string.Format("*Hit Rating %: {0}%\nUnder the cap by {1} Hit Rating", StatConversion.GetPhysicalHitFromRating(BasicStats.HitRating) * 100, capMiss - BasicStats.HitRating);
                }
                else
                {
                    tipMiss = string.Format("*Hit Rating %: {0}%\nExactly at the cap", StatConversion.GetPhysicalHitFromRating(BasicStats.HitRating) * 100);
                }

                string tipDodge = string.Empty;
                if (BasicStats.ExpertiseRating > capDodge)
                {
                    tipDodge = string.Format("*Expertise Rating %: {0}%\nOver the cap by {1} Expertise Rating", StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating) * 0.25f, BasicStats.ExpertiseRating - capDodge);
                }
                else if (BasicStats.ExpertiseRating < capDodge)
                {
                    tipDodge = string.Format("*Expertise Rating %: {0}%\nUnder the cap by {1} Expertise Rating", StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating) * 0.25f, capDodge - BasicStats.ExpertiseRating);
                }
                else
                {
                    tipDodge = string.Format("*Expertise Rating %: {0}%\nExactly at the cap", StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating) * 0.25f);
                }

                string tipHaste = string.Format("*Haste Rating %: {0}%", StatConversion.GetPhysicalHasteFromRating(BasicStats.HasteRating, CharacterClass.Druid) * 100f);

                string tipMastery = string.Format("*Increases the damage done by your bleed abilities by {0}%", ((StatConversion.GetMasteryFromRating(BasicStats.MasteryRating, CharacterClass.Druid) + 8f) * 0.031f) * 100f);

                dictValues.Add("Health", BasicStats.Health.ToString());
                dictValues.Add("Attack Power", BasicStats.AttackPower.ToString());
                dictValues.Add("Agility", BasicStats.Agility.ToString());
                dictValues.Add("Strength", BasicStats.Strength.ToString());
                dictValues.Add("Crit Rating", BasicStats.CritRating.ToString());
                dictValues.Add("Hit Rating", BasicStats.HitRating.ToString() + tipMiss);
                dictValues.Add("Expertise Rating", BasicStats.ExpertiseRating.ToString() + tipDodge);
                dictValues.Add("Mastery Rating", BasicStats.MasteryRating.ToString() + tipMastery);
                dictValues.Add("Haste Rating", BasicStats.HasteRating.ToString() + tipHaste);

                dictValues.Add("Avoided Attacks", string.Format("{0}%*{1}% Dodged, {2}% Missed", AvoidedAttacks, DodgedAttacks, MissedAttacks));
                dictValues.Add("Crit Chance", CritChance.ToString() + "%");
                dictValues.Add("Attack Speed", AttackSpeed.ToString() + "s");
                dictValues.Add("Armor Mitigation", ArmorMitigation.ToString() + "%");

                dictValues.Add("Optimal Rotation", HighestDPSRotation.ToString());
                //dictValues.Add("Optimal Rotation DPS", HighestDPSRotation.DPS.ToString());
                //dictValues.Add("Custom Rotation DPS", CustomRotation.DPS.ToString());


                float chanceNonAvoided = 1f - (AvoidedAttacks / 100f);
                dictValues.Add("Melee", Abilities.MeleeStats.ToString());
                dictValues.Add("Mangle", Abilities.MangleStats.ToString());
                dictValues.Add("Shred", Abilities.ShredStats.ToString());
                dictValues.Add("Ravage", Abilities.RavageStats.ToString());
                dictValues.Add("Rake", Abilities.RakeStats.ToString());
                dictValues.Add("Rip", Abilities.RipStats.ToString());
                dictValues.Add("Bite", Abilities.BiteStats.ToString());


                //string[] abilityStats = MeleeStats.GetStatsTexts(HighestDPSRotation.MeleeCount, 0, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration);
                //dictValues.Add("Melee Usage", abilityStats[0]);
                //dictValues.Add("Melee Stats", abilityStats[1]);
                //abilityStats = MangleStats.GetStatsTexts(HighestDPSRotation.MangleCount, 0, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration);
                //dictValues.Add("Mangle Usage", abilityStats[0]);
                //dictValues.Add("Mangle Stats", abilityStats[1]);
                //abilityStats = ShredStats.GetStatsTexts(HighestDPSRotation.ShredCount, 0, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration);
                //dictValues.Add("Shred Usage", abilityStats[0]);
                //dictValues.Add("Shred Stats", abilityStats[1]);
                //abilityStats = RakeStats.GetStatsTexts(HighestDPSRotation.RakeCount, 0, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration);
                //dictValues.Add("Rake Usage", abilityStats[0]);
                //dictValues.Add("Rake Stats", abilityStats[1]);
                //abilityStats = RipStats.GetStatsTexts(HighestDPSRotation.RipCount, 0, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration);
                //dictValues.Add("Rip Usage", abilityStats[0]);
                //dictValues.Add("Rip Stats", abilityStats[1]);
                //abilityStats = RoarStats.GetStatsTexts(HighestDPSRotation.RoarCount, HighestDPSRotation.RoarCP, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration);
                //dictValues.Add("Roar Usage", abilityStats[0]);
                //dictValues.Add("Roar Stats", abilityStats[1]);
                //abilityStats = BiteStats.GetStatsTexts(HighestDPSRotation.BiteCount, HighestDPSRotation.BiteCP, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration);
                //dictValues.Add("Bite Usage", abilityStats[0]);
                //dictValues.Add("Bite Stats", abilityStats[1]);

                //string attackFormat = "{0}%*Damage Per Hit: {1}, Damage Per Swing: {2}\r\n{0}% of Total Damage, {3} Damage Done";
                //dictValues.Add("Melee Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.MeleeDamageTotal / HighestDPSRotation.DamageTotal, MeleeDamagePerHit, MeleeDamagePerSwing, HighestDPSRotation.MeleeDamageTotal));
                //dictValues.Add("Mangle Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.MangleDamageTotal / HighestDPSRotation.DamageTotal, MangleDamagePerHit, MangleDamagePerSwing, HighestDPSRotation.MangleDamageTotal));
                //dictValues.Add("Shred Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.ShredDamageTotal / HighestDPSRotation.DamageTotal, ShredDamagePerHit, ShredDamagePerSwing, HighestDPSRotation.ShredDamageTotal));
                //dictValues.Add("Rake Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.RakeDamageTotal / HighestDPSRotation.DamageTotal, RakeDamagePerHit, RakeDamagePerSwing, HighestDPSRotation.RakeDamageTotal));
                //dictValues.Add("Rip Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.RipDamageTotal / HighestDPSRotation.DamageTotal, RipDamagePerHit, RipDamagePerSwing, HighestDPSRotation.RipDamageTotal));
                //dictValues.Add("Bite Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.BiteDamageTotal / HighestDPSRotation.DamageTotal, BiteDamagePerHit, BiteDamagePerSwing, HighestDPSRotation.BiteDamageTotal));

                //string rotationDescription = string.Empty;
                //try
                //{
                //    rotationDescription = string.Format("{0}*Keep {1}cp Savage Roar up.\r\n{2}{3}{4}{5}Use {6} for combo points.",
                //        HighestDPSRotation.Name.Replace(" + ", "+"), HighestDPSRotation.RoarCP,
                //        HighestDPSRotation.Name.Contains("Rake") ? "Keep Rake up.\r\n" : "",
                //        HighestDPSRotation.Name.Contains("Rip") ? "Keep 5cp Rip up.\r\n" : "",
                //        HighestDPSRotation.Name.Contains("Mangle") ? "Keep Mangle up.\r\n" : "",
                //        HighestDPSRotation.Name.Contains("Bite") ? string.Format("Use {0}cp Ferocious Bites to spend extra combo points.\r\n", HighestDPSRotation.BiteCP) : "",
                //        HighestDPSRotation.Name.Contains("Shred") ? "Shred" : "Mangle");
                //}
                //catch (Exception ex)
                //{
                //    ex.ToString();
                //}
            }
            catch (Exception ex)
            {
                new Base.ErrorBox()
                {
                    Title        = "Error Getting Cat Dictionary Values",
                    Function     = "GetCharacterDisplayCalculationValues()",
                    TheException = ex,
                }.Show();
            }
            return(dictValues);
        }
Exemple #10
0
        public static float HitChance(Character character, Stats stats, int targetLevel)
        {
            float physicalHit = StatConversion.GetPhysicalHitFromRating(stats.HitRating, CharacterClass.Paladin) + stats.PhysicalHit;

            return(Math.Min(1f, (1f - StatConversion.WHITE_MISS_CHANCE_CAP[targetLevel - 80]) + physicalHit));
        }