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); }
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("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); }