Пример #1
0
 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)));
 }
Пример #2
0
 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)));
 }
Пример #3
0
        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);
             */
        }
Пример #4
0
        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
        }