public static float BonusCritPercentage(Player player) { return(Math.Max(0.0f, Math.Min(1.0f, StatConversion.GetPhysicalCritFromRating(player.Stats.CritRating, CharacterClass.Warrior) + StatConversion.GetPhysicalCritFromAgility(player.Stats.Agility, CharacterClass.Warrior) + player.Stats.PhysicalCrit))); }
public static float BonusCritPercentage(Character character, Stats stats, int targetLevel) { return(Math.Max(0.0f, Math.Min(1.0f, StatConversion.GetPhysicalCritFromRating(stats.CritRating, CharacterClass.Warrior) + StatConversion.GetPhysicalCritFromAgility(stats.Agility, CharacterClass.Warrior) + stats.PhysicalCrit))); }
public static float BonusCritPercentage(Character character, Stats stats) { CalculationOptionsProtWarr calcOpts = character.CalculationOptions as CalculationOptionsProtWarr; return(Math.Max(0.0f, Math.Min(1.0f, StatConversion.GetPhysicalCritFromRating(stats.CritRating, CharacterClass.Warrior) + StatConversion.GetPhysicalCritFromAgility(stats.Agility, CharacterClass.Warrior) + stats.PhysicalCrit - StatConversion.NPC_LEVEL_CRIT_MOD[calcOpts.TargetLevel - character.Level]))); /* * if ((calcOpts.TargetLevel - character.Level) < 3) * // This formula may or may not be accurate anymore, as the modifier on +1/2 mobs is untested * return Math.Min(1.0f, (((stats.CritRating * ProtWarr.CritRatingToCrit) + (stats.Agility * ProtWarr.AgilityToCrit) * - LevelModifier(character)) / 100.0f) + stats.PhysicalCrit); * else * // 4.8% critical hit supression as tested on bosses * return Math.Min(1.0f, (((stats.CritRating * ProtWarr.CritRatingToCrit) + (stats.Agility * ProtWarr.AgilityToCrit) * - 4.8f) / 100.0f) + stats.PhysicalCrit); */ }
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 }