private String getExpertiseString()
        {   // using 26.5 for display purposes as its pointless warning over cap if 26.1 Expertise for example.
            String caps = "";

            if (TotalExpertiseMH == TotalExpertiseOH)
            {
                if (TotalExpertiseMH > 26.5f)
                {
                    caps = "{0} (Over Cap)*{1} Expertise\r\n{2} Expertise Rating\r\n{3}% Dodged\r\n{4}% Parried";
                }
                else if (TotalExpertiseMH < 26)
                {
                    caps = "{0} (Under Cap)*{1} Expertise\r\n{2} Expertise Rating\r\n{3}% Dodged\r\n{4}% Parried";
                }
                else
                {
                    caps = "{0}*{1} Expertise\r\n{2} Expertise Rating\r\n{3}% Dodged\r\n{4}% Parried";
                }
                return(String.Format(caps,
                                     TotalExpertiseMH.ToString("F0", CultureInfo.InvariantCulture),
                                     BasicStats.Expertise.ToString("F0", CultureInfo.InvariantCulture),
                                     BasicStats.ExpertiseRating.ToString("F0", CultureInfo.InvariantCulture),
                                     DodgedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                     ParriedAttacks.ToString("F2", CultureInfo.InvariantCulture)));
            }
            else
            {
                if (TotalExpertiseMH > 26.5f && TotalExpertiseOH > 26.5f)
                {
                    caps = "{0}/{1} (Over Cap)*MH/OH\r\n{2} Expertise\r\n{3} Expertise Rating\r\n{4}% Dodged\r\n{5}% Parried";
                }
                else if (TotalExpertiseMH > 26.5f)
                {
                    caps = "{0}/{1} (MH Over Cap)*MH/OH\r\n{2} Expertise\r\n{3} Expertise Rating\r\n{4}% OH Dodged\r\n{5}% Parried";
                }
                else if (TotalExpertiseOH > 26.5f)
                {
                    caps = "{0}/{1} (OH Over Cap)*MH/OH\r\n{2} Expertise\r\n{3} Expertise Rating\r\n{4}% MH Dodged\r\n{5}% Parried";
                }
                else if (TotalExpertiseMH < 26f)
                {
                    caps = "{0}/{1} (MH Under Cap)*MH/OH\r\n{2} Expertise\r\n{3} Expertise Rating\r\n{4}% Dodged";
                }
                else
                {
                    caps = "{0}/{1}*MH/OH\r\n{2} Expertise\r\n{3} Expertise Rating\r\n{4}% Dodged";
                }
                return(String.Format(caps,
                                     TotalExpertiseMH.ToString("F0", CultureInfo.InvariantCulture),
                                     TotalExpertiseOH.ToString("F0", CultureInfo.InvariantCulture),
                                     BasicStats.Expertise.ToString("F0", CultureInfo.InvariantCulture),
                                     BasicStats.ExpertiseRating.ToString("F0", CultureInfo.InvariantCulture),
                                     DodgedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                     ParriedAttacks.ToString("F2", CultureInfo.InvariantCulture)));
            }
        }
示例#2
0
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            int   levelDifference = TargetLevel - CharacterLevel;
            float baseMiss        = StatConversion.WHITE_MISS_CHANCE_CAP[levelDifference] - BasicStats.PhysicalHit;
            float baseDodge       = StatConversion.WHITE_DODGE_CHANCE_CAP[levelDifference] - StatConversion.GetDodgeParryReducFromExpertise(BasicStats.Expertise);
            float baseParry       = StatConversion.WHITE_PARRY_CHANCE_CAP[levelDifference] - 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);
            float capParry        = (float)Math.Ceiling(baseParry * 400f * StatConversion.RATING_PER_EXPERTISE);

            string tipMiss = string.Empty;

            if (BasicStats.HitRating > capMiss)
            {
                tipMiss = string.Format("*Over the cap by {0} Hit Rating", BasicStats.HitRating - capMiss);
            }
            else if (BasicStats.HitRating < capMiss)
            {
                tipMiss = string.Format("*Under the cap by {0} Hit Rating", capMiss - BasicStats.HitRating);
            }
            else
            {
                tipMiss = "*Exactly at the cap";
            }

            string tipDodgeParry = string.Empty;

            if (BasicStats.ExpertiseRating > capDodge)
            {
                tipDodgeParry = string.Format("*Over the dodge cap by {0} Expertise Rating\r\n", BasicStats.ExpertiseRating - capDodge);
            }
            else if (BasicStats.ExpertiseRating < capDodge)
            {
                tipDodgeParry = string.Format("*Under the dodge cap by {0} Expertise Rating\r\n", capDodge - BasicStats.ExpertiseRating);
            }
            else
            {
                tipDodgeParry = "*Exactly at the dodge cap";
            }

            if (BasicStats.ExpertiseRating > capParry)
            {
                tipDodgeParry += string.Format("Over the parry cap by {0} Expertise Rating", BasicStats.ExpertiseRating - capParry);
            }
            else if (BasicStats.ExpertiseRating < capParry)
            {
                tipDodgeParry += string.Format("Under the parry cap by {0} Expertise Rating", capParry - BasicStats.ExpertiseRating);
            }
            else
            {
                tipDodgeParry += "Exactly at the parry cap";
            }



            int   armorCap = (int)Math.Ceiling(6502.5f * TargetLevel - 474502.5f);
            float levelDifferenceAvoidance = 0.002f * levelDifference;
            float targetCritReduction      = StatConversion.NPC_LEVEL_CRIT_MOD[levelDifference];

            /*int defToCap = 0, resToCap = 0;
             * if (CritReduction < targetCritReduction)
             * {
             *  //while (((float)Math.Floor((BasicStats.DefenseRating + defToCap) / (123f / 52f)) * 0.04f)
             *  //+ BasicStats.Resilience / (2050f / 52f) + BasicStats.CritChanceReduction < targetCritReduction)
             *  //    defToCap++;
             *  //while (((float)Math.Floor(BasicStats.DefenseRating / (123f / 52f)) * 0.04f)
             *  //+ (BasicStats.Resilience + resToCap) / (2050f / 52f) + BasicStats.CritChanceReduction < targetCritReduction)
             *  //    resToCap++;
             *  while (((float)Math.Floor(StatConversion.GetDefenseFromRating(BasicStats.DefenseRating + defToCap)) * 0.0004f)
             + StatConversion.GetCritReductionFromResilience(BasicStats.Resilience)
             + BasicStats.CritChanceReduction < targetCritReduction)
             +      defToCap++;
             +  while (((float)Math.Floor(StatConversion.GetDefenseFromRating(BasicStats.DefenseRating)) * 0.0004f)
             + StatConversion.GetCritReductionFromResilience(BasicStats.Resilience + resToCap)
             + BasicStats.CritChanceReduction < targetCritReduction)
             +      resToCap++;
             + }
             + else if (CritReduction > targetCritReduction)
             + {
             +  //while (((float)Math.Floor((BasicStats.DefenseRating + defToCap) / (123f / 52f)) * 0.04f)
             +  //+ BasicStats.Resilience / (2050f / 52f) + BasicStats.CritChanceReduction > targetCritReduction)
             +  //    defToCap--;
             +  //while (((float)Math.Floor(BasicStats.DefenseRating / (123f / 52f)) * 0.04f)
             +  //+ (BasicStats.Resilience + resToCap) / (2050f / 52f) + BasicStats.CritChanceReduction > targetCritReduction)
             +  //    resToCap--;
             +
             +  while (((float)Math.Floor(StatConversion.GetDefenseFromRating(BasicStats.DefenseRating + defToCap)) * 0.0004f)
             + StatConversion.GetCritReductionFromResilience(BasicStats.Resilience) + BasicStats.CritChanceReduction > targetCritReduction)
             +      defToCap--;
             +  while (((float)Math.Floor(StatConversion.GetDefenseFromRating(BasicStats.DefenseRating)) * 0.0004f)
             + StatConversion.GetCritReductionFromResilience(BasicStats.Resilience + resToCap) + BasicStats.CritChanceReduction > targetCritReduction)
             +      resToCap--;
             +  defToCap++;
             +  resToCap++;
             + }*/

            // Changed to not just give a resist rating, but a breakdown of the resulting resist values in the tooltip
            string tipResist = string.Empty;

            tipResist = StatConversion.GetResistanceTableString(TargetLevel, CharacterLevel, BasicStats.NatureResistance, 0);
            dictValues.Add("Nature Resist", BasicStats.NatureResistance.ToString() + "*" + tipResist);
            tipResist = StatConversion.GetResistanceTableString(TargetLevel, CharacterLevel, BasicStats.ArcaneResistance, 0);
            dictValues.Add("Arcane Resist", BasicStats.ArcaneResistance.ToString() + "*" + tipResist);
            tipResist = StatConversion.GetResistanceTableString(TargetLevel, CharacterLevel, BasicStats.FrostResistance, 0);
            dictValues.Add("Frost Resist", BasicStats.FrostResistance.ToString() + "*" + tipResist);
            tipResist = StatConversion.GetResistanceTableString(TargetLevel, CharacterLevel, BasicStats.FireResistance, 0);
            dictValues.Add("Fire Resist", BasicStats.FireResistance.ToString() + "*" + tipResist);
            tipResist = StatConversion.GetResistanceTableString(TargetLevel, CharacterLevel, BasicStats.ShadowResistance, 0);
            dictValues.Add("Shadow Resist", BasicStats.ShadowResistance.ToString() + "*" + tipResist);

            dictValues.Add("Health", BasicStats.Health.ToString());
            dictValues.Add("Agility", BasicStats.Agility.ToString());
            dictValues.Add("Armor", BasicStats.Armor.ToString());
            dictValues.Add("Stamina", BasicStats.Stamina.ToString());
            dictValues.Add("Dodge Rating", BasicStats.DodgeRating.ToString());
            dictValues.Add("Mastery", string.Format("{0}*{1} Mastery Rating",
                                                    StatConversion.GetMasteryFromRating(BasicStats.MasteryRating) + 8f,
                                                    BasicStats.MasteryRating.ToString()));
            dictValues.Add("Resilience", BasicStats.Resilience.ToString());
            dictValues.Add("Dodge", Dodge.ToString("0.000%"));
            dictValues.Add("Miss", Miss.ToString("0.000%"));
            if (BasicStats.Armor == armorCap)
            {
                dictValues.Add("Armor Damage Reduction", DamageReductionFromArmor.ToString("0.000%")
                               + string.Format("*Exactly at the armor cap against level {0} mobs.", TargetLevel));
            }
            else if (BasicStats.Armor > armorCap)
            {
                dictValues.Add("Armor Damage Reduction", DamageReductionFromArmor.ToString("0.000%")
                               + string.Format("*Over the armor cap by {0} armor.", BasicStats.Armor - armorCap));
            }
            else
            {
                dictValues.Add("Armor Damage Reduction", DamageReductionFromArmor.ToString("0.000%")
                               + string.Format("*Short of the armor cap by {0} armor.", armorCap - BasicStats.Armor));
            }
            dictValues.Add("Total Damage Reduction", TotalConstantDamageReduction.ToString("0.000%"));
            dictValues.Add("Avoidance PreDR", AvoidancePreDR.ToString("0.000%"));
            dictValues.Add("Avoidance PostDR", AvoidancePostDR.ToString("0.000%"));
            dictValues.Add("Total Mitigation", TotalMitigation.ToString("0.000%"));
            dictValues.Add("Damage Taken", DamageTaken.ToString("0.000%"));
            dictValues.Add("Savage Defense", string.Format(
                               "{0} ~ {1}*{0} chance to absorb incoming hit\r\n{1} absorbed per hit\r\n{2} of incoming damage absorbed",
                               SavageDefenseChance.ToString("0.000%"), SavageDefenseValue, SavageDefensePercent.ToString("0.000%")));
            dictValues.Add("Chance to be Crit", ((0.05f + levelDifferenceAvoidance) - CritReduction).ToString("0.000%"));
            dictValues.Add("Overall Points", OverallPoints.ToString());
            dictValues.Add("Mitigation Points", MitigationPoints.ToString());
            dictValues.Add("Survival Points", string.Format("{0}*{1} Before Soft Cap", SurvivabilityPoints.ToString(), SurvivalPointsRaw.ToString()));
            dictValues.Add("Threat Points", ThreatPoints.ToString());

            dictValues["Nature Survival"] = NatureSurvivalPoints.ToString();
            dictValues["Frost Survival"]  = FrostSurvivalPoints.ToString();
            dictValues["Fire Survival"]   = FireSurvivalPoints.ToString();
            dictValues["Shadow Survival"] = ShadowSurvivalPoints.ToString();
            dictValues["Arcane Survival"] = ArcaneSurvivalPoints.ToString();


            dictValues["Strength"]             = BasicStats.Strength.ToString();
            dictValues["Attack Power"]         = string.Format("{0}*{1} with Vengeance", (BasicStats.AttackPower - AverageVengeanceAP), BasicStats.AttackPower);
            dictValues["Average Vengeance AP"] = AverageVengeanceAP.ToString("N1");
            dictValues["Crit Rating"]          = BasicStats.CritRating.ToString();
            dictValues["Hit Rating"]           = BasicStats.HitRating.ToString() + tipMiss;
            dictValues["Expertise Rating"]     = BasicStats.ExpertiseRating.ToString() + tipDodgeParry;
            dictValues["Haste Rating"]         = string.Format("{0}*{1}sec Attack Speed", BasicStats.HasteRating, AttackSpeed.ToString("0.000"));
            //dictValues["Armor Penetration Rating"] = BasicStats.ArmorPenetrationRating.ToString();

            dictValues["Avoided Attacks"] = String.Format("{0}*{1} Missed\r\n{2} Dodged\r\n{3} Parried",
                                                          AvoidedAttacks.ToString("0.000%"), MissedAttacks.ToString("0.000%"),
                                                          DodgedAttacks.ToString("0.000%"), ParriedAttacks.ToString("0.000%"));

            dictValues["Highest DPS Rotation"] = HighestDPSRotation.Name;
            dictValues["Highest TPS Rotation"] = HighestTPSRotation.Name;
            dictValues["Swipe Rotation"]       = "";
            dictValues["Custom Rotation"]      = "";
            //string rotationFormat = "{0} DPS, {1} TPS*{2}";
            //dictValues["Highest DPS Rotation"] = String.Format(rotationFormat, Math.Round(HighestDPSRotation.DPS), Math.Round(HighestDPSRotation.TPS), GetRotationTooltip(HighestDPSRotation.Name));
            //dictValues["Highest TPS Rotation"] = String.Format(rotationFormat, Math.Round(HighestTPSRotation.DPS), Math.Round(HighestTPSRotation.TPS), GetRotationTooltip(HighestTPSRotation.Name));
            //dictValues["Swipe Rotation"] = String.Format(rotationFormat, Math.Round(SwipeRotation.DPS), Math.Round(SwipeRotation.TPS), GetRotationTooltip(SwipeRotation.Name));
            //dictValues["Custom Rotation"] = String.Format(rotationFormat, Math.Round(CustomRotation.DPS), Math.Round(CustomRotation.TPS), GetRotationTooltip(CustomRotation.Name));

            dictValues["Melee"]       = Abilities.MeleeStats.ToString();
            dictValues["Maul"]        = Abilities.MaulStats.ToString();
            dictValues["Mangle"]      = Abilities.MangleStats.ToString();
            dictValues["Lacerate"]    = Abilities.LacerateStats.ToString();
            dictValues["Pulverize"]   = Abilities.PulverizeStats.ToString();
            dictValues["Swipe"]       = Abilities.SwipeStats.ToString();
            dictValues["Thrash"]      = Abilities.ThrashStats.ToString();
            dictValues["Faerie Fire"] = Abilities.FaerieFireStats.ToString();
            dictValues["Thorns"]      = Abilities.ThornsStats.ToString();
            //string attackFormat = "{0} Dmg, {1} Threat*Per Hit: {0} Damage, {1} Threat\r\nPer Average Swing: {2} Damage, {3} Threat";
            //string attackFormatWithRage = attackFormat + "\r\nThreat Per Rage: {4}\r\nDamage Per Rage: {5}";
            //dictValues["Melee"] = String.Format(attackFormat, MeleeDamageRaw, MeleeThreatRaw, MeleeDamageAverage, MeleeThreatAverage);
            //dictValues["Maul"] = String.Format(attackFormatWithRage, MaulDamageRaw, MaulThreatRaw, MaulDamageAverage, MaulThreatAverage, MaulTPR, MaulDPR);
            //dictValues["Mangle"] = String.Format(attackFormatWithRage, MangleDamageRaw, MangleThreatRaw, MangleDamageAverage, MangleThreatAverage, MangleTPR, MangleDPR);
            //dictValues["Swipe"] = String.Format(attackFormatWithRage, SwipeDamageRaw, SwipeThreatRaw, SwipeDamageAverage, SwipeThreatAverage, SwipeTPR, SwipeDPR);
            //dictValues["Faerie Fire"] = String.Format(attackFormat, FaerieFireDamageRaw, FaerieFireThreatRaw, FaerieFireDamageAverage, FaerieFireThreatAverage);
            //dictValues["Lacerate"] = String.Format(attackFormatWithRage, LacerateDamageRaw, LacerateThreatRaw, LacerateDamageAverage, LacerateThreatAverage, LacerateTPR, LacerateDPR);
            //dictValues["Lacerate DoT Tick"] = String.Format(attackFormat, LacerateDotDamageRaw, LacerateDotThreatRaw, LacerateDotDamageAverage, LacerateDotThreatAverage).Replace("Swing", "Tick");

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

            dictValues.Add("DPS Points", DPS.ToString("F2", CultureInfo.InvariantCulture));
            dictValues.Add("Survivability Points", Survivability.ToString("F2", CultureInfo.InvariantCulture));
            dictValues.Add("Overall Points", OverallPoints.ToString("F2", CultureInfo.InvariantCulture));

            dictValues.Add("Health", BasicStats.Health.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Mana", BasicStats.Mana.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Strength", String.Format("{0}*Increases Attack Power by {1}",
                                                     BasicStats.Strength.ToString("F0", CultureInfo.InvariantCulture),
                                                     (BasicStats.Strength - 10f).ToString("F0", CultureInfo.InvariantCulture)));
            dictValues.Add("Agility", String.Format("{0}*Increases Attack Power by {1}\r\nIncreases Critical Hit chance by {2}%",
                                                    BasicStats.Agility.ToString("F0", CultureInfo.InvariantCulture),
                                                    ((BasicStats.Agility * 2f) - 20f).ToString("F0", CultureInfo.InvariantCulture),
                                                    (StatConversion.GetCritFromAgility(BasicStats.Agility, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Stamina", String.Format("{0}*Increase Health by {1}",
                                                    BasicStats.Stamina.ToString("F0", CultureInfo.InvariantCulture),
                                                    (StatConversion.GetHealthFromStamina(BasicStats.Stamina)).ToString("F0", CultureInfo.InvariantCulture)));
            dictValues.Add("Intellect", String.Format("{0}*Increases Mana by {1}\r\nIncreases Spell Power by {2}\r\nIncreases Spell Critical Hit chance by {3}%",
                                                      BasicStats.Intellect.ToString("F0", CultureInfo.InvariantCulture),
                                                      (StatConversion.GetManaFromIntellect(BasicStats.Intellect)).ToString("F0", CultureInfo.InvariantCulture),
                                                      (BasicStats.Intellect - 10f).ToString("F0", CultureInfo.InvariantCulture),
                                                      (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Spirit", String.Format("{0}*Increases mana regeneration by {1} every 5 seconds while not casting",
                                                   BasicStats.Spirit.ToString("F0", CultureInfo.InvariantCulture),
                                                   (StatConversion.GetSpiritRegenSec(BasicStats.Spirit, BasicStats.Intellect) * 5f).ToString("F0", CultureInfo.InvariantCulture)));
            dictValues.Add("Mastery", String.Format("{0}*Mastery rating of {1} adds {2} Mastery\r\nIncreases all Fire, Frost, and Nature Damage by {3}%.",
                                                    (8f + StatConversion.GetMasteryFromRating(BasicStats.MasteryRating)).ToString("F2", CultureInfo.InvariantCulture),
                                                    BasicStats.MasteryRating.ToString("F0", CultureInfo.InvariantCulture),
                                                    (StatConversion.GetMasteryFromRating(BasicStats.MasteryRating)).ToString("F2", CultureInfo.InvariantCulture),
                                                    ((8f + StatConversion.GetMasteryFromRating(BasicStats.MasteryRating)) * 2.5f).ToString("F2", CultureInfo.InvariantCulture)));

            //dictValues.Add("Damage"
            //dictValues.Add("DPS"
            dictValues.Add("Attack Power", BasicStats.AttackPower.ToString("F0", CultureInfo.InvariantCulture));
            //dictValues.Add("Speed"
            dictValues.Add("Melee Haste", String.Format("{0}%*Haste Rating of {1} adds {2}% Haste",
                                                        (StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                        BasicStats.HasteRating.ToString("F0", CultureInfo.InvariantCulture),
                                                        (StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Melee Hit", String.Format("{0}%*Hit Rating of {1} adds {2}% Hit chance\r\n{3}% Draenei Hit Bonus",
                                                      (StatConversion.GetHitFromRating(BasicStats.HitRating) * 100f + DraeneiHitBonus * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                      BasicStats.HitRating.ToString("F0", CultureInfo.InvariantCulture),
                                                      (StatConversion.GetHitFromRating(BasicStats.HitRating) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                      DraeneiHitBonus * 100f));
            dictValues.Add("Melee Crit", String.Format("{0}%*Crit Rating of {1} adds {2}% Crit chance",
                                                       ((StatConversion.GetCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f) + (StatConversion.GetCritFromAgility(BasicStats.Agility, CharacterClass.Shaman) * 100f)).ToString("F2", CultureInfo.InvariantCulture),
                                                       BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
                                                       (StatConversion.GetCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Expertise", getExpertiseString());// String.Format("{0} / {1}*Reduces chance to be dodged or parried by {2}% / {3}%\r\nExpertise Rating of {4} adds {5} Expertise",

            dictValues.Add("Spell Power", BasicStats.SpellPower.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Spell Haste", String.Format("{0}%*Haste Rating of {1} adds {2}% Haste",
                                                        (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                        BasicStats.HasteRating.ToString("F0", CultureInfo.InvariantCulture),
                                                        (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Spell Hit", String.Format("{0}%*Hit Rating of {1} adds {2}% Hit chance\r\n{3}% Draenei Hit Bonus",
                                                      (StatConversion.GetSpellHitFromRating(BasicStats.HitRating + ElemPrecMod) * 100f + DraeneiHitBonus * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                      (BasicStats.HitRating + ElemPrecMod).ToString("F0", CultureInfo.InvariantCulture),
                                                      (StatConversion.GetSpellHitFromRating(BasicStats.HitRating + ElemPrecMod) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                      DraeneiHitBonus * 100f));
            dictValues.Add("Spell Crit", String.Format("{0}%*Crit Rating of {1} adds {2}% Crit chance",
                                                       ((StatConversion.GetSpellCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f) + (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect, CharacterClass.Shaman) * 100f)).ToString("F2", CultureInfo.InvariantCulture),
                                                       BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
                                                       (StatConversion.GetSpellCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Combat Regen", String.Format("{0}*{0} mana regenerated every 5 seconds while in combat",
                                                         BaseRegen.ToString("F0", CultureInfo.InvariantCulture)));

            //dictValues.Add("Avg Agility", _attackPower.ToString("F0", CultureInfo.InvariantCulture));
            //dictValues.Add("Avg Intellect"
            //dictValues.Add("Avg Mastery"
            //dictValues.Add("Avg Attack Power"
            dictValues.Add("Avg Speed", String.Format("{0} / {1}", AvMHSpeed.ToString("F2", CultureInfo.InvariantCulture), AvOHSpeed.ToString("F2", CultureInfo.InvariantCulture)));
            //dictValues.Add("Avg Melee Haste"
            //dictValues.Add("Avg Melee Hit"
            //dictValues.Add("Avg Melee Crit"
            //dictValues.Add("Avg Expertise"
            //dictValues.Add("Avg Spell Power"
            //dictValues.Add("Avg Spell Haste"
            //dictValues.Add("Avg Spell Hit"
            //dictValues.Add("Avg Spell Crit"
            dictValues.Add("Avg Combat Regen", ManaRegen.ToString("F0", CultureInfo.InvariantCulture));

            /*dictValues.Add("White Hit", WhiteHit.ToString("F2", CultureInfo.InvariantCulture) + "%");
             * if (YellowHit < 100f && TotalExpertiseMH < 26)
             * {
             *  float ratingRequired = (float)Math.Ceiling(4f * StatConversion.GetRatingFromExpertise(100f - YellowHit));
             *  dictValues.Add("Yellow Hit", String.Format("{0}% (Under Cap)*You need {1} more expertise to cap specials (WF,SS)",
             *      YellowHit.ToString("F2", CultureInfo.InvariantCulture),
             *      ratingRequired.ToString("F0", CultureInfo.InvariantCulture)));
             * }
             * else
             * {
             *  if (ParriedAttacks > 0)
             *  {
             *      float ratingRequired = (float)Math.Ceiling(4f * StatConversion.GetRatingFromExpertise(100f - YellowHit));
             *      dictValues.Add("Yellow Hit", String.Format("{0}%*Being in front of boss allows your attacks to be parried\r\nYou would need {1} more expertise to cap specials (WF,SS)",
             *         YellowHit.ToString("F2", CultureInfo.InvariantCulture),
             *         ratingRequired.ToString("F0", CultureInfo.InvariantCulture)));
             *  }
             *  else
             *      dictValues.Add("Yellow Hit", YellowHit.ToString("F2", CultureInfo.InvariantCulture) + "%");
             * }
             * if (OverSpellHitCap > 0.38f) // only warn if more than .38% over cap (equivalent to 10 hit rating)
             *  dictValues.Add("Spell Hit", String.Format("{0}% (Over Cap)*Over Spell Hit Cap by {1}%",
             *      SpellHit.ToString("F2", CultureInfo.InvariantCulture),
             *      OverSpellHitCap.ToString("F2", CultureInfo.InvariantCulture)));
             * else
             * {
             *  if (SpellHit < 100f)
             *  {
             *      float ratingRequired = (float)Math.Ceiling(StatConversion.GetRatingFromSpellHit(1f - SpellHit/100f));
             *      dictValues.Add("Spell Hit", String.Format("{0}% (Under Cap)*You need {1} more hit rating to cap spells (ES, LB etc)",
             *          SpellHit.ToString("F2", CultureInfo.InvariantCulture),
             *          ratingRequired.ToString("F0", CultureInfo.InvariantCulture)));
             *  }
             *  else
             *      dictValues.Add("Spell Hit", SpellHit.ToString("F2", CultureInfo.InvariantCulture) + "%");
             * }*/
            /*if (OverMeleeCritCap > 0.21f) // only warn if more than .21% over cap (equivalent to 10 crit rating)
             *  dictValues.Add("Melee Crit", String.Format("{0} (Over Cap)*Crit Rating {1} (+{2}% crit chance)\r\nOver Soft Cap by {3}%",
             *      MeleeCrit.ToString("F2", CultureInfo.InvariantCulture) + "%",
             *      BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
             *      (StatConversion.GetCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture),
             *      OverMeleeCritCap.ToString("F2", CultureInfo.InvariantCulture)));
             * else
             *  dictValues.Add("Melee Crit", String.Format("{0}*Crit Rating {1} (+{2}% crit chance)",
             *      MeleeCrit.ToString("F2", CultureInfo.InvariantCulture) + "%",
             *      BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
             *      (StatConversion.GetCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
             *
             * dictValues.Add("Spell Crit", String.Format("{0}*Crit Rating {1} (+{2}% crit chance)",
             *  SpellCrit.ToString("F2", CultureInfo.InvariantCulture) + "%",
             *  BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
             *  (StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture)));*/

            float spellMiss = 100 - SpellHit;

            dictValues.Add("Avoided Attacks", String.Format("{0}%*{1}% Boss Dodged\r\n{2}% Boss Parried\r\n{3}% Spell Misses\r\n{4}% White Misses",
                                                            AvoidedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                                            DodgedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                                            ParriedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                                            spellMiss.ToString("F2", CultureInfo.InvariantCulture),
                                                            MissedAttacks.ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Armor Mitigation", ArmorMitigation.ToString("F2", CultureInfo.InvariantCulture) + "%*Amount of physical damage lost due to boss armor");

            dictValues.Add("ED Uptime", String.Format("{0}%*{1}% ED Bonus Crit",
                                                      EDUptime.ToString("F2", CultureInfo.InvariantCulture),
                                                      EDBonusCrit.ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Flurry Uptime", FlurryUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Avg Time to 5 Stack", String.Format("{0} sec*{1} PPM",
                                                                SecondsTo5Stack.ToString("F2", CultureInfo.InvariantCulture),
                                                                _MWPPM.ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("MH Enchant Uptime", MHEnchantUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("OH Enchant Uptime", OHEnchantUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Trinket 1 Uptime", Trinket1Uptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Trinket 2 Uptime", Trinket2Uptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Fire Totem Uptime", FireTotemUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");

            dictValues.Add("White Damage", dpsOutputFormat(SwingDamage, DPS, true));
            dictValues.Add("Windfury Attack", dpsOutputFormat(WindfuryAttack, DPS, true));
            dictValues.Add("Flametongue Attack", dpsOutputFormat(FlameTongueAttack, DPS, true));
            dictValues.Add("Stormstrike", dpsOutputFormat(Stormstrike, DPS, true));
            dictValues.Add("Lava Lash", dpsOutputFormat(LavaLash, DPS, true));
            dictValues.Add("Searing/Magma Totem", dpsOutputFormat(SearingMagma, DPS, false));
            dictValues.Add("Earth Shock", dpsOutputFormat(EarthShock, DPS, false));
            dictValues.Add("Flame Shock", dpsOutputFormat(FlameShock, DPS, false));
            dictValues.Add("Lightning Bolt", dpsOutputFormat(LightningBolt, DPS, false));
            dictValues.Add("Unleash Wind", dpsOutputFormat(UnleashWind, DPS, true));
            dictValues.Add("Unleash Flame", dpsOutputFormat(UnleashFlame, DPS, false));
            dictValues.Add("Lightning Shield", dpsOutputFormat(LightningShield, DPS, false));
            dictValues.Add("Chain Lightning", dpsOutputFormat(ChainLightning, DPS, false));
            dictValues.Add("Fire Nova", dpsOutputFormat(FireNova, DPS, false));
            dictValues.Add("Fire Elemental", FireElemental.getDPSOutput());
            dictValues.Add("Spirit Wolf", dpsOutputFormat(SpiritWolf, DPS, true));
            dictValues.Add("Other", dpsOutputFormat(Other, DPS, false));
            dictValues.Add("Total DPS", DPS.ToString("F2", CultureInfo.InvariantCulture));

            /*dictValues.Add("Status", String.Format("Enhance Model : DPS Points {0}, Survivability Points {1}, Overall Points {2}",
             *  DPS.ToString("F2", CultureInfo.InvariantCulture),
             *  Survivability.ToString("F2", CultureInfo.InvariantCulture),
             *  OverallPoints.ToString("F2", CultureInfo.InvariantCulture)));*/

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

            dictValues.Add("Health", BasicStats.Health.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Mana", BasicStats.Mana.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Attack Power", BasicStats.AttackPower.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Agility", BasicStats.Agility.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Strength", BasicStats.Strength.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Intellect", BasicStats.Intellect.ToString("F0", CultureInfo.InvariantCulture));

            dictValues.Add("White Hit", WhiteHit.ToString("F2", CultureInfo.InvariantCulture) + "%");
            if (YellowHit < 100f && TotalExpertiseMH < 26)
            {
                float ratingRequired = (float)Math.Ceiling(4f * StatConversion.GetRatingFromExpertise(100f - YellowHit));
                dictValues.Add("Yellow Hit", String.Format("{0}% (Under Cap)*You need {1} more expertise to cap specials (WF,SS)",
                                                           YellowHit.ToString("F2", CultureInfo.InvariantCulture),
                                                           ratingRequired.ToString("F0", CultureInfo.InvariantCulture)));
            }
            else
            {
                if (ParriedAttacks > 0)
                {
                    float ratingRequired = (float)Math.Ceiling(4f * StatConversion.GetRatingFromExpertise(100f - YellowHit));
                    dictValues.Add("Yellow Hit", String.Format("{0}%*Being in front of boss allows your attacks to be parried\r\nYou would need {1} more expertise to cap specials (WF,SS)",
                                                               YellowHit.ToString("F2", CultureInfo.InvariantCulture),
                                                               ratingRequired.ToString("F0", CultureInfo.InvariantCulture)));
                }
                else
                {
                    dictValues.Add("Yellow Hit", YellowHit.ToString("F2", CultureInfo.InvariantCulture) + "%");
                }
            }
            if (OverSpellHitCap > 0.38f) // only warn if more than .38% over cap (equivalent to 10 hit rating)
            {
                dictValues.Add("Spell Hit", String.Format("{0}% (Over Cap)*Over Spell Hit Cap by {1}%",
                                                          SpellHit.ToString("F2", CultureInfo.InvariantCulture),
                                                          OverSpellHitCap.ToString("F2", CultureInfo.InvariantCulture)));
            }
            else
            {
                if (SpellHit < 100f)
                {
                    float ratingRequired = (float)Math.Ceiling(StatConversion.GetRatingFromHit(1f - SpellHit / 100f));
                    dictValues.Add("Spell Hit", String.Format("{0}% (Under Cap)*You need {1} more hit rating to cap spells (ES, LB etc)",
                                                              SpellHit.ToString("F2", CultureInfo.InvariantCulture),
                                                              ratingRequired.ToString("F0", CultureInfo.InvariantCulture)));
                }
                else
                {
                    dictValues.Add("Spell Hit", SpellHit.ToString("F2", CultureInfo.InvariantCulture) + "%");
                }
            }
            if (OverMeleeCritCap > 0.21f) // only warn if more than .21% over cap (equivalent to 10 crit rating)
            {
                dictValues.Add("Melee Crit", String.Format("{0} (Over Cap)*Crit Rating {1} (+{2}% crit chance)\r\nOver Soft Cap by {3}%",
                                                           MeleeCrit.ToString("F2", CultureInfo.InvariantCulture) + "%",
                                                           BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
                                                           (StatConversion.GetCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                           OverMeleeCritCap.ToString("F2", CultureInfo.InvariantCulture)));
            }
            else
            {
                dictValues.Add("Melee Crit", String.Format("{0}*Crit Rating {1} (+{2}% crit chance)",
                                                           MeleeCrit.ToString("F2", CultureInfo.InvariantCulture) + "%",
                                                           BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
                                                           (StatConversion.GetCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            }

            dictValues.Add("Spell Crit", String.Format("{0}*Crit Rating {1} (+{2}% crit chance)",
                                                       SpellCrit.ToString("F2", CultureInfo.InvariantCulture) + "%",
                                                       BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
                                                       (StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture)));

            dictValues.Add("Spellpower", BasicStats.SpellPower.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Total Expertise", getExpertiseString());
            dictValues.Add("Haste Rating", String.Format("{0}*{1}% Melee Haste\r\n{2}% Spell Haste",
                                                         BasicStats.HasteRating.ToString("F0", CultureInfo.InvariantCulture),
                                                         (StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                         (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Hit Rating", String.Format("{0}*{1}% Melee Hit\r\n{2}% Spell Hit",
                                                       BasicStats.HitRating.ToString("F0", CultureInfo.InvariantCulture),
                                                       (StatConversion.GetHitFromRating(BasicStats.HitRating) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                       (StatConversion.GetSpellHitFromRating(BasicStats.HitRating) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Armour Pen Rating", String.Format("{0}*{1}% Armour Penetration",
                                                              BasicStats.ArmorPenetrationRating.ToString("F0", CultureInfo.InvariantCulture),
                                                              (StatConversion.GetArmorPenetrationFromRating(BasicStats.ArmorPenetrationRating) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            float spellMiss = 100 - SpellHit;

            dictValues.Add("Avoided Attacks", String.Format("{0}%*{1}% Boss Dodged\r\n{2}% Boss Parried\r\n{3}% Spell Misses\r\n{4}% White Misses",
                                                            AvoidedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                                            DodgedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                                            ParriedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                                            spellMiss.ToString("F2", CultureInfo.InvariantCulture),
                                                            MissedAttacks.ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Avg MH Speed", AvMHSpeed.ToString("F2", CultureInfo.InvariantCulture));
            dictValues.Add("Avg OH Speed", AvOHSpeed.ToString("F2", CultureInfo.InvariantCulture));
            dictValues.Add("Armor Mitigation", ArmorMitigation.ToString("F2", CultureInfo.InvariantCulture) + "%*Amount of physical damage lost due to boss armor");

            dictValues.Add("ED Uptime", String.Format("{0}%*{1}% ED Bonus Crit",
                                                      EDUptime.ToString("F2", CultureInfo.InvariantCulture),
                                                      EDBonusCrit.ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Flurry Uptime", FlurryUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Avg Time to 5 Stack", String.Format("{0} sec*{1} PPM",
                                                                SecondsTo5Stack.ToString("F2", CultureInfo.InvariantCulture),
                                                                _MWPPM.ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("MH Enchant Uptime", MHEnchantUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("OH Enchant Uptime", OHEnchantUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Trinket 1 Uptime", Trinket1Uptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Trinket 2 Uptime", Trinket2Uptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Fire Totem Uptime", FireTotemUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Tier 10 2 pc Uptime", T10_2Uptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Tier 10 4 pc Uptime", T10_4Uptime.ToString("F2", CultureInfo.InvariantCulture) + "%");

            dictValues.Add("DPS Points", DPSPoints.ToString("F2", CultureInfo.InvariantCulture));
            dictValues.Add("Survivability Points", SurvivabilityPoints.ToString("F2", CultureInfo.InvariantCulture));
            dictValues.Add("Overall Points", OverallPoints.ToString("F2", CultureInfo.InvariantCulture));

            dictValues.Add("White Damage", dpsOutputFormat(SwingDamage, DPSPoints, true));
            dictValues.Add("Windfury Attack", dpsOutputFormat(WindfuryAttack, DPSPoints, true));
            dictValues.Add("Flametongue Attack", dpsOutputFormat(FlameTongueAttack, DPSPoints, false));
            dictValues.Add("Lightning Bolt", dpsOutputFormat(LightningBolt, DPSPoints, false));
            dictValues.Add("Earth Shock", dpsOutputFormat(EarthShock, DPSPoints, false));
            dictValues.Add("Flame Shock", dpsOutputFormat(FlameShock, DPSPoints, false));
            dictValues.Add("Searing/Magma Totem", dpsOutputFormat(SearingMagma, DPSPoints, false));
            dictValues.Add("Stormstrike", dpsOutputFormat(Stormstrike, DPSPoints, true));
            dictValues.Add("Spirit Wolf", dpsOutputFormat(SpiritWolf, DPSPoints, true));
            dictValues.Add("Fire Nova", dpsOutputFormat(FireNova, DPSPoints, false));
            dictValues.Add("Fire Elemental", FireElemental.getDPSOutput());
            dictValues.Add("Lightning Shield", dpsOutputFormat(LightningShield, DPSPoints, false));
            dictValues.Add("Lava Lash", dpsOutputFormat(LavaLash, DPSPoints, true));
            dictValues.Add("Total DPS", DPSPoints.ToString("F2", CultureInfo.InvariantCulture));

            dictValues.Add("Enhance Version", _version);

            dictValues.Add("Status", String.Format("Enhance Model : DPS Points {0}, Survivability Points {1}, Overall Points {2}",
                                                   DPSPoints.ToString("F2", CultureInfo.InvariantCulture),
                                                   SurvivabilityPoints.ToString("F2", CultureInfo.InvariantCulture),
                                                   OverallPoints.ToString("F2", CultureInfo.InvariantCulture)));

            return(dictValues);
        }