public override float GetOptimizableCalculationValue(string calculation) { switch (calculation) { case "Health": return(BasicStats.Health); case "Avoided Attacks %": return(AvoidedAttacks); case "Hit Rating": return(BasicStats.HitRating); case "Hit Rating %": return(StatConversion.GetPhysicalHitFromRating(BasicStats.HitRating) * 100); case "Expertise Rating": return(BasicStats.ExpertiseRating); case "Expertise": return(StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating)); case "Expertise Rating %": return(StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating) * 0.25f); case "Nature Resist": return(BasicStats.NatureResistance); case "Fire Resist": return(BasicStats.FireResistance); case "Frost Resist": return(BasicStats.FrostResistance); case "Shadow Resist": return(BasicStats.ShadowResistance); case "Arcane Resist": return(BasicStats.ArcaneResistance); //case "Custom Rotation DPS": return CustomRotation.DPS; } return(0f); }
private void ConvertRatings(Stats stats, PaladinTalents talents, CalculationOptionsHealadin calcOpts) { stats.Stamina *= 1f + stats.BonusStaminaMultiplier; // Intellect is used to calculate initial mana pool. // To avoid temporary intellect from highest stat procs changing initial mana pool // we track temporary intellect separatly in HighestStat property and combine it with intellect // when needed. // TODO: However this doesn't help to deal with pure temporary intellect procs (if there are any). // NOTE: If we add highest stat to intellect after we calculate mana, the only visible change // will be the displayed intellect for the character. stats.Intellect *= (1f + stats.BonusIntellectMultiplier); stats.HighestStat *= (1f + stats.BonusIntellectMultiplier); stats.SpellCrit = stats.SpellCrit + StatConversion.GetSpellCritFromIntellect( stats.Intellect + stats.HighestStat, CharacterClass.Paladin) + StatConversion.GetSpellCritFromRating(stats.CritRating, CharacterClass.Paladin); // I want to track haste before talent seperately, going to use RangedHaste for that. // I plan to use this on the "Stats" page so I can report sources of haste seperatly stats.RangedHaste = (1f + stats.SpellHaste) * (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin)) - 1f; // calculating physical haste for use in melee attacks, which will generate mana // can also divide spellhaste / physicalhaste to get orignal value of spellhaste, which is from buffs as far as I can tell stats.PhysicalHaste = (1f + talents.JudgementsOfThePure * 0.03f) * (1f + talents.SpeedOfLight * 0.01f) * (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin)) - 1f; stats.SpellHaste = (1f + talents.JudgementsOfThePure * 0.03f) * (1f + talents.SpeedOfLight * 0.01f) * (1f + stats.SpellHaste) * (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin)) - 1f; // GetManaFromIntellect/GetHealthFromStamina account for the fact // that the first 20 Int/Sta only give 1 Mana/Health each. stats.Mana += StatConversion.GetManaFromIntellect(stats.Intellect, CharacterClass.Paladin) * (1f + stats.BonusManaMultiplier); stats.Health += StatConversion.GetHealthFromStamina(stats.Stamina, CharacterClass.Paladin); stats.PhysicalHit += StatConversion.GetPhysicalHitFromRating( stats.HitRating, CharacterClass.Paladin); }
private void ConvertRatings(Stats stats, PaladinTalents talents, CalculationOptionsHealadin calcOpts) { stats.Stamina *= 1f + stats.BonusStaminaMultiplier; // Intellect is used to calculate initial mana pool. // To avoid temporary intellect from highest stat procs changing initial mana pool // we track temporary intellect separatly in HighestStat property and combine it with intellect // when needed. // TODO: However this doesn't help to deal with pure temporary intellect procs (if there are any). // NOTE: If we add highest stat to intellect after we calculate mana, the only visible change // will be the displayed intellect for the character. stats.Intellect *= (1f + stats.BonusIntellectMultiplier) * (1f + talents.DivineIntellect * .02f); stats.HighestStat *= (1f + stats.BonusIntellectMultiplier) * (1f + talents.DivineIntellect * .02f); stats.SpellPower += 0.04f * (stats.Intellect + stats.HighestStat) * talents.HolyGuidance; stats.SpellCrit = stats.SpellCrit + StatConversion.GetSpellCritFromIntellect( stats.Intellect + stats.HighestStat, CharacterClass.Paladin) + StatConversion.GetSpellCritFromRating(stats.CritRating, CharacterClass.Paladin) + talents.SanctityOfBattle * .01f + talents.Conviction * .01f; stats.SpellHaste = (1f + talents.JudgementsOfThePure * (calcOpts.JotP ? .03f : 0f)) * (1f + stats.SpellHaste) * (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin)) - 1f; // GetManaFromIntellect/GetHealthFromStamina account for the fact // that the first 20 Int/Sta only give 1 Mana/Health each. stats.Mana += StatConversion.GetManaFromIntellect(stats.Intellect, CharacterClass.Paladin) * (1f + stats.BonusManaMultiplier); stats.Health += StatConversion.GetHealthFromStamina(stats.Stamina, CharacterClass.Paladin); stats.PhysicalHit += StatConversion.GetPhysicalHitFromRating( stats.HitRating, CharacterClass.Paladin); }
public override Dictionary <string, string> GetCharacterDisplayCalculationValues() { float critRating = BasicStats.CritRating; float hitRating = BasicStats.HitRating; Dictionary <string, string> dictValues = new Dictionary <string, string>(); dictValues.Add("Health", BasicStats.Health.ToString("N0")); dictValues.Add("Strength", BasicStats.Strength.ToString("N0")); dictValues.Add("Agility", string.Format("{0:0}*Provides {1:P} crit chance", BasicStats.Agility, StatConversion.GetCritFromAgility(BasicStats.Agility, CharacterClass.DeathKnight))); dictValues.Add("Attack Power", BasicStats.AttackPower.ToString("N0")); dictValues.Add("Crit Rating", string.Format("{0:0}*Provides {1:P} crit chance", critRating, StatConversion.GetCritFromRating(critRating, CharacterClass.DeathKnight))); dictValues.Add("Hit Rating", string.Format("{0:0}*Negates {1:P} melee miss / {2:P} spell miss", hitRating, StatConversion.GetPhysicalHitFromRating(hitRating, CharacterClass.DeathKnight), StatConversion.GetSpellHitFromRating(hitRating, CharacterClass.DeathKnight))); dictValues.Add("Expertise", string.Format("{0:0.00} / {1:0.00}*Negates {2:P} / {3:P} dodge chance", MHExpertise, OHExpertise, StatConversion.GetDodgeParryReducFromExpertise(MHExpertise), StatConversion.GetDodgeParryReducFromExpertise(OHExpertise))); dictValues.Add("Haste Rating", string.Format("{0:0}*Increases attack speed by {1:P}", BasicStats.HasteRating, StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.DeathKnight))); dictValues.Add("Armor", BasicStats.Armor.ToString("N0")); dictValues.Add("Resilience", BasicStats.Resilience.ToString("F0")); dictValues.Add("Mastery", string.Format("{0:N0}*Rating: {1:N0}", BasicStats.Mastery, BasicStats.MasteryRating)); dictValues.Add("Weapon Damage", MHWeaponDamage.ToString("N2") + " / " + OHWeaponDamage.ToString("N2")); dictValues.Add("Attack Speed", MHAttackSpeed.ToString("N2") + " / " + OHAttackSpeed.ToString("N2")); dictValues.Add("Crit Chance", string.Format("{0:P}", BasicStats.PhysicalCrit)); dictValues.Add("Avoided Attacks", string.Format("{0:P}*{1:P} Dodged, {2:P} Missed", AvoidedAttacks, DodgedAttacks, MissedAttacks)); dictValues.Add("Enemy Mitigation", string.Format("{0:P}*{1:0} effective enemy armor", EnemyMitigation, EffectiveArmor)); dictValues.Add("White HitChance", string.Format("{0:P}*Include Glance & Crit Chance", WhiteHitChance)); dictValues.Add("Yellow HitChance", string.Format("{0:P}", YellowHitChance)); foreach (int i in EnumHelper.GetValues(typeof(DKability))) { dictValues.Add(Enum.GetName(typeof(DKability), i), string.Format("{0:N2}*{1:P}", dpsSub[i], (dpsSub[i] / DPSPoints))); } dictValues.Add("Total DPS", DPSPoints.ToString("N2")); dictValues.Add("Rotation Duration", RotationTime.ToString() + " secs"); dictValues.Add("Blood", Blood.ToString()); dictValues.Add("Frost", Frost.ToString()); dictValues.Add("Unholy", Unholy.ToString()); dictValues.Add("Death", Death.ToString()); dictValues.Add("Runic Power", Death.ToString()); dictValues.Add("RE Runes", FreeRERunes.ToString("N2")); dictValues.Add("Rune Cooldown", m_RuneCD.ToString("N2")); PopulateSingleUseValues(dictValues, "BB", DKability.BloodBoil); PopulateSingleUseValues(dictValues, "BP", DKability.BloodPlague); PopulateSingleUseValues(dictValues, "BS", DKability.BloodStrike); PopulateSingleUseValues(dictValues, "DC", DKability.DeathCoil); PopulateSingleUseValues(dictValues, "DnD", DKability.DeathNDecay); PopulateSingleUseValues(dictValues, "DS", DKability.DeathStrike); PopulateSingleUseValues(dictValues, "Fest", DKability.FesteringStrike); PopulateSingleUseValues(dictValues, "FF", DKability.FrostFever); PopulateSingleUseValues(dictValues, "FS", DKability.FrostStrike); PopulateSingleUseValues(dictValues, "HS", DKability.HeartStrike); PopulateSingleUseValues(dictValues, "HB", DKability.HowlingBlast); PopulateSingleUseValues(dictValues, "IT", DKability.IcyTouch); PopulateSingleUseValues(dictValues, "NS", DKability.NecroticStrike); PopulateSingleUseValues(dictValues, "OB", DKability.Obliterate); PopulateSingleUseValues(dictValues, "PS", DKability.PlagueStrike); PopulateSingleUseValues(dictValues, "RS", DKability.RuneStrike); PopulateSingleUseValues(dictValues, "SS", DKability.ScourgeStrike); return(dictValues); }
public void CritsAndResists() { #region Crits, Resists { // Attack Rolltable (DW): // 27.0% miss (8.0% with 2H) // 6.5% dodge // 24.0% glancing (75% hit-dmg) // xx.x% crit // remaining = hit float targetArmor = calcOpts.BossArmor, totalArP = stats.ArmorPenetration; float arpBuffs = talents.BloodGorged * 2f / 100; physicalMitigation = 1f - StatConversion.GetArmorDamageReduction(character.Level, targetArmor, stats.ArmorPenetration, arpBuffs, stats.ArmorPenetrationRating); calcs.EnemyMitigation = 1f - physicalMitigation; calcs.EffectiveArmor = physicalMitigation; // Crit: Base .65% physCrits = .0065f; physCrits += StatConversion.GetPhysicalCritFromRating(stats.CritRating); physCrits += StatConversion.GetPhysicalCritFromAgility(stats.Agility, CharacterClass.DeathKnight); physCrits += .01f * (float)(talents.DarkConviction + talents.EbonPlaguebringer + talents.Annihilation); physCrits += stats.PhysicalCrit; calcs.CritChance = physCrits; float chanceAvoided = 0.335f; float chanceDodged = StatConversion.WHITE_DODGE_CHANCE_CAP[calcOpts.TargetLevel - 80]; calcs.DodgedMHAttacks = MH.chanceDodged; calcs.DodgedOHAttacks = OH.chanceDodged; if (character.MainHand != null) { chanceDodged = MH.chanceDodged; } if (character.OffHand != null) { if (DW) { chanceDodged += OH.chanceDodged; chanceDodged /= 2; } else if (character.MainHand == null) { chanceDodged = OH.chanceDodged; } } calcs.DodgedAttacks = chanceDodged; // Process White hits: float chanceMiss = DW ? StatConversion.WHITE_MISS_CHANCE_CAP_DW[calcOpts.TargetLevel - 80] : StatConversion.WHITE_MISS_CHANCE_CAP[calcOpts.TargetLevel - 80]; chanceMiss -= StatConversion.GetPhysicalHitFromRating(stats.HitRating); chanceMiss -= hitBonus; chanceMiss -= stats.PhysicalHit; // Cap the Miss rate at 0% chanceMiss = Math.Max(chanceMiss, 0f); calcs.MissedAttacks = chanceMiss; whiteMiss = chanceMiss; chanceAvoided = chanceDodged + chanceMiss; calcs.AvoidedAttacks = chanceDodged + chanceMiss; // Process Yellow hits chanceMiss = StatConversion.YELLOW_MISS_CHANCE_CAP[calcOpts.TargetLevel - 80]; chanceMiss -= StatConversion.GetPhysicalHitFromRating(stats.HitRating); chanceMiss -= hitBonus; chanceMiss -= stats.PhysicalHit; chanceMiss = Math.Max(chanceMiss, 0f); chanceDodged = MH.chanceDodged; missedSpecial = chanceMiss; dodgedSpecial = chanceDodged; // calcs.MissedAttacks = chanceMiss spellCrits = 0f; spellCrits += StatConversion.GetSpellCritFromRating(stats.CritRating); spellCrits += stats.SpellCrit + stats.SpellCritOnTarget; spellCrits += .01f * (float)(talents.DarkConviction + talents.EbonPlaguebringer); calcs.SpellCritChance = spellCrits; // Resists: Base 17% spellResist = .17f; spellResist -= StatConversion.GetSpellHitFromRating(stats.HitRating); spellResist -= .01f * talents.Virulence; spellResist -= stats.SpellHit; if (spellResist < 0f) { spellResist = 0f; } // Total physical misses totalMHMiss = calcs.DodgedMHAttacks + whiteMiss; totalOHMiss = calcs.DodgedOHAttacks + whiteMiss; double spellGCD = (calcOpts.rotation.presence == CalculationOptionsDPSDK.Presence.Blood ? 1.5d / ((1 + (StatConversion.GetHasteFromRating(stats.HasteRating, CharacterClass.DeathKnight))) * (1d + stats.SpellHaste)) < 1d ? 1d : 1.5d / ((1 + (StatConversion.GetHasteFromRating(stats.HasteRating, CharacterClass.DeathKnight))) * (1d + stats.SpellHaste)): 1d); double physicalGCD = (calcOpts.rotation.presence == CalculationOptionsDPSDK.Presence.Blood ? 1.5d : 1d); float minDuration = totalMeleeAbilities * (float)physicalGCD + totalSpellAbilities * (float)spellGCD; realDuration = (float)Math.Max(minDuration, calcOpts.rotation.CurRotationDuration); float dodgeMissPerRotation = (float)(totalMeleeAbilities - calcOpts.rotation.FrostStrike); chanceAvoided = chanceDodged + chanceMiss; double GChanceAvoided = (1 / (1 - chanceAvoided)) - 1; double GSpellResist = (1 / (1 - spellResist)) - 1; double ProbableGCDLossPerRotation = dodgeMissPerRotation * physicalGCD * GChanceAvoided + (calcOpts.rotation.IcyTouch + calcOpts.rotation.Pestilence) * spellGCD * GSpellResist; realDuration += (float)(((minDuration + ProbableGCDLossPerRotation) / realDuration < 1 ? (minDuration + ProbableGCDLossPerRotation) / realDuration : 1) * ProbableGCDLossPerRotation); // This last line is a bit hackish, but basically the extra GCD is more inconvenient the closer we are to having a GCD-capped rotation; once we're GCD-capped, they cost the full value. } #endregion }
public static float BonusHitPercentage(Character character, Stats stats) { return(StatConversion.GetPhysicalHitFromRating(stats.HitRating, CharacterClass.Warrior) + stats.PhysicalHit); //return ((stats.HitRating * ProtWarr.HitRatingToHit) / 100.0f) + stats.PhysicalHit; }
public static float BonusHitPercentage(Player player) { return(StatConversion.GetPhysicalHitFromRating(player.Stats.HitRating, CharacterClass.Warrior) + player.Stats.PhysicalHit); }
public override Dictionary <string, string> GetCharacterDisplayCalculationValues() { float critRating = BasicStats.CritRating; float hitRating = BasicStats.HitRating; float armorPenetrationRating = BasicStats.ArmorPenetrationRating; float attackPower = BasicStats.AttackPower; if (ActiveBuffs.Contains(Buff.GetBuffByName("Improved Hunter's Mark"))) { attackPower -= 110f * (1f + BasicStats.BonusAttackPowerMultiplier); } Dictionary <string, string> dictValues = new Dictionary <string, string>(); dictValues.Add("Health", BasicStats.Health.ToString("N0")); dictValues.Add("Strength", BasicStats.Strength.ToString("N0")); dictValues.Add("Agility", string.Format("{0:0}*Provides {1:P} crit chance", BasicStats.Agility, StatConversion.GetCritFromAgility(BasicStats.Agility, CharacterClass.DeathKnight))); dictValues.Add("Attack Power", attackPower.ToString("N0")); dictValues.Add("Crit Rating", string.Format("{0:0}*Provides {1:P} crit chance", critRating, StatConversion.GetCritFromRating(critRating, CharacterClass.DeathKnight))); dictValues.Add("Hit Rating", string.Format("{0:0}*Negates {1:P} melee miss / {2:P} spell miss", hitRating, StatConversion.GetPhysicalHitFromRating(hitRating, CharacterClass.DeathKnight), StatConversion.GetSpellHitFromRating(hitRating, CharacterClass.DeathKnight))); dictValues.Add("Expertise", string.Format("{0:0.00} / {1:0.00}*Negates {2:P} / {3:P} dodge chance", MHExpertise, OHExpertise, StatConversion.GetDodgeParryReducFromExpertise(MHExpertise), StatConversion.GetDodgeParryReducFromExpertise(OHExpertise))); dictValues.Add("Haste Rating", string.Format("{0:0}*Increases attack speed by {1:P}", BasicStats.HasteRating, StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.DeathKnight))); dictValues.Add("Armor Penetration Rating", armorPenetrationRating.ToString("N0")); dictValues.Add("Armor", BasicStats.Armor.ToString("N0")); dictValues.Add("Resilience", BasicStats.Resilience.ToString("F0")); dictValues.Add("Weapon Damage", MHWeaponDamage.ToString("N2") + " / " + OHWeaponDamage.ToString("N2")); dictValues.Add("Attack Speed", MHAttackSpeed.ToString("N2") + " / " + OHAttackSpeed.ToString("N2")); dictValues.Add("Crit Chance", string.Format("{0:P}", CritChance)); dictValues.Add("Avoided Attacks", string.Format("{0:P}*{1:P} Dodged, {2:P} Missed", AvoidedAttacks, DodgedAttacks, MissedAttacks)); dictValues.Add("Enemy Mitigation", string.Format("{0:P}*{1:0} effective enemy armor", EnemyMitigation, EffectiveArmor)); dictValues.Add("BCB", string.Format("{0:N2}*{1:P}", BCBDPS, (float)BCBDPS / DPSPoints)); dictValues.Add("Blood Plague", string.Format("{0:N2}*{1:P}", BloodPlagueDPS, (float)BloodPlagueDPS / DPSPoints)); dictValues.Add("Blood Strike", string.Format("{0:N2}*{1:P}", BloodStrikeDPS, (float)BloodStrikeDPS / DPSPoints)); dictValues.Add("Death Coil", string.Format("{0:N2}*{1:P}", DeathCoilDPS, (float)DeathCoilDPS / DPSPoints)); dictValues.Add("DRW", string.Format("{0:N2}*{1:P}, wait for " + DRWStats + " proc", DRWDPS, (float)DRWDPS / DPSPoints)); dictValues.Add("Frost Fever", string.Format("{0:N2}*{1:P}", FrostFeverDPS, (float)FrostFeverDPS / DPSPoints)); dictValues.Add("Frost Strike", string.Format("{0:N2}*{1:P}", FrostStrikeDPS, (float)FrostStrikeDPS / DPSPoints)); dictValues.Add("Gargoyle", string.Format("{0:N2}*{1:P}", GargoyleDPS, (float)GargoyleDPS / DPSPoints)); dictValues.Add("Heart Strike", string.Format("{0:N2}*{1:P}", HeartStrikeDPS, (float)HeartStrikeDPS / DPSPoints)); dictValues.Add("Howling Blast", string.Format("{0:N2}*{1:P}", HowlingBlastDPS, (float)HowlingBlastDPS / DPSPoints)); dictValues.Add("Icy Touch", string.Format("{0:N2}*{1:P}", IcyTouchDPS, (float)IcyTouchDPS / DPSPoints)); dictValues.Add("Necrosis", string.Format("{0:N2}*{1:P}", NecrosisDPS, (float)NecrosisDPS / DPSPoints)); dictValues.Add("Obliterate", string.Format("{0:N2}*{1:P}", ObliterateDPS, (float)ObliterateDPS / DPSPoints)); dictValues.Add("Death Strike", string.Format("{0:N2}*{1:P}", DeathStrikeDPS, (float)DeathStrikeDPS / DPSPoints)); dictValues.Add("Plague Strike", string.Format("{0:N2}*{1:P}", PlagueStrikeDPS, (float)PlagueStrikeDPS / DPSPoints)); dictValues.Add("Scourge Strike", string.Format("{0:N2}*{1:P}", ScourgeStrikeDPS, (float)ScourgeStrikeDPS / DPSPoints)); dictValues.Add("Unholy Blight", string.Format("{0:N2}*{1:P}", UnholyBlightDPS, (float)UnholyBlightDPS / DPSPoints)); dictValues.Add("Wandering Plague", string.Format("{0:N2}*{1:P}", WanderingPlagueDPS, (float)WanderingPlagueDPS / DPSPoints)); dictValues.Add("White", string.Format("{0:N2}*{1:P}", WhiteDPS, (float)WhiteDPS / DPSPoints)); dictValues.Add("Ghoul", string.Format("{0:N2}*{1:P}", GhoulDPS, (float)GhoulDPS / DPSPoints)); dictValues.Add("Bloodworms", string.Format("{0:N2}*{1:P}", BloodwormsDPS, (float)BloodwormsDPS / DPSPoints)); dictValues.Add("Other", string.Format("{0:N2}*{1:P}", OtherDPS, (float)OtherDPS / DPSPoints)); dictValues.Add("Total DPS", DPSPoints.ToString("N2")); return(dictValues); }
public override Dictionary <string, string> GetCharacterDisplayCalculationValues() { Dictionary <string, string> dictValues = new Dictionary <string, string>(); try { dictValues.Add("Overall Points", OverallPoints.ToString()); dictValues.Add("DPS Points", DPSPoints.ToString()); dictValues.Add("Survivability Points", SurvivabilityPoints.ToString()); float baseMiss = StatConversion.WHITE_MISS_CHANCE_CAP[TargetLevel - 85] - BasicStats.PhysicalHit; float baseDodge = StatConversion.WHITE_DODGE_CHANCE_CAP[TargetLevel - 85] - StatConversion.GetDodgeParryReducFromExpertise(BasicStats.Expertise); float capMiss = (float)Math.Ceiling(baseMiss * StatConversion.RATING_PER_PHYSICALHIT); float capDodge = (float)Math.Ceiling(baseDodge * 400f * StatConversion.RATING_PER_EXPERTISE); string tipMiss = string.Empty; if (BasicStats.HitRating > capMiss) { tipMiss = string.Format("*Hit Rating %: {0}%\nOver the cap by {1} Hit Rating", StatConversion.GetPhysicalHitFromRating(BasicStats.HitRating) * 100, BasicStats.HitRating - capMiss); } else if (BasicStats.HitRating < capMiss) { tipMiss = string.Format("*Hit Rating %: {0}%\nUnder the cap by {1} Hit Rating", StatConversion.GetPhysicalHitFromRating(BasicStats.HitRating) * 100, capMiss - BasicStats.HitRating); } else { tipMiss = string.Format("*Hit Rating %: {0}%\nExactly at the cap", StatConversion.GetPhysicalHitFromRating(BasicStats.HitRating) * 100); } string tipDodge = string.Empty; if (BasicStats.ExpertiseRating > capDodge) { tipDodge = string.Format("*Expertise Rating %: {0}%\nOver the cap by {1} Expertise Rating", StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating) * 0.25f, BasicStats.ExpertiseRating - capDodge); } else if (BasicStats.ExpertiseRating < capDodge) { tipDodge = string.Format("*Expertise Rating %: {0}%\nUnder the cap by {1} Expertise Rating", StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating) * 0.25f, capDodge - BasicStats.ExpertiseRating); } else { tipDodge = string.Format("*Expertise Rating %: {0}%\nExactly at the cap", StatConversion.GetExpertiseFromRating(BasicStats.ExpertiseRating) * 0.25f); } string tipHaste = string.Format("*Haste Rating %: {0}%", StatConversion.GetPhysicalHasteFromRating(BasicStats.HasteRating, CharacterClass.Druid) * 100f); string tipMastery = string.Format("*Increases the damage done by your bleed abilities by {0}%", ((StatConversion.GetMasteryFromRating(BasicStats.MasteryRating, CharacterClass.Druid) + 8f) * 0.031f) * 100f); dictValues.Add("Health", BasicStats.Health.ToString()); dictValues.Add("Attack Power", BasicStats.AttackPower.ToString()); dictValues.Add("Agility", BasicStats.Agility.ToString()); dictValues.Add("Strength", BasicStats.Strength.ToString()); dictValues.Add("Crit Rating", BasicStats.CritRating.ToString()); dictValues.Add("Hit Rating", BasicStats.HitRating.ToString() + tipMiss); dictValues.Add("Expertise Rating", BasicStats.ExpertiseRating.ToString() + tipDodge); dictValues.Add("Mastery Rating", BasicStats.MasteryRating.ToString() + tipMastery); dictValues.Add("Haste Rating", BasicStats.HasteRating.ToString() + tipHaste); dictValues.Add("Avoided Attacks", string.Format("{0}%*{1}% Dodged, {2}% Missed", AvoidedAttacks, DodgedAttacks, MissedAttacks)); dictValues.Add("Crit Chance", CritChance.ToString() + "%"); dictValues.Add("Attack Speed", AttackSpeed.ToString() + "s"); dictValues.Add("Armor Mitigation", ArmorMitigation.ToString() + "%"); dictValues.Add("Optimal Rotation", HighestDPSRotation.ToString()); //dictValues.Add("Optimal Rotation DPS", HighestDPSRotation.DPS.ToString()); //dictValues.Add("Custom Rotation DPS", CustomRotation.DPS.ToString()); float chanceNonAvoided = 1f - (AvoidedAttacks / 100f); dictValues.Add("Melee", Abilities.MeleeStats.ToString()); dictValues.Add("Mangle", Abilities.MangleStats.ToString()); dictValues.Add("Shred", Abilities.ShredStats.ToString()); dictValues.Add("Ravage", Abilities.RavageStats.ToString()); dictValues.Add("Rake", Abilities.RakeStats.ToString()); dictValues.Add("Rip", Abilities.RipStats.ToString()); dictValues.Add("Bite", Abilities.BiteStats.ToString()); //string[] abilityStats = MeleeStats.GetStatsTexts(HighestDPSRotation.MeleeCount, 0, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration); //dictValues.Add("Melee Usage", abilityStats[0]); //dictValues.Add("Melee Stats", abilityStats[1]); //abilityStats = MangleStats.GetStatsTexts(HighestDPSRotation.MangleCount, 0, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration); //dictValues.Add("Mangle Usage", abilityStats[0]); //dictValues.Add("Mangle Stats", abilityStats[1]); //abilityStats = ShredStats.GetStatsTexts(HighestDPSRotation.ShredCount, 0, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration); //dictValues.Add("Shred Usage", abilityStats[0]); //dictValues.Add("Shred Stats", abilityStats[1]); //abilityStats = RakeStats.GetStatsTexts(HighestDPSRotation.RakeCount, 0, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration); //dictValues.Add("Rake Usage", abilityStats[0]); //dictValues.Add("Rake Stats", abilityStats[1]); //abilityStats = RipStats.GetStatsTexts(HighestDPSRotation.RipCount, 0, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration); //dictValues.Add("Rip Usage", abilityStats[0]); //dictValues.Add("Rip Stats", abilityStats[1]); //abilityStats = RoarStats.GetStatsTexts(HighestDPSRotation.RoarCount, HighestDPSRotation.RoarCP, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration); //dictValues.Add("Roar Usage", abilityStats[0]); //dictValues.Add("Roar Stats", abilityStats[1]); //abilityStats = BiteStats.GetStatsTexts(HighestDPSRotation.BiteCount, HighestDPSRotation.BiteCP, HighestDPSRotation.TotalDamage, chanceNonAvoided, Duration); //dictValues.Add("Bite Usage", abilityStats[0]); //dictValues.Add("Bite Stats", abilityStats[1]); //string attackFormat = "{0}%*Damage Per Hit: {1}, Damage Per Swing: {2}\r\n{0}% of Total Damage, {3} Damage Done"; //dictValues.Add("Melee Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.MeleeDamageTotal / HighestDPSRotation.DamageTotal, MeleeDamagePerHit, MeleeDamagePerSwing, HighestDPSRotation.MeleeDamageTotal)); //dictValues.Add("Mangle Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.MangleDamageTotal / HighestDPSRotation.DamageTotal, MangleDamagePerHit, MangleDamagePerSwing, HighestDPSRotation.MangleDamageTotal)); //dictValues.Add("Shred Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.ShredDamageTotal / HighestDPSRotation.DamageTotal, ShredDamagePerHit, ShredDamagePerSwing, HighestDPSRotation.ShredDamageTotal)); //dictValues.Add("Rake Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.RakeDamageTotal / HighestDPSRotation.DamageTotal, RakeDamagePerHit, RakeDamagePerSwing, HighestDPSRotation.RakeDamageTotal)); //dictValues.Add("Rip Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.RipDamageTotal / HighestDPSRotation.DamageTotal, RipDamagePerHit, RipDamagePerSwing, HighestDPSRotation.RipDamageTotal)); //dictValues.Add("Bite Damage", string.Empty);//.Format(attackFormat, 100f * HighestDPSRotation.BiteDamageTotal / HighestDPSRotation.DamageTotal, BiteDamagePerHit, BiteDamagePerSwing, HighestDPSRotation.BiteDamageTotal)); //string rotationDescription = string.Empty; //try //{ // rotationDescription = string.Format("{0}*Keep {1}cp Savage Roar up.\r\n{2}{3}{4}{5}Use {6} for combo points.", // HighestDPSRotation.Name.Replace(" + ", "+"), HighestDPSRotation.RoarCP, // HighestDPSRotation.Name.Contains("Rake") ? "Keep Rake up.\r\n" : "", // HighestDPSRotation.Name.Contains("Rip") ? "Keep 5cp Rip up.\r\n" : "", // HighestDPSRotation.Name.Contains("Mangle") ? "Keep Mangle up.\r\n" : "", // HighestDPSRotation.Name.Contains("Bite") ? string.Format("Use {0}cp Ferocious Bites to spend extra combo points.\r\n", HighestDPSRotation.BiteCP) : "", // HighestDPSRotation.Name.Contains("Shred") ? "Shred" : "Mangle"); //} //catch (Exception ex) //{ // ex.ToString(); //} } catch (Exception ex) { new Base.ErrorBox() { Title = "Error Getting Cat Dictionary Values", Function = "GetCharacterDisplayCalculationValues()", TheException = ex, }.Show(); } return(dictValues); }
public static float HitChance(Character character, Stats stats, int targetLevel) { float physicalHit = StatConversion.GetPhysicalHitFromRating(stats.HitRating, CharacterClass.Paladin) + stats.PhysicalHit; return(Math.Min(1f, (1f - StatConversion.WHITE_MISS_CHANCE_CAP[targetLevel - 80]) + physicalHit)); }