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

            dictValues.Add("Health", BasicStats.Health.ToString());
            dictValues.Add("Strength", BasicStats.Strength.ToString());
            dictValues.Add("Agility", BasicStats.Agility.ToString());
            dictValues.Add("Stamina", BasicStats.Stamina.ToString());
            dictValues.Add("Armor", string.Format("{0}*Reduces physical damage taken by {1:0.00%}", BasicStats.Armor, ArmorReduction));
            dictValues.Add("Defense", Defense.ToString() + string.Format("*Defense Rating {0}", BasicStats.DefenseRating));
            dictValues.Add("Dodge", string.Format("{0:0.00%}*Dodge Rating {1}", Dodge, BasicStats.DodgeRating));
            dictValues.Add("Parry", string.Format("{0:0.00%}*Parry Rating {1}", Parry, BasicStats.ParryRating));
            dictValues.Add("Block", string.Format("{0:0.00%}*Block Rating {1}", Block, BasicStats.BlockRating));
            dictValues.Add("Miss", string.Format("{0:0.00%}", Miss));
            dictValues.Add("Block Value", string.Format("{0}", BlockValue));
            dictValues.Add("Guaranteed Reduction", string.Format("{0:0.00%}", GuaranteedReduction));
            dictValues.Add("Avoidance", string.Format("{0:0.00%} (+Block {1:0.00%})", DodgePlusMissPlusParry, DodgePlusMissPlusParryPlusBlock));
            dictValues.Add("Total Mitigation", string.Format("{0:0.00%}", TotalMitigation));

            if (AttackerSpeed == BaseAttackerSpeed)
            {
                dictValues.Add("Attacker Speed", string.Format("{0:0.00}s", AttackerSpeed));
            }
            else
            {
                dictValues.Add("Attacker Speed", string.Format("{0:0.00}s*Base speed of {1:0.00}s (modified by haste)", AttackerSpeed, BaseAttackerSpeed));
            }

            dictValues.Add("Damage Taken",
                           string.Format("{0:0.0} DPS*{1:0} damage per normal attack" + Environment.NewLine +
                                         "{2:0} damage per blocked attack" + Environment.NewLine +
                                         "{3:0} damage per critically blocked attack" + Environment.NewLine +
                                         "{4:0} damage per critical attack", DamageTaken, DamageTakenPerHit, DamageTakenPerBlock, DamageTakenPerCritBlock, DamageTakenPerCrit));

            dictValues.Add("Resilience",
                           string.Format(@"{0}*Reduces the damage of critical strikes and chance to be critically hit by {1}%.",
                                         BasicStats.Resilience,
                                         StatConversion.GetCritReductionFromResilience(BasicStats.Resilience, CharacterClass.Warrior)));

            if (CritVulnerability > 0.0001f)
            {
                float resilienceNeeded = (float)Math.Ceiling((StatConversion.RATING_PER_RESILIENCE * CritVulnerability));
                dictValues.Add("Chance to be Crit",
                               string.Format("{0:0.00%}*CRITTABLE! Short by {1:0} defense or {2:0} resilience to be uncrittable.",
                                             CritVulnerability, DefenseRatingNeeded, resilienceNeeded));
            }
            else
            {
                dictValues.Add("Chance to be Crit", string.Format("{0:0.00%}*Chance to crit reduced by {1:0.00%}", CritVulnerability, CritReduction));
            }

            dictValues.Add("Nature Resist", string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", BasicStats.NatureResistance, NatureReduction));
            dictValues.Add("Arcane Resist", string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", BasicStats.ArcaneResistance, ArcaneReduction));
            dictValues.Add("Frost Resist", string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", BasicStats.FrostResistance, FrostReduction));
            dictValues.Add("Fire Resist", string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", BasicStats.FireResistance, FireReduction));
            dictValues.Add("Shadow Resist", string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", BasicStats.ShadowResistance, ShadowReduction));
            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.Add("Weapon Speed", string.Format("{0:0.00}*{1:0.00%} Haste", WeaponSpeed, Haste));
            dictValues.Add("Attack Power", string.Format("{0}", BasicStats.AttackPower));
            dictValues.Add("Hit", string.Format("{0:0.00%}*Hit Rating {1}", Hit, BasicStats.HitRating));
            dictValues.Add("Expertise",
                           string.Format("{0}*Expertise Rating {1}" + Environment.NewLine + "Reduces chance to be dodged or parried by {2:0.00%}.",
                                         Math.Round(StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating, CharacterClass.Warrior) + BasicStats.Expertise),
                                         BasicStats.ExpertiseRating, Expertise));
            dictValues.Add("Haste", string.Format("{0:0.00%}*Haste Rating {1:0.00}", Haste, BasicStats.HasteRating));
            dictValues.Add("Armor Penetration",
                           string.Format("{0:0.00%}*Armor Penetration Rating {1}" + Environment.NewLine + "Armor Reduction {2}",
                                         ArmorPenetration, BasicStats.ArmorPenetrationRating, BasicStats.ArmorPenetration));
            dictValues.Add("Crit", string.Format("{0:0.00%}*Crit Rating {1}", Crit, BasicStats.CritRating));
            // Never really used in current WoW itemization, just taking up space
            // dictValues.Add("Weapon Damage", string.Format("{0}", BasicStats.WeaponDamage));
            dictValues.Add("Missed Attacks",
                           string.Format("{0:0.00%}*Attacks Missed: {1:0.00%}" + Environment.NewLine + "Attacks Dodged: {2:0.00%}" + Environment.NewLine +
                                         "Attacks Parried: {3:0.00%}", AvoidedAttacks, MissedAttacks, DodgedAttacks, ParriedAttacks));
            dictValues.Add("Total Damage/sec", string.Format("{0:0.0}", TotalDamagePerSecond));
            dictValues.Add("Total Threat/sec", string.Format("{0:0.0}*{1:0%} of Swings converted to Heroic Strikes", ThreatPerSecond, HeroicStrikeFrequency));
            dictValues.Add("Rotation", ThreatModelName + "*" + ThreatModel);

            switch (RankingMode)
            {
            case 2:
                dictValues.Add("Ranking Mode", "TankPoints*The average amount of unmitigated damage which can be taken before dying");
                dictValues.Add("Survival Points", string.Format("{0:0}*Effective Health", SurvivalPoints));
                break;

            case 3:
                dictValues.Add("Ranking Mode", "Burst Time*The average amount of time between events which have a chance to result in a burst death");
                dictValues.Add("Survival Points", string.Format("{0:0}*{1:0.00} seconds between events", SurvivalPoints, SurvivalPoints / 100.0f));
                break;

            case 4:
                dictValues.Add("Ranking Mode", "Damage Output*The average amount of DPS which can be produced");
                dictValues.Add("Survival Points", string.Format("{0:0}*Survival is not weighted in this mode", SurvivalPoints, SurvivalPoints / 100.0f));
                break;

            default:
                dictValues.Add("Ranking Mode", "Mitigation Scale*Customizable scale which allows you to weight mitigation vs. effective health.");
                dictValues.Add("Survival Points", string.Format("{0:0}*Effective Health", SurvivalPoints));
                break;
            }
            dictValues.Add("Overall Points", string.Format("{0:0}", OverallPoints));
            dictValues.Add("Mitigation Points", string.Format("{0:0}", MitigationPoints));
            dictValues.Add("Threat Points", string.Format("{0:0}", ThreatPoints));

            return(dictValues);
        }
Example #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);
        }
Example #3
0
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            dictValues.Add("Health", BasicStats.Health.ToString());
            dictValues.Add("Mana", BasicStats.Mana.ToString());
            dictValues.Add("Strength", BasicStats.Strength.ToString());
            dictValues.Add("Agility", BasicStats.Agility.ToString());
            dictValues.Add("Stamina", string.Format("{0}*Increases Health by {1}", BasicStats.Stamina, (BasicStats.Stamina - 20f) * 10f + 20f));
            dictValues.Add("Intellect", BasicStats.Intellect.ToString());
            dictValues.Add("Armor", string.Format("{0}*Reduces physical damage taken by {1:0.00%}" + Environment.NewLine +
                                                  "Armor Damage Reduction depends on Attacker Level.",
                                                  BasicStats.Armor, ArmorReduction));
            dictValues.Add("Dodge", string.Format("{0:0.0000%}*Dodge Rating {1}", Dodge, BasicStats.DodgeRating));
            dictValues.Add("Parry", string.Format("{0:0.0000%}*Parry Rating {1}", Parry, BasicStats.ParryRating));
            dictValues.Add("Block", string.Format("{0:0.0000%}*Block Rating {1}", Block, BasicStats.BlockRating));
            dictValues.Add("Mastery", string.Format("{0}*Mastery Rating {1}" + Environment.NewLine +
                                                    "Adds {2:0.0000%} Block", Mastery, BasicStats.MasteryRating, Mastery * 0.0225f));
            dictValues.Add("Miss", string.Format("{0:0.0000%}", Miss));
            dictValues.Add("Guaranteed Reduction", string.Format("{0:0.00%}", GuaranteedReduction));
            dictValues.Add("Avoidance", string.Format("{0:0.0000%}*Avoidance Points {1}", DodgePlusMissPlusParry, (DodgePlusMissPlusParry * 10000f)));
            dictValues.Add("Avoidance + Block", string.Format("{0:0.0000%}", DodgePlusMissPlusParryPlusBlock));
            dictValues.Add("Total Mitigation", string.Format("{0:0.00%}", TotalMitigation));

            dictValues.Add("Attacker Speed", string.Format("{0:0.00}s", AttackerSpeed));

            dictValues.Add("Damage Taken",
                           string.Format("{0:0.0} DPS*{1:0} damage per normal attack" + Environment.NewLine +
                                         "{2:0} damage per blocked attack" + Environment.NewLine +
                                         "{3:0} damage per critical attack" + Environment.NewLine +
                                         "On Average, you take" + Environment.NewLine +
                                         "{4:0.00%} of incoming damage", DPSTaken, DamageTakenPerHit, DamageTakenPerBlock, DamageTakenPerCrit, DamageTaken));

            dictValues.Add("Resilience",
                           string.Format(@"{0}" /* + "*Reduces periodic damage by {1:0.00%}." + Environment.NewLine +
                                                 * "Reduces the effect of mana-drains and the damage of critical strikes by {2:0.00%}."*/,
                                         BasicStats.Resilience //,
                                                               //StatConversion.GetCritReductionFromResilience(BasicStats.Resilience,CharacterClass.Paladin),
                                                               //StatConversion.GetCritReductionFromResilience(BasicStats.Resilience,CharacterClass.Paladin)*2f
                                         ));

            if (CritVulnerability > 0.0001f)
            {
                dictValues.Add("Chance to be Crit",
                               string.Format("{0:0.00%}*CRITTABLE! Spec 3 points into the protection talent Sanctuary to be uncrittable.",
                                             CritVulnerability));
            }
            else
            {
                dictValues.Add("Chance to be Crit", string.Format("{0:0.00%}*Chance to be crit reduced by {1:0.00%}", CritVulnerability, CritReduction));
            }

            dictValues.Add("Nature Resist", string.Format("{0:0}*{1:0.00%} Total Reduction", BasicStats.NatureResistance, NatureReduction));
            dictValues.Add("Arcane Resist", string.Format("{0:0}*{1:0.00%} Total Reduction", BasicStats.ArcaneResistance, ArcaneReduction));
            dictValues.Add("Frost Resist", string.Format("{0:0}*{1:0.00%} Total Reduction", BasicStats.FrostResistance, FrostReduction));
            dictValues.Add("Fire Resist", string.Format("{0:0}*{1:0.00%} Total Reduction", BasicStats.FireResistance, FireReduction));
            dictValues.Add("Shadow Resist", string.Format("{0:0}*{1:0.00%} Total Reduction", BasicStats.ShadowResistance, ShadowReduction));
            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.Add("Weapon Speed", string.Format("{0:0.00}*{1:0.00%} Haste", WeaponSpeed, PhysicalHaste));
            dictValues.Add("Attack Power", string.Format("{0}", BasicStats.AttackPower));
            dictValues.Add("Spell Power", string.Format("{0}", BasicStats.SpellPower));
            dictValues.Add("Hit", string.Format("{0:0.00%}*Hit Rating {1}" + Environment.NewLine + "Against a Target of Level {2}", Hit, BasicStats.HitRating, TargetLevel));
            dictValues.Add("Spell Hit", string.Format("{0:0.00%}*Hit Rating {1}" + Environment.NewLine + "Against a Target of Level {2}",
                                                      SpellHit, BasicStats.HitRating, TargetLevel));
            dictValues.Add("Expertise",
                           string.Format("{0:0.00}*Expertise Rating {1}" + Environment.NewLine + "Reduces chance to be dodged or parried by {2:0.00%}.",
                                         StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating, CharacterClass.Paladin) + BasicStats.Expertise,
                                         BasicStats.ExpertiseRating, Expertise));
            dictValues.Add("Physical Haste", string.Format("{0:0.00%}*Haste Rating {1:0.00}", PhysicalHaste, BasicStats.HasteRating));
            dictValues.Add("Effective Target Armor",
                           string.Format("{0}*Reduces the physical damage you deal by {1:0.00%}" + Environment.NewLine + Environment.NewLine +
                                         "Effective Armor depends on Armor ignore debuffs," + Environment.NewLine +
                                         "your Armor Penetration buffs and talents." + Environment.NewLine +
                                         "Enemy Damage Reduction depends on your Level.",
                                         (float)Math.Floor(EffectiveTargetArmor), EffectiveTargetArmorDamageReduction));

            dictValues.Add("Crit", string.Format("{0:0.00%}*Crit Rating {1}" + Environment.NewLine + "Against a Target of Level {2}",
                                                 Crit, BasicStats.CritRating, TargetLevel));
            dictValues.Add("Spell Crit", string.Format("{0:0.00%}*Crit Rating {1}" + Environment.NewLine + "Against a Target of Level {2}",
                                                       SpellCrit, BasicStats.CritRating, TargetLevel));
            dictValues.Add("Weapon Damage", string.Format("{0:0.00}*As average damage per {1}" + Environment.NewLine + "Before Armor",
                                                          BasicStats.WeaponDamage, Lookup.Name(Ability.MeleeSwing)));
            dictValues.Add("Missed Attacks",
                           string.Format("{0:0.00%}*Attacks Missed: {1:0.00%}" + Environment.NewLine + "Attacks Dodged: {2:0.00%}" + Environment.NewLine +
                                         "Attacks Parried: {3:0.00%}", AvoidedAttacks, MissedAttacks, DodgedAttacks, ParriedAttacks));
            dictValues.Add("Glancing Attacks", string.Format("{0:0.00%}*{1:0.00%} Reduction" + Environment.NewLine +
                                                             "Against a Target of Level {2}", GlancingAttacks, 1.0f - GlancingReduction, TargetLevel));
            dictValues.Add("Total Damage/sec", string.Format("{0:0.0}", TotalDamagePerSecond) + "*" + ThreatModel);
            dictValues.Add("Threat/sec", string.Format("{0:0.0}", ThreatPerSecond) + "*" + ThreatModel);
            //dictValues.Add("Unlimited Threat/sec", string.Format("{0:0.0}", UnlimitedThreat) + "*" + ThreatModel);

            switch (RankingMode)
            {
            case 1:
                dictValues.Add("Ranking Mode", "Burst Time*The average amount of time between events which have a chance to result in a burst death");
                dictValues.Add("Survival Points", string.Format("{0:0}*{1:0.00} seconds between events", SurvivabilityPoints, SurvivabilityPoints / 100.0f));
                break;

            case 2:
                dictValues.Add("Ranking Mode", "Damage Output*The average amount of DPS which can be produced");
                dictValues.Add("Survival Points", string.Format("{0:0}*Survival is not weighted in this mode", SurvivabilityPoints, SurvivabilityPoints / 100.0f));
                break;

            case 0:
            default:
                dictValues.Add("Ranking Mode", "Mitigation Scale*Customizable scale which allows you to weight mitigation vs. effective health.");
                dictValues.Add("Survival Points", string.Format("{0:0}*Effective Health", SurvivabilityPoints));
                break;
            }
            dictValues.Add("Overall Points", string.Format("{0:0}", OverallPoints));
            dictValues.Add("Mitigation Points", string.Format("{0:0}", MitigationPoints));
            dictValues.Add("Threat Points", string.Format("{0:0}", ThreatPoints));
            dictValues.Add("CTC Points", string.Format("{0:0}", CTCPoints));

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

            dictValues.Add("Health", BasicStats.Health.ToString());
            dictValues.Add("Strength", BasicStats.Strength.ToString());
            dictValues.Add("Agility", BasicStats.Agility.ToString());
            dictValues.Add("Stamina", BasicStats.Stamina.ToString());
            dictValues.Add("Armor", string.Format("{0}*Reduces physical damage taken by {1:0.00%}", BasicStats.Armor, ArmorReduction));
            dictValues.Add("Dodge", string.Format("{0:0.00%}*Dodge Rating {1}", Dodge, BasicStats.DodgeRating));
            dictValues.Add("Parry", string.Format("{0:0.00%}*Parry Rating {1}", Parry, BasicStats.ParryRating));
            dictValues.Add("Miss", string.Format("{0:0.00%}", Miss));

            if (Block != BuffedBlock)
            {
                dictValues.Add("Block", string.Format("{0:0.00%}*Mastery Rating {1}" + Environment.NewLine +
                                                      "{2:0.00%} Normal Block Chance" + Environment.NewLine +
                                                      "{3:0.00%} Block Chance w/ Shield Block", Block, BasicStats.MasteryRating, BaseBlock, BuffedBlock));
            }
            else
            {
                dictValues.Add("Block", string.Format("{0:0.00%}*Mastery Rating {1}", Block, BasicStats.MasteryRating));
            }

            if (Block > 0)
            {
                dictValues.Add("Critical Block", string.Format("{0:0.00%} ({1:0.00%} actual)*Mastery Rating {2}", CriticalBlock / Block, CriticalBlock, BasicStats.MasteryRating));
            }
            else
            {
                dictValues.Add("Critical Block", string.Format("{0:0.00%}*Mastery Rating {1}", 0, BasicStats.MasteryRating));
            }

            dictValues.Add("Guaranteed Reduction", string.Format("{0:0.00%}", GuaranteedReduction));

            if (AnyAvoid != BaseAnyAvoid)
            {
                dictValues.Add("Avoidance", string.Format("{0:0.00%}*Avoidance: {0:0.00%}" + Environment.NewLine +
                                                          "+ Normal Block Chance: {1:0.00%}" + Environment.NewLine +
                                                          "+ Average Block Chance: {2:0.00%}" + Environment.NewLine +
                                                          "+ Block Chance w/ Shield Block: {3:0.00%}", AnyMiss, BaseAnyAvoid, AnyAvoid, BuffedAnyAvoid));
            }
            else
            {
                dictValues.Add("Avoidance", string.Format("{0:0.00%}*Avoidance: {0:0.00%}" + Environment.NewLine +
                                                          "Avoidance + Block: {1:0.00%}", AnyMiss, BaseAnyAvoid));
            }

            dictValues.Add("Total Mitigation", string.Format("{0:0.00%}", TotalMitigation));

            if (AttackerSpeed == BaseAttackerSpeed)
            {
                dictValues.Add("Attacker Speed", string.Format("{0:0.00}s", AttackerSpeed));
            }
            else
            {
                dictValues.Add("Attacker Speed", string.Format("{0:0.00}s*Base speed of {1:0.00}s (modified by haste)", AttackerSpeed, BaseAttackerSpeed));
            }

            dictValues.Add("Damage Taken",
                           string.Format("{0:0.0} DPS*{1:0} damage per normal attack" + Environment.NewLine +
                                         "{2:0} damage per blocked attack" + Environment.NewLine +
                                         "{3:0} damage per critically blocked attack" + Environment.NewLine +
                                         "{4:0} damage per critical attack", DamageTaken, DamageTakenPerHit, DamageTakenPerBlock, DamageTakenPerCritBlock, DamageTakenPerCrit));

            if (CritVulnerability > 0.0001f)
            {
                dictValues.Add("Chance to be Crit", string.Format("{0:0.00%}*CRITTABLE!", CritVulnerability));
            }
            else
            {
                dictValues.Add("Chance to be Crit", string.Format("{0:0.00%}*Chance to crit reduced by {1:0.00%}", CritVulnerability, CritReduction));
            }

            dictValues.Add("Nature Resist", string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", BasicStats.NatureResistance, NatureReduction));
            dictValues.Add("Arcane Resist", string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", BasicStats.ArcaneResistance, ArcaneReduction));
            dictValues.Add("Frost Resist", string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", BasicStats.FrostResistance, FrostReduction));
            dictValues.Add("Fire Resist", string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", BasicStats.FireResistance, FireReduction));
            dictValues.Add("Shadow Resist", string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", BasicStats.ShadowResistance, ShadowReduction));
            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.Add("Weapon Speed", string.Format("{0:0.00}*{1:0.00%} Haste", WeaponSpeed, Haste));
            dictValues.Add("Attack Power", string.Format("{0}", BasicStats.AttackPower));
            dictValues.Add("Hit", string.Format("{0:0.00%}*Hit Rating {1}", Hit, BasicStats.HitRating));
            dictValues.Add("Expertise",
                           string.Format("{0}*Expertise Rating {1}" + Environment.NewLine + "Reduces chance to be dodged or parried by {2:0.00%}.",
                                         Math.Round(StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating, CharacterClass.Warrior) + BasicStats.Expertise),
                                         BasicStats.ExpertiseRating, Expertise));
            dictValues.Add("Haste", string.Format("{0:0.00%}*Haste Rating {1:0.00}", Haste, BasicStats.HasteRating));
            dictValues.Add("Armor Penetration",
                           string.Format("{0:0.00%}*" + /*"Armor Penetration Rating {1}" + Environment.NewLine +*/ "Armor Reduction {1}",
                                         ArmorPenetration, /*BasicStats.ArmorPenetrationRating,*/ BasicStats.ArmorPenetration));
            dictValues.Add("Crit", string.Format("{0:0.00%}*Crit Rating {1}", Crit, BasicStats.CritRating));
            dictValues.Add("Missed Attacks",
                           string.Format("{0:0.00%}*Attacks Missed: {1:0.00%}" + Environment.NewLine + "Attacks Dodged: {2:0.00%}" + Environment.NewLine +
                                         "Attacks Parried: {3:0.00%}", AvoidedAttacks, MissedAttacks, DodgedAttacks, ParriedAttacks));
            dictValues.Add("Total Damage/sec", string.Format("{0:0.0}", TotalDamagePerSecond));
            dictValues.Add("Total Threat/sec", string.Format("{0:0.0}*Heroic Strike used every {1:0.0} seconds", ThreatPerSecond, 3.0f / HeroicStrikeFrequency));
            dictValues.Add("Rotation", ThreatModelName + "*" + ThreatModel);

            switch (RankingMode)
            {
            case 3:
                dictValues.Add("Ranking Mode", "Burst Time*The average amount of time between events which have a chance to result in a burst death");
                dictValues.Add("Survival Points", string.Format("{0:0}*{1:0.00} seconds between events", SurvivalPoints, SurvivalPoints / 100.0f));
                break;

            case 4:
                dictValues.Add("Ranking Mode", "Damage Output*The average amount of DPS which can be produced");
                dictValues.Add("Survival Points", string.Format("{0:0}*Survival is not weighted in this mode", SurvivalPoints, SurvivalPoints / 100.0f));
                break;

            default:
                dictValues.Add("Ranking Mode", "Mitigation Scale*Default scale which compares mitigation, effective health, and threat.");
                dictValues.Add("Survival Points", string.Format("{0:0}*Effective Health", SurvivalPoints));
                break;
            }
            dictValues.Add("Overall Points", string.Format("{0:0}", OverallPoints));
            dictValues.Add("Mitigation Points", string.Format("{0:0}", MitigationPoints));
            dictValues.Add("Threat Points", string.Format("{0:0}", ThreatPoints));

            return(dictValues);
        }
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();
            int   armorCap             = (int)Math.Ceiling((1402.5f * TargetLevel) - 66502.5f);
            float levelDifference      = 0.2f * (TargetLevel - 70);
            float targetCritReduction  = 5f + levelDifference;
            float currentCritReduction = ((float)Math.Floor(
                                              (BasicStats.DefenseRating * WarriorConversions.DefenseRatingToDefense + BasicStats.Defense)) *
                                          WarriorConversions.DefenseToCritReduction) +
                                         (BasicStats.Resilience * WarriorConversions.ResilienceRatingToCritReduction);
            int defToCap = 0, resToCap = 0;

            if (currentCritReduction < targetCritReduction)
            {
                while ((((float)Math.Floor(
                             ((BasicStats.DefenseRating + defToCap) * WarriorConversions.DefenseRatingToDefense + BasicStats.Defense)) *
                         WarriorConversions.DefenseToCritReduction) +
                        (BasicStats.Resilience * WarriorConversions.ResilienceRatingToCritReduction)) < targetCritReduction)
                {
                    defToCap++;
                }
                while ((((float)Math.Floor(
                             (BasicStats.DefenseRating * WarriorConversions.DefenseRatingToDefense + BasicStats.Defense)) *
                         WarriorConversions.DefenseToCritReduction) +
                        ((BasicStats.Resilience + resToCap) * WarriorConversions.ResilienceRatingToCritReduction)) < targetCritReduction)
                {
                    resToCap++;
                }
            }
            else if (currentCritReduction > targetCritReduction)
            {
                while ((((float)Math.Floor(
                             ((BasicStats.DefenseRating + defToCap) * WarriorConversions.DefenseRatingToDefense + BasicStats.Defense)) *
                         WarriorConversions.DefenseToCritReduction) +
                        (BasicStats.Resilience * WarriorConversions.ResilienceRatingToCritReduction)) > targetCritReduction)
                {
                    defToCap--;
                }
                while ((((float)Math.Floor(
                             (BasicStats.DefenseRating * WarriorConversions.DefenseRatingToDefense + BasicStats.Defense)) *
                         WarriorConversions.DefenseToCritReduction) +
                        ((BasicStats.Resilience + resToCap) * WarriorConversions.ResilienceRatingToCritReduction)) > targetCritReduction)
                {
                    resToCap--;
                }
                defToCap++;
                resToCap++;
            }

            dictValues.Add("Health", BasicStats.Health.ToString());
            dictValues.Add("Strength", BasicStats.Strength.ToString());
            dictValues.Add("Agility", BasicStats.Agility.ToString());
            dictValues.Add("Stamina", BasicStats.Stamina.ToString());
            dictValues.Add("Armor", BasicStats.Armor.ToString());
            dictValues.Add("Defense", Defense.ToString() +
                           string.Format("*Defense Rating {0}", BasicStats.DefenseRating));
            dictValues.Add("Dodge", Dodge.ToString() +
                           string.Format("%*Dodge Rating {0}", BasicStats.DodgeRating));
            dictValues.Add("Parry", Parry.ToString() +
                           string.Format("%*Parry Rating {0}", BasicStats.ParryRating));
            if (BlockOverCap > 0f)
            {
                dictValues.Add("Block", (Block + BlockOverCap).ToString()
                               + string.Format("%*Block Rating {0}. Over the crush cap by {1}% block", BasicStats.BlockRating, BlockOverCap));
            }
            else
            {
                dictValues.Add("Block", Block.ToString()
                               + string.Format("%*Block Rating {0}", BasicStats.BlockRating));
            }
            dictValues.Add("Miss", Miss.ToString() + "%");
            dictValues.Add("Resilience", BasicStats.Resilience.ToString() +
                           string.Format(@"*Reduces periodic damage and chance to be critically hit by {0}%.
Reduces the effect of mana-drains and the damage of critical strikes by {1}%.",
                                         BasicStats.Resilience * WarriorConversions.ResilienceRatingToCritReduction,
                                         BasicStats.Resilience * WarriorConversions.ResilienceRatingToCritReduction * 2));
            dictValues.Add("Block Value", BlockValue.ToString());

            #region Offensive Stats
            dictValues["Attack Power"] = BasicStats.AttackPower.ToString();
            dictValues["Hit"]          = (BasicStats.HitRating * WarriorConversions.HitRatingToHit +
                                          BasicStats.Hit).ToString() +
                                         string.Format("%*Hit Rating {0}", BasicStats.HitRating);
            dictValues["Expertise"] = (Math.Round(BasicStats.ExpertiseRating * WarriorConversions.ExpertiseRatingToExpertise +
                                                  BasicStats.Expertise)).ToString() +
                                      string.Format(@"*Expertise Rating {0}
Reduces chance to be dodged or parried by {1}%.", BasicStats.ExpertiseRating,
                                                    Math.Round((BasicStats.ExpertiseRating * WarriorConversions.ExpertiseRatingToExpertise +
                                                                BasicStats.Expertise) * WarriorConversions.ExpertiseToDodgeParryReduction));
            dictValues["Haste"] = (BasicStats.HasteRating * WarriorConversions.HasteRatingToHaste).ToString() +
                                  string.Format("%*Haste Rating {0}", BasicStats.HasteRating);
            dictValues["Armor Penetration"] = BasicStats.ArmorPenetration.ToString();
            dictValues["Crit"] = Crit.ToString() +
                                 string.Format("%*Crit Rating {0}", BasicStats.CritRating);
            dictValues["Weapon Damage"] = BasicStats.WeaponDamage.ToString();
            dictValues.Add("Missed Attacks", AvoidedAttacks.ToString() +
                           string.Format(@"%*Out of 100 attacks:
Attacks Missed: {0}%
Attacks Dodged: {1}%
Attacks Parried: {2}%", MissedAttacks, DodgedAttacks, ParriedAttacks));
            dictValues.Add("Limited Threat", (LimitedThreat / ThreatScale).ToString() +
                           string.Format(@"*White TPS: {0}
Shield Slam TPS: {1}
Revenge TPS: {2}
Devastate TPS: {3}
Windfury TPS: {4}", WhiteThreat, ShieldSlamThreat, RevengeThreat, DevastateThreat, WindfuryThreat));
            dictValues.Add("Unlimited Threat", (UnlimitedThreat / ThreatScale).ToString() +
                           string.Format(@"*Heroic Strike TPS: {0}
Shield Slam TPS: {1}
Revenge TPS: {2}
Devastate TPS: {3}
Windfury TPS: {4}", HeroicStrikeThreat, ShieldSlamThreat, RevengeThreat, DevastateThreat, WindfuryThreat));
            #endregion

            dictValues["Nature Resist"] = (BasicStats.NatureResistance + BasicStats.AllResist).ToString();
            dictValues["Arcane Resist"] = (BasicStats.ArcaneResistance + BasicStats.AllResist).ToString();
            dictValues["Frost Resist"]  = (BasicStats.FrostResistance + BasicStats.AllResist).ToString();
            dictValues["Fire Resist"]   = (BasicStats.FireResistance + BasicStats.AllResist).ToString();
            dictValues["Shadow Resist"] = (BasicStats.ShadowResistance + BasicStats.AllResist).ToString();
            if (BasicStats.Armor == armorCap)
            {
                dictValues.Add("Mitigation", Mitigation.ToString()
                               + string.Format("%*Exactly at the armor cap against level {0} mobs.", TargetLevel));
            }
            else if (BasicStats.Armor > armorCap)
            {
                dictValues.Add("Mitigation", Mitigation.ToString()
                               + string.Format("%*Over the armor cap by {0} armor.", BasicStats.Armor - armorCap));
            }
            else
            {
                dictValues.Add("Mitigation", Mitigation.ToString()
                               + string.Format("%*Short of the armor cap by {0} armor.", armorCap - BasicStats.Armor));
            }
            dictValues.Add("Avoidance", DodgePlusMissPlusParry.ToString() + "%");
            dictValues.Add("Avoidance + Block", DodgePlusMissPlusParryPlusBlock.ToString() + "%");
            dictValues.Add("Total Mitigation", TotalMitigation.ToString() + "%");
            dictValues.Add("Damage Taken", DamageTaken.ToString() + "%");
            if (defToCap == 0 && resToCap == 0)
            {
                dictValues.Add("Chance to be Crit", ((5f + levelDifference) - CritReduction).ToString()
                               + "%*Exactly enough defense rating/resilience to be uncrittable by bosses.");
            }
            else if (defToCap + resToCap > 0)
            {
                dictValues.Add("Chance to be Crit", ((5f + levelDifference) - CritReduction).ToString()
                               + string.Format("%*CRITTABLE! Short by {0} defense rating ({1} defense) or {2} resilience to be uncrittable by bosses.",
                                               defToCap, defToCap * WarriorConversions.DefenseRatingToDefense, resToCap));
            }
            else
            {
                dictValues.Add("Chance to be Crit", ((5f + levelDifference) - CritReduction).ToString()
                               + string.Format("%*Uncrittable by bosses. {0} defense rating ({1} defense) or {2} resilience over the crit cap.",
                                               -defToCap, -defToCap * WarriorConversions.DefenseRatingToDefense, -resToCap));
            }

            dictValues.Add("Chance Crushed", CrushChance.ToString() + "%");
            dictValues.Add("Overall Points", OverallPoints.ToString());
            dictValues.Add("Mitigation Points", MitigationPoints.ToString());
            dictValues.Add("Survival Points", SurvivalPoints.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();

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

            dictValues.Add("Health", BasicStats.Health.ToString());
            dictValues.Add("Mana", BasicStats.Mana.ToString());
            dictValues.Add("Strength", BasicStats.Strength.ToString());
            dictValues.Add("Agility", BasicStats.Agility.ToString());
            dictValues.Add("Stamina", string.Format("{0}*Increases Health by {1}", BasicStats.Stamina, (BasicStats.Stamina - 20f) * 10f + 20f));
            dictValues.Add("Intellect", BasicStats.Intellect.ToString());
            dictValues.Add("Armor", string.Format("{0}*Reduces physical damage taken by {1:0.00%}" + Environment.NewLine +
                                                  "Armor Damage Reduction depends on Attacker Level.",
                                                  BasicStats.Armor, ArmorReduction));
            dictValues.Add("Defense", Defense.ToString() + string.Format("*Defense Rating {0}", BasicStats.DefenseRating));
            dictValues.Add("Dodge", string.Format("{0:0.0000%}*Dodge Rating {1}", Dodge, BasicStats.DodgeRating));
            dictValues.Add("Parry", string.Format("{0:0.0000%}*Parry Rating {1}", Parry, BasicStats.ParryRating));
            dictValues.Add("Block", string.Format("{0:0.0000%}*Block Rating {1}", Block, BasicStats.BlockRating));
            dictValues.Add("Miss", string.Format("{0:0.0000%}", Miss));
            dictValues.Add("Block Value", string.Format("{0}*{1} Active Block Value (Libram etc)", StaticBlockValue, ActiveBlockValue));
            dictValues.Add("Guaranteed Reduction", string.Format("{0:0.00%}", GuaranteedReduction));
            dictValues.Add("Avoidance", string.Format("{0:0.0000%}*Avoidance Points {1}", DodgePlusMissPlusParry, (DodgePlusMissPlusParry * 10000f)));
            dictValues.Add("Avoidance + Block", string.Format("{0:0.0000%}", DodgePlusMissPlusParryPlusBlock));
            dictValues.Add("Total Mitigation", string.Format("{0:0.00%}", TotalMitigation));

            if (AttackerSpeed == BaseAttackerSpeed)
            {
                dictValues.Add("Attacker Speed", string.Format("{0:0.00}s", AttackerSpeed));
            }
            else
            {
                dictValues.Add("Attacker Speed", string.Format("{0:0.00}s*Base speed of {1:0.00}s (reduced by parry haste)", AttackerSpeed, BaseAttackerSpeed));
            }

            dictValues.Add("Damage Taken",
                           string.Format("{0:0.0} DPS*{1:0} damage per normal attack" + Environment.NewLine +
                                         "{2:0} damage per blocked attack" + Environment.NewLine +
                                         "{3:0} damage per critical attack" + Environment.NewLine +
                                         "On Average, you take" + Environment.NewLine +
                                         "{4:0.00%} of incoming damage", DPSTaken, DamageTakenPerHit, DamageTakenPerBlock, DamageTakenPerCrit, DamageTaken));

            dictValues.Add("Resilience",
                           string.Format(@"{0}*Reduces periodic damage and chance to be critically hit by {1:0.00%}." + Environment.NewLine +
                                         "Reduces the effect of mana-drains and the damage of critical strikes by {2:0.00%}.",
                                         BasicStats.Resilience,
                                         StatConversion.GetCritReductionFromResilience(BasicStats.Resilience, CharacterClass.Paladin),
                                         StatConversion.GetCritReductionFromResilience(BasicStats.Resilience, CharacterClass.Paladin) * 2f));

            if (CritVulnerability > 0.0001f)
            {
                double defenseNeeded    = Math.Ceiling((100 * CritVulnerability / StatConversion.DEFENSE_RATING_AVOIDANCE_MULTIPLIER) * StatConversion.RATING_PER_DEFENSE);
                double resilienceNeeded = Math.Ceiling(CritVulnerability * StatConversion.RATING_PER_RESILIENCE);
                dictValues.Add("Chance to be Crit",
                               string.Format("{0:0.00%}*CRITTABLE! Short by approximately {1:0} defense rating or approximately {2:0} resilience rating to be uncrittable.",
                                             CritVulnerability, defenseNeeded, resilienceNeeded));
            }
            else
            {
                dictValues.Add("Chance to be Crit", string.Format("{0:0.00%}*Chance to be crit reduced by {1:0.00%}", CritVulnerability, CritReduction));
            }

            if (UsingHolyShield)
            {
                if (CritVulnerabilityWithoutHolyShield > 0.0001f)
                {
                    double defenseNeeded    = Math.Ceiling((100 * CritVulnerabilityWithoutHolyShield / StatConversion.DEFENSE_RATING_AVOIDANCE_MULTIPLIER) * StatConversion.RATING_PER_DEFENSE);
                    double resilienceNeeded = Math.Ceiling(CritVulnerability * StatConversion.RATING_PER_RESILIENCE);
                    dictValues.Add("...Without Holy Shield",
                                   string.Format("{0:0.00%}*CRITTABLE! Short by approximately {1:0} defense rating or approximately {2:0} resilience rating to be uncrittable without holy shield.",
                                                 CritVulnerabilityWithoutHolyShield, defenseNeeded, resilienceNeeded));
                }
                else
                {
                    dictValues.Add("...Without Holy Shield", string.Format("{0:0.00%}*Chance to be crit reduced by {1:0.00%}", CritVulnerabilityWithoutHolyShield, CritReduction));
                }
            }
            else
            {
                dictValues.Add("...Without Holy Shield", "N/A*Not applicable");
            }

            dictValues.Add("Nature Resist", string.Format("{0:0}*{1:0.00%} Total Reduction", BasicStats.NatureResistance, NatureReduction));
            dictValues.Add("Arcane Resist", string.Format("{0:0}*{1:0.00%} Total Reduction", BasicStats.ArcaneResistance, ArcaneReduction));
            dictValues.Add("Frost Resist", string.Format("{0:0}*{1:0.00%} Total Reduction", BasicStats.FrostResistance, FrostReduction));
            dictValues.Add("Fire Resist", string.Format("{0:0}*{1:0.00%} Total Reduction", BasicStats.FireResistance, FireReduction));
            dictValues.Add("Shadow Resist", string.Format("{0:0}*{1:0.00%} Total Reduction", BasicStats.ShadowResistance, ShadowReduction));
            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.Add("Weapon Speed", string.Format("{0:0.00}*{1:0.00%} Haste", WeaponSpeed, PhysicalHaste));
            dictValues.Add("Attack Power", string.Format("{0}", BasicStats.AttackPower));
            dictValues.Add("Spell Power", string.Format("{0}", BasicStats.SpellPower));
            dictValues.Add("Hit", string.Format("{0:0.00%}*Hit Rating {1}" + Environment.NewLine + "Against a Target of Level {2}", Hit, BasicStats.HitRating, TargetLevel));
            dictValues.Add("Spell Hit", string.Format("{0:0.00%}*Hit Rating {1}" + Environment.NewLine + "Against a Target of Level {2}",
                                                      SpellHit, BasicStats.HitRating, TargetLevel));
            dictValues.Add("Expertise",
                           string.Format("{0:0.00}*Expertise Rating {1}" + Environment.NewLine + "Reduces chance to be dodged or parried by {2:0.00%}.",
                                         StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating, CharacterClass.Paladin) + BasicStats.Expertise,
                                         BasicStats.ExpertiseRating, Expertise));
            dictValues.Add("Physical Haste", string.Format("{0:0.00%}*Haste Rating {1:0.00}", PhysicalHaste, BasicStats.HasteRating));
            dictValues.Add("Effective Target Armor",
                           string.Format("{0}*Reduces the physical damage you deal by {1:0.00%}" + Environment.NewLine + Environment.NewLine +
                                         "Effective Armor depends on Armor ignore debuffs," + Environment.NewLine +
                                         "your Armor Penetration buffs and talents." + Environment.NewLine +
                                         "Enemy Damage Reduction depends on your Level.",
                                         (float)Math.Floor(EffectiveTargetArmor), EffectiveTargetArmorDamageReduction));

            dictValues.Add("Effective Armor Penetration",
                           string.Format("{0:0.00%}*Armor Penetration Rating {1} = {2:0.00%}." + Environment.NewLine + "" + Environment.NewLine +
                                         "Your Armor Penetration Cap is {3} Armor, this is" + Environment.NewLine +
                                         "the highest amount your Arp Rating will ignore." + Environment.NewLine +
                                         "Your Rating currently reduces Enemy Armor by {4}." + Environment.NewLine + "" + Environment.NewLine +
                                         "Your Arp Rating is {5:0.00%} effective (GC)." + Environment.NewLine +
                                         "Note that debuffs like Sunder reduce the Cap.",
                                         EffectiveArmorPenetration, BasicStats.ArmorPenetrationRating, ArmorPenetrationFromRating,
                                         (float)Math.Floor(ArmorPenetrationCap),
                                         (float)Math.Floor(ArmorPenetrationCap * ArmorPenetrationFromRating),
                                         EffectiveArmorPenetrationRating));

            dictValues.Add("Crit", string.Format("{0:0.00%}*Crit Rating {1}" + Environment.NewLine + "Against a Target of Level {2}",
                                                 Crit, BasicStats.CritRating, TargetLevel));
            dictValues.Add("Spell Crit", string.Format("{0:0.00%}*Crit Rating {1}" + Environment.NewLine + "Against a Target of Level {2}",
                                                       SpellCrit, BasicStats.CritRating, TargetLevel));
            dictValues.Add("Weapon Damage", string.Format("{0:0.00}*As average damage per {1}" + Environment.NewLine + "Before Armor",
                                                          BasicStats.WeaponDamage, Lookup.Name(Ability.None)));
            dictValues.Add("Missed Attacks",
                           string.Format("{0:0.00%}*Attacks Missed: {1:0.00%}" + Environment.NewLine + "Attacks Dodged: {2:0.00%}" + Environment.NewLine +
                                         "Attacks Parried: {3:0.00%}", AvoidedAttacks, MissedAttacks, DodgedAttacks, ParriedAttacks));
            dictValues.Add("Glancing Attacks", string.Format("{0:0.00%}*{1:0.00%} Reduction" + Environment.NewLine +
                                                             "Against a Target of Level {2}", GlancingAttacks, 1.0f - GlancingReduction, TargetLevel));
            dictValues.Add("Total Damage/sec", string.Format("{0:0.0}", TotalDamagePerSecond) + "*" + ThreatModel);
            dictValues.Add("Threat/sec", string.Format("{0:0.0}", ThreatPerSecond) + "*" + ThreatModel);
            //dictValues.Add("Unlimited Threat/sec", string.Format("{0:0.0}", UnlimitedThreat) + "*" + ThreatModel);

            switch (RankingMode)
            {
            case 2:
                dictValues.Add("Ranking Mode", "TankPoints*The average amount of unmitigated damage which can be taken before dying");
                dictValues.Add("Survival Points", string.Format("{0:0}*Effective Health", SurvivalPoints));
                break;

            case 3:
                dictValues.Add("Ranking Mode", "Burst Time*The average amount of time between events which have a chance to result in a burst death");
                dictValues.Add("Survival Points", string.Format("{0:0}*{1:0.00} seconds between events", SurvivalPoints, SurvivalPoints / 100.0f));
                break;

            case 4:
                dictValues.Add("Ranking Mode", "Damage Output*The average amount of DPS which can be produced");
                dictValues.Add("Survival Points", string.Format("{0:0}*Survival is not weighted in this mode", SurvivalPoints, SurvivalPoints / 100.0f));
                break;

            case 5:
                dictValues.Add("Ranking Mode", "ProtWarr Mode*Average mitigated damage vs Effective Health");
                dictValues.Add("Survival Points", string.Format("{0:0}*Effective Health", SurvivalPoints));
                break;

            case 6:
                dictValues.Add("Ranking Mode", "Damage Taken*Average taken damage vs. Effective Health");
                dictValues.Add("Survival Points", string.Format("{0:0}*Effective Health", SurvivalPoints));
                break;

            case 7:
                dictValues.Add("Ranking Mode", "Ranking Mode 7*Dummy Placeholder");
                dictValues.Add("Survival Points", string.Format("{0:0}*Survival Placeholder", SurvivalPoints));
                break;

            case 8:
                dictValues.Add("Ranking Mode", "Ranking Mode 8*Dummy Placeholder");
                dictValues.Add("Survival Points", string.Format("{0:0}*Survival Placeholder", SurvivalPoints));
                break;

            default:
                dictValues.Add("Ranking Mode", "Mitigation Scale*Customizable scale which allows you to weight mitigation vs. effective health.");
                dictValues.Add("Survival Points", string.Format("{0:0}*Effective Health", SurvivalPoints));
                break;
            }
            dictValues.Add("Overall Points", string.Format("{0:0}", OverallPoints));
            dictValues.Add("Mitigation Points", string.Format("{0:0}", MitigationPoints));
            dictValues.Add("Threat Points", string.Format("{0:0}", ThreatPoints));

            return(dictValues);
        }