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>(); 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); }
public override Dictionary <string, string> GetCharacterDisplayCalculationValues() { Dictionary <string, string> dictValues = new Dictionary <string, string>(); Stats baseStats = BaseStats.GetBaseStats(character); dictValues.Add("Health", BasicStats.Health.ToString()); dictValues.Add("Stamina", BasicStats.Stamina.ToString()); float ResilienceCap = 0.15f, ResilienceFromRating = StatConversion.GetCritReductionFromResilience(1); float Resilience = StatConversion.GetCritReductionFromResilience(BasicStats.Resilience); dictValues.Add("Resilience", string.Format("{0}*-{1}% Damage from DoT and Mana Drains\n\r-{1}% Chance to be crit\r\n-{2}% Damage from Crits.\r\n{3}", BasicStats.Resilience.ToString(), (Resilience * 100f).ToString("0.00"), (Resilience * 100f * 2.2f).ToString("0.00"), (Resilience > ResilienceCap)?(string.Format("{0} rating above cap", ((float)Math.Floor((Resilience - ResilienceCap) / ResilienceFromRating)).ToString("0"))):(string.Format("{0} rating below cap", ((float)Math.Ceiling((ResilienceCap - Resilience) / ResilienceFromRating)).ToString("0"))))); dictValues.Add("Mana", BasicStats.Mana.ToString()); dictValues.Add("Intellect", BasicStats.Intellect.ToString()); dictValues.Add("Spirit", Math.Floor(BasicStats.Spirit).ToString("0")); dictValues.Add("Spell Power", string.Format("{0}*{1} from Inner Fire", Math.Floor(BasicStats.SpellPower).ToString("0"), BasicStats.PriestInnerFire * CalculationsHealPriest.GetInnerFireSpellPowerBonus(character))); //dictValues.Add("Healing", Math.Floor(BasicStats.SpellPower * 1.88f).ToString("0")); dictValues.Add("In FSR MP5", string.Format("{0}*{1} from MP5\r\n{2} from Meditation\r\n{3} Outside FSR\r\n{4} OFSR w/MP5", (BasicStats.Mp5 + RegenInFSR).ToString("0"), BasicStats.Mp5.ToString("0"), RegenInFSR.ToString("0"), RegenOutFSR.ToString("0"), (BasicStats.Mp5 + RegenOutFSR).ToString("0"))); dictValues.Add("Spell Crit", string.Format("{0}%*{1}% from Intellect\r\n{2}% from {6} Crit rating\r\n{3}% from Focused Will\r\n{4}% Class Base\r\n{5}% from Buffs", (BasicStats.SpellCrit * 100f).ToString("0.00"), (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f).ToString("0.00"), (StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f).ToString("0.00"), character.PriestTalents.FocusedWill.ToString("0"), (baseStats.SpellCrit * 100f).ToString("0.00"), (BasicStats.SpellCrit * 100f - baseStats.SpellCrit * 100f - StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f - StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f - character.PriestTalents.FocusedWill * 1f).ToString("0.00"), BasicStats.CritRating)); dictValues.Add("Healing Crit", string.Format("{0}%*{1} ({1}%) points in Holy Specialization\r\n{2} ({3}%) points in Renewed Hope", ((BasicStats.SpellCrit * 100f) + character.PriestTalents.HolySpecialization * 1f + character.PriestTalents.RenewedHope * 2f).ToString("0.00"), character.PriestTalents.HolySpecialization, character.PriestTalents.RenewedHope, character.PriestTalents.RenewedHope * 2)); dictValues.Add("Spell Haste", string.Format("{0}%*{1}% from {2} Haste rating\r\n{3}% ({6}) points in Enlightenment\r\n{4}% from Buffs\r\n{5}s Global Cooldown", (BasicStats.SpellHaste * 100f).ToString("0.00"), (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating) * 100f).ToString("0.00"), BasicStats.HasteRating.ToString(), (character.PriestTalents.Enlightenment * 2).ToString("0"), (((1 + BasicStats.SpellHaste) / (1 + StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating)) / (1 + character.PriestTalents.Enlightenment * 0.02f) - 1) * 100f).ToString("0.00"), Math.Max(1.0f, 1.5f / (1 + BasicStats.SpellHaste)).ToString("0.00"), character.PriestTalents.Enlightenment)); dictValues.Add("Armor", string.Format("{0}*{1}% Damage Reduction.", (BasicStats.Armor + BasicStats.BonusArmor).ToString("0"), (StatConversion.GetArmorDamageReduction(80, (BasicStats.Armor + BasicStats.BonusArmor), 0f, 0f, 0f) * 100f).ToString("0.00"))); float[] Resistances = { 0, BasicStats.ArcaneResistance + BasicStats.ArcaneResistanceBuff, BasicStats.FireResistance + BasicStats.FireResistanceBuff, BasicStats.FrostResistance + BasicStats.FrostResistanceBuff, BasicStats.NatureResistance + BasicStats.NatureResistanceBuff, BasicStats.ShadowResistance + BasicStats.ShadowResistanceBuff, }; string[] ResistanceNames = { "None", "Arcane", "Fire", "Frost", "Nature", "Shadow", }; string ResistanceString = "*Resistances:"; float MaxResist = Resistances[0]; int MaxResistIndex = 0; float AvgResist = 0f; for (int x = 1; x < Resistances.Length; x++) { AvgResist += Resistances[x]; if (Resistances[x] > MaxResist) { MaxResist = Resistances[x]; MaxResistIndex = x; } ResistanceString += string.Format("\r\n{0} : {1}", ResistanceNames[x], Resistances[x]); } AvgResist /= (Resistances.Length - 1); if (AvgResist == 0) { ResistanceString = "None" + ResistanceString; } else { string ResistanceName = (MaxResist == AvgResist) ? "All" : ResistanceNames[MaxResistIndex]; ResistanceString = string.Format("{0} : {1}", ResistanceName, MaxResist.ToString("0")) + ResistanceString; ResistanceString += string.Format("\r\n\r\nResist ({0}):", ResistanceName); ResistanceString += string.Format("\r\n{0}", StatConversion.GetResistanceTableString(character.Level + 3, character.Level, MaxResist, 0)); } dictValues.Add("Resistance", ResistanceString); BaseSolver solver; if ((character.CalculationOptions as CalculationOptionsHealPriest).Role == eRole.CUSTOM) { solver = new AdvancedSolver(BasicStats, character); } else { solver = new Solver(BasicStats, character); } solver.Calculate(this); dictValues.Add("Role", string.Format("{0}*{1}", solver.Role, solver.ActionList)); dictValues.Add("Burst", string.Format("{0}", HPSBurstPoints.ToString("0"))); dictValues.Add("Sustained", string.Format("{0}", HPSSustainPoints.ToString("0"))); dictValues.Add("Renew", new Renew(BasicStats, character).ToString()); dictValues.Add("Flash Heal", new FlashHeal(BasicStats, character).ToString()); dictValues.Add("Greater Heal", new Heal(BasicStats, character).ToString()); dictValues.Add("PoH", new PrayerOfHealing(BasicStats, character).ToString()); dictValues.Add("Binding Heal", new BindingHeal(BasicStats, character).ToString()); dictValues.Add("Prayer of Mending", new PrayerOfMending(BasicStats, character).ToString()); dictValues.Add("Power Word Shield", new PowerWordShield(BasicStats, character).ToString()); dictValues.Add("Holy Nova", new HolyNova(BasicStats, character).ToString()); if (character.PriestTalents.CircleOfHealing > 0) { dictValues.Add("CoH", new CircleOfHealing(BasicStats, character).ToString()); } else { dictValues.Add("CoH", "- *No required talents"); } if (character.PriestTalents.Lightwell > 0) { dictValues.Add("Lightwell", new Lightwell(BasicStats, character).ToString()); } else { dictValues.Add("Lightwell", "- *No required talents"); } if (character.PriestTalents.Penance > 0) { dictValues.Add("Penance", new Penance(BasicStats, character).ToString()); } else { dictValues.Add("Penance", "- *No required talents"); } if (Race == CharacterRace.Draenei) { dictValues.Add("Gift of the Naaru", new GiftOfTheNaaru(BasicStats, character).ToString()); } else { dictValues.Add("Gift of the Naaru", "-"); } dictValues.Add("Divine Hymn", new DivineHymn(BasicStats, character).ToString()); dictValues.Add("Resurrection", new Resurrection(BasicStats, character).ToString()); return(dictValues); }
public override Dictionary <string, string> GetCharacterDisplayCalculationValues() { Dictionary <string, string> dictValues = new Dictionary <string, string>(); CalculationOptionsShadowPriest calcOpts = character.CalculationOptions as CalculationOptionsShadowPriest; BossOptions BossOpts = character.BossOptions; Stats baseStats = BaseStats.GetBaseStats(character.Level, character.Class, character.Race); bool Ptr = calcOpts.PTR; dictValues.Add("Health", BasicStats.Health.ToString()); float ResilienceCap = 0.15f, ResilienceFromRating = StatConversion.GetCritReductionFromResilience(1); float Resilience = StatConversion.GetCritReductionFromResilience(BasicStats.Resilience); dictValues.Add("Resilience", string.Format("{0}*-{1}% Damage from DoT and Mana Drains\n\r-{1}% Chance to be crit\r\n-{2}% Damage from Crits.\r\n{3}", BasicStats.Resilience.ToString(), (Resilience * 100f).ToString("0.00"), (Resilience * 100f * 2.2f).ToString("0.00"), (Resilience > ResilienceCap) ? (string.Format("{0} rating above cap", ((float)Math.Floor((Resilience - ResilienceCap) / ResilienceFromRating)).ToString("0"))) : (string.Format("{0} rating below cap", ((float)Math.Ceiling((ResilienceCap - Resilience) / ResilienceFromRating)).ToString("0"))))); dictValues.Add("Stamina", BasicStats.Stamina.ToString()); dictValues.Add("Mana", BasicStats.Mana.ToString()); dictValues.Add("Intellect", BasicStats.Intellect.ToString()); dictValues.Add("Spirit", Math.Floor(BasicStats.Spirit).ToString("0")); dictValues.Add("Spell Power", String.Format("{0}*{1} Bonus Shadow\r\n{2} Bonus Holy\r\n{3} from Inner Fire", Math.Floor(BasicStats.SpellPower), Math.Floor(BasicStats.SpellPower + BasicStats.SpellShadowDamageRating), Math.Floor(BasicStats.SpellPower /*+ BasicStats.SpellHolyDamageRating*/), BasicStats.PriestInnerFire * CalculationsShadowPriest.GetInnerFireSpellPowerBonus(character))); dictValues.Add("Regen", String.Format("{0}*MP5: {1}\r\nOutFSR: {2}", RegenInFSR.ToString("0"), BasicStats.Mp5.ToString(), RegenOutFSR.ToString("0"))); dictValues.Add("Crit", string.Format("{0}%*{1}% from {2} Spell Crit rating\r\n{3}% from Intellect\r\n{4}% from Focused Will\r\n{5}% from Base Crit\r\n{6}% from Buffs\r\n{7}% on Mind Blast, Mind Flay and Mind Sear.\r\n{8}% on VT, SW:P and DP\r\n{9}% on Smite, Holy Fire and Penance.", (BasicStats.SpellCrit * 100f).ToString("0.00"), (StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f).ToString("0.00"), BasicStats.CritRating.ToString("0"), (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f).ToString("0.00"), character.PriestTalents.FocusedWill, (baseStats.SpellCrit * 100f).ToString("0.00"), (BasicStats.SpellCrit * 100f - StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f - StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f - baseStats.SpellCrit * 100f - character.PriestTalents.FocusedWill).ToString("0.00"), (BasicStats.SpellCrit * 100f + character.PriestTalents.MindMelt * 2f).ToString("0.00"), (BasicStats.SpellCrit * 100f + character.PriestTalents.MindMelt * 3f).ToString("0.00"), (BasicStats.SpellCrit * 100f + character.PriestTalents.HolySpecialization * 1f).ToString("0.00"))); #if RAWR3 || SILVERLIGHT float Hit = 100 - (StatConversion.GetSpellMiss(character.Level - BossOpts.Level, false) * 100); #else float Hit = 100 - (StatConversion.GetSpellMiss(-calcOpts.TargetLevel, false) * 100); #endif float BonusHit = BasicStats.SpellHit * 100f; float RacialHit = 0; string RacialText = ""; if (character.Race == CharacterRace.Draenei) { RacialHit = 1; RacialText = "1% from Draenei Racial\r\n"; if (!character.ActiveBuffsContains("Heroic Presence")) { BonusHit += 1; } } float DebuffHit = character.PriestTalents.Misery * 1f; if (character.ActiveBuffsConflictingBuffContains("Spell Hit Chance Taken")) { DebuffHit = 3f; } else { BonusHit += DebuffHit; } float RHitRating = 0.01f / StatConversion.GetSpellHitFromRating(1); float ShadowFocusHit = character.PriestTalents.ShadowFocus * 1f; float HitShadow = Hit + BonusHit + ShadowFocusHit; float HitHoly = Hit + BonusHit; dictValues.Add("Hit", string.Format("{0}%*{1}% from {2} Hit Rating\r\n{3}% from Buffs\r\n{4}% from {5} points in Misery\r\n{6}% from {7} points in Shadow Focus\r\n{8}{9}% Hit with Shadow spells, {10}\r\n{11}% Hit with Holy spells, {12}", BonusHit.ToString("0.00"), (StatConversion.GetSpellHitFromRating(BasicStats.HitRating) * 100f).ToString("0.00"), BasicStats.HitRating, (BonusHit - StatConversion.GetSpellHitFromRating(BasicStats.HitRating) * 100f - RacialHit - DebuffHit).ToString("0.00"), DebuffHit, character.PriestTalents.Misery, ShadowFocusHit, character.PriestTalents.ShadowFocus, RacialText, HitShadow.ToString("0.00"), (HitShadow > 100f) ? string.Format("{0} hit rating above cap", Math.Floor((HitShadow - 100f) * RHitRating)) : string.Format("{0} hit rating below cap", Math.Ceiling((100f - HitShadow) * RHitRating)), HitHoly.ToString("0.00"), (HitHoly > 100f) ? string.Format("{0} hit rating above cap", Math.Floor((HitHoly - 100f) * RHitRating)) : string.Format("{0} hit rating below cap", Math.Ceiling((100f - HitHoly) * RHitRating)))); dictValues.Add("Haste", string.Format("{0}%*{1}% from {2} Haste rating\r\n{3}% ({6}) points in Enlightenment\r\n{4}% from Buffs\r\n{5}s Global Cooldown", (BasicStats.SpellHaste * 100f).ToString("0.00"), (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating) * 100f).ToString("0.00"), BasicStats.HasteRating.ToString(), (character.PriestTalents.Enlightenment * 2).ToString("0"), (((1f + BasicStats.SpellHaste) / (1f + StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating)) / (1f + character.PriestTalents.Enlightenment * 0.02f) - 1f) * 100f).ToString("0.00"), Math.Max(1.0f, 1.5f / (1 + BasicStats.SpellHaste)).ToString("0.00"), character.PriestTalents.Enlightenment)); dictValues.Add("Armor", string.Format("{0}*{1}% Damage Reduction.", (BasicStats.Armor + BasicStats.BonusArmor).ToString("0"), (StatConversion.GetArmorDamageReduction(80, (BasicStats.Armor + BasicStats.BonusArmor), 0f, 0f, 0f) * 100f).ToString("0.00"))); float[] Resistances = { 0, BasicStats.ArcaneResistance + BasicStats.ArcaneResistanceBuff, BasicStats.FireResistance + BasicStats.FireResistanceBuff, BasicStats.FrostResistance + BasicStats.FrostResistanceBuff, BasicStats.NatureResistance + BasicStats.NatureResistanceBuff, BasicStats.ShadowResistance + BasicStats.ShadowResistanceBuff, }; string[] ResistanceNames = { "None", "Arcane", "Fire", "Frost", "Nature", "Shadow", }; string ResistanceString = "*Resistances:"; float MaxResist = Resistances[0]; int MaxResistIndex = 0; float AvgResist = 0f; for (int x = 1; x < Resistances.Length; x++) { AvgResist += Resistances[x]; if (Resistances[x] > MaxResist) { MaxResist = Resistances[x]; MaxResistIndex = x; } ResistanceString += string.Format("\r\n{0} : {1}", ResistanceNames[x], Resistances[x]); } AvgResist /= (Resistances.Length - 1); if (AvgResist == 0) { ResistanceString = "None" + ResistanceString; } else { string ResistanceName = (MaxResist == AvgResist) ? "All" : ResistanceNames[MaxResistIndex]; ResistanceString = string.Format("{0} : {1}", ResistanceName, MaxResist.ToString("0")) + ResistanceString; ResistanceString += string.Format("\r\n\r\nResist ({0}):", ResistanceName); ResistanceString += string.Format("\r\n{0}", StatConversion.GetResistanceTableString(character.Level + 3, character.Level, MaxResist, 0)); } dictValues.Add("Resistance", ResistanceString); SolverBase solver = GetSolver(character, BasicStats); solver.Calculate(this); dictValues.Add("Rotation", string.Format("{0}*{1}", solver.Name, solver.Rotation)); if (solver.SpellSimulation != null) { String s = "Spell Cast List:"; int i = 0; foreach (Spell spell in solver.SpellSimulation) { if (i++ % 10 == 0) { s += "\r\n"; } s += ", " + spell.Name; } s += "\r\n---Repeat---"; dictValues.Add("Castlist", string.Format("{0}*{1}", solver.SpellSimulation.Count, s)); } else { dictValues.Add("Castlist", "Empty"); } dictValues.Add("DPS", string.Format("{0}*Damage Pr Second", solver.DPS.ToString("0"))); //dictValues.Add("SustainDPS", string.Format("{0}*Mana restrained DPS", solver.SustainDPS.ToString("0"))); float baseMana = BaseStats.GetBaseStats(character).Mana; dictValues.Add("SW Pain", new ShadowWordPain(BasicStats, character, baseMana, Ptr).ToString()); DevouringPlague dp = new DevouringPlague(BasicStats, character, baseMana, Ptr); dictValues.Add("Devouring Plague", dp.ToString()); if (dp.ImprovedDP != null) { dictValues.Add("Imp. Devouring Plague", dp.ImprovedDP.ToString()); } else { dictValues.Add("Imp. Devouring Plague", "- *No required talents"); } dictValues.Add("SW Death", new ShadowWordDeath(BasicStats, character, baseMana, Ptr).ToString()); dictValues.Add("Mind Blast", new MindBlast(BasicStats, character, baseMana, Ptr).ToString()); dictValues.Add("PW Shield", new PowerWordShield(BasicStats, character, baseMana, Ptr).ToString()); if (character.PriestTalents.VampiricTouch > 0) { dictValues.Add("Vampiric Touch", new VampiricTouch(BasicStats, character, baseMana, Ptr).ToString()); } else { dictValues.Add("Vampiric Touch", "- *No required talents"); } if (character.PriestTalents.MindFlay > 0) { dictValues.Add("Mind Flay", new MindFlay(BasicStats, character, baseMana, Ptr).ToString()); } else { dictValues.Add("Mind Flay", "- *No required talents"); } dictValues.Add("Shadowfiend", new Shadowfiend(BasicStats, character, baseMana, Ptr).ToString()); dictValues.Add("Smite", new Smite(BasicStats, character, baseMana, Ptr).ToString()); dictValues.Add("Holy Fire", new HolyFire(BasicStats, character, baseMana, Ptr).ToString()); if (character.PriestTalents.Penance > 0) { dictValues.Add("Penance", new Penance(BasicStats, character, baseMana, Ptr).ToString()); } else { dictValues.Add("Penance", "- *No required talents"); } return(dictValues); }