Example #1
0
        public CombatTable(Character c, CharacterCalculationsDPSDK calcs, Stats stats, CalculationOptionsDPSDK calcOpts /*, Item additionalItem*/)
        {
            character           = c;
            this.calcs          = calcs;
            talents             = character.DeathKnightTalents;
            this.calcOpts       = calcOpts;
            this.stats          = stats;
            this.additionalItem = null;
            totalMeleeAbilities = 0f;
            totalSpellAbilities = 0f;


/*#if RAWR3
 *          if (calcOpts.rotation == null)
 *          {
 *              calcOpts.rotation = new Rotation();
 *              calcOpts.rotation.setRotation(Rotation.Type.Blood);
 *          }
 #endif*/
            float DWExtraHits = 1f;// +talents.ThreatOfThassarian / 3f;

            totalMeleeAbilities = (float)(calcOpts.rotation.PlagueStrike * DWExtraHits + calcOpts.rotation.ScourgeStrike +
                                          calcOpts.rotation.Obliterate * DWExtraHits + calcOpts.rotation.BloodStrike * DWExtraHits + calcOpts.rotation.HeartStrike +
                                          calcOpts.rotation.FrostStrike * DWExtraHits + calcOpts.rotation.DeathStrike * DWExtraHits);

            totalSpellAbilities = (float)(calcOpts.rotation.DeathCoil + calcOpts.rotation.IcyTouch + calcOpts.rotation.HowlingBlast + calcOpts.rotation.Pestilence + calcOpts.rotation.Horn + calcOpts.rotation.GhoulFrenzy);

            hitBonus = .01f * (float)talents.NervesOfColdSteel;
            Weapons();
            CritsAndResists();
        }
Example #2
0
File: DKDPS.cs Project: rakot/rawr
        public void DPSDK_Rotation()
        {
            Rawr.DPSDK.CharacterCalculationsDPSDK CalcDPSDK = new Rawr.DPSDK.CharacterCalculationsDPSDK();
            CalculationOptionsDPSDK calcOpts = new CalculationOptionsDPSDK();

            Rawr.DK.StatsDK TotalStats = new Rawr.DK.StatsDK();

            Rawr.DK.DKCombatTable ct  = new Rawr.DK.DKCombatTable(m_char, TotalStats, CalcDPSDK, calcOpts, m_char.BossOptions);
            Rawr.DK.Rotation      rot = new Rawr.DK.Rotation(ct, false);
            rot.PRE_OneEachRot();
            rot.ReportRotation();
            Assert.IsTrue(rot.m_DPS > 0, "rotation OneEach produces 0 DPS");
            rot.PRE_Frost();
            rot.ReportRotation();
            Assert.IsTrue(rot.m_DPS > 0, "rotation Frost produces 0 DPS");
            rot.PRE_Unholy();
            rot.ReportRotation();
            Assert.IsTrue(rot.m_DPS > 0, "rotation Unholy produces 0 DPS");
            rot.PRE_BloodDiseased();
            rot.ReportRotation();
            Assert.IsTrue(rot.m_DPS > 0, "rotation BloodDiseased produces 0 DPS");
            //rot.Solver();
            //rot.ReportRotation();
            //Assert.IsTrue(rot.m_DPS > 0, "rotation solver produces 0 DPS");
        }
Example #3
0
        public void DPSDK_Rotation()
        {
            Rawr.DPSDK.CharacterCalculationsDPSDK CalcDPSDK = new Rawr.DPSDK.CharacterCalculationsDPSDK();
            CalculationOptionsDPSDK calcOpts = new CalculationOptionsDPSDK();
            Rawr.DK.StatsDK TotalStats = new Rawr.DK.StatsDK();

            Rawr.DK.DKCombatTable ct = new Rawr.DK.DKCombatTable(m_char, TotalStats, CalcDPSDK, calcOpts, m_char.BossOptions);
            Rawr.DK.Rotation rot = new Rawr.DK.Rotation(ct, false);
            rot.PRE_OneEachRot();
            rot.ReportRotation();
            Assert.IsTrue(rot.m_DPS > 0, "rotation OneEach produces 0 DPS");
            rot.PRE_Frost();
            rot.ReportRotation();
            Assert.IsTrue(rot.m_DPS > 0, "rotation Frost produces 0 DPS");
            rot.PRE_Unholy();
            rot.ReportRotation();
            Assert.IsTrue(rot.m_DPS > 0, "rotation Unholy produces 0 DPS");
            rot.PRE_BloodDiseased();
            rot.ReportRotation();
            Assert.IsTrue(rot.m_DPS > 0, "rotation BloodDiseased produces 0 DPS");
            //rot.Solver();
            //rot.ReportRotation();
            //Assert.IsTrue(rot.m_DPS > 0, "rotation solver produces 0 DPS");
            
        }
Example #4
0
        public DRW(CombatTable combatTable, CharacterCalculationsDPSDK calcs, CalculationOptionsDPSDK calcOpts, Stats stats,
                   Character character, DeathKnightTalents talents)
        {
            bool DW = false;

            float dpsWhite              = 0f;
            float dpsBCB                = 0f;
            float dpsNecrosis           = 0f;
            float dpsDeathCoil          = 0f;
            float dpsIcyTouch           = 0f;
            float dpsPlagueStrike       = 0f;
            float dpsFrostFever         = 0f;
            float dpsBloodPlague        = 0f;
            float dpsDeathStrike        = 0f;
            float dpsHeartStrike        = 0f;
            float dpsWPFromFF           = 0f;
            float dpsWPFromBP           = 0f;
            float dpsWhiteMinusGlancing = 0f;
            float dpsWhiteBeforeArmor   = 0f;

            float IcyTouchAPMult    = 0.1f;
            float FrostFeverAPMult  = 0.055f;
            float BloodPlagueAPMult = 0.055f;
            float DeathCoilAPMult   = 0.15f;

            float OHMult = 0.5f;

            int   targetLevel = calcOpts.TargetLevel;
            float arpBuffs    = talents.BloodGorged * 2f / 100;
            float mitigation  = StatConversion.GetArmorDamageReduction(character.Level, calcOpts.BossArmor, stats.ArmorPenetration, arpBuffs, stats.ArmorPenetrationRating);

            mitigation = 1 - mitigation;
            float MHDPS = 0f, OHDPS = 0f;

            #region White Dmg
            {
                #region Main Hand
                {
                    float dpsMHglancing    = (StatConversion.WHITE_GLANCE_CHANCE_CAP[targetLevel - 80] * combatTable.MH.DPS) * 0.7f;
                    float dpsMHBeforeArmor = ((combatTable.MH.DPS * (1f - calcs.AvoidedAttacks - StatConversion.WHITE_GLANCE_CHANCE_CAP[targetLevel - 80])) * (1f + combatTable.physCrits)) + dpsMHglancing;
                    dpsWhiteMinusGlancing = dpsMHBeforeArmor - dpsMHglancing;
                    dpsWhiteBeforeArmor   = dpsMHBeforeArmor;
                    MHDPS = dpsMHBeforeArmor * mitigation;
                }
                #endregion

                #region Off Hand
                if (DW || (character.MainHand == null && character.OffHand != null))
                {
                    float dpsOHglancing    = (StatConversion.WHITE_GLANCE_CHANCE_CAP[targetLevel - 80] * combatTable.OH.DPS) * 0.7f;
                    float dpsOHBeforeArmor = ((combatTable.OH.DPS * (1f - calcs.AvoidedAttacks - StatConversion.WHITE_GLANCE_CHANCE_CAP[targetLevel - 80])) * (1f + combatTable.physCrits)) + dpsOHglancing;
                    dpsOHBeforeArmor      *= OHMult;
                    dpsWhiteMinusGlancing += dpsOHBeforeArmor - dpsOHglancing;
                    dpsWhiteBeforeArmor   += dpsOHBeforeArmor;
                    OHDPS = dpsOHBeforeArmor * mitigation;
                }
                #endregion

                dpsWhite = MHDPS + OHDPS;
            }
            #endregion

            #region Necrosis
            {
                dpsNecrosis = dpsWhiteMinusGlancing * (.04f * (float)talents.Necrosis); // doesn't proc off Glancings
            }
            #endregion

            #region Blood Caked Blade
            {
                float dpsMHBCB = 0f;
                if (combatTable.MH.damage != 0)
                {
                    float MHBCBDmg = (float)(combatTable.MH.damage * (.25f + .125f * calcOpts.rotation.AvgDiseaseMult));
                    dpsMHBCB = MHBCBDmg / combatTable.MH.hastedSpeed;
                }
                dpsBCB  = dpsMHBCB;
                dpsBCB *= .1f * (float)talents.BloodCakedBlade;
            }
            #endregion

            #region Death Coil
            {
                if (calcOpts.rotation.DeathCoil > 0f)
                {
                    float DCCD  = 1;
                    float DCDmg = 443f + (DeathCoilAPMult * stats.AttackPower);
                    dpsDeathCoil = DCDmg / DCCD;
                    float DCCritDmgMult = .5f * (2f + stats.BonusCritMultiplier);
                    float DCCrit        = 1f + ((combatTable.spellCrits + stats.BonusDeathCoilCrit) * DCCritDmgMult);
                    dpsDeathCoil *= DCCrit;

                    dpsDeathCoil *= 1f + (.05f * (float)talents.Morbidity);
                }
            }
            #endregion

            #region Icy Touch
            {
                if (calcOpts.rotation.IcyTouch > 0f)
                {
                    float ITCD  = 1;
                    float ITDmg = 236f + (IcyTouchAPMult * stats.AttackPower) + stats.BonusIcyTouchDamage;
                    ITDmg      *= 1f + .1f * (float)talents.ImprovedIcyTouch;
                    dpsIcyTouch = ITDmg / ITCD;
                    float ITCritDmgMult = .5f * (2f + stats.CritBonusDamage + stats.BonusCritMultiplier);
                    float ITCrit        = 1f + (Math.Min((combatTable.spellCrits + (.05f * (float)talents.Rime)), 1f) * ITCritDmgMult);
                    dpsIcyTouch *= ITCrit;
                }
            }
            #endregion

            #region Plague Strike
            {
                if (calcOpts.rotation.PlagueStrike > 0f)
                {
                    float PSCD  = 1;
                    float PSDmg = (combatTable.MH.baseDamage + ((stats.AttackPower / 14f) *
                                                                combatTable.normalizationFactor)) * 0.5f + 189f;
                    dpsPlagueStrike = PSDmg / PSCD;
                    float PSCritDmgMult = 1f + (.15f * (float)talents.ViciousStrikes) + stats.BonusCritMultiplier;
                    float PSCrit        = 1f + ((combatTable.physCrits + (.03f * (float)talents.ViciousStrikes) +
                                                 stats.BonusPlagueStrikeCrit) * PSCritDmgMult);

                    dpsPlagueStrike *= PSCrit;
                    dpsPlagueStrike *= 1f + (.1f * (float)talents.Outbreak);
                }
            }
            #endregion

            #region Frost Fever
            {
                if (calcOpts.rotation.IcyTouch > 0f ||
                    (talents.GlyphofHowlingBlast && calcOpts.rotation.HowlingBlast > 0f) ||
                    (talents.GlyphofDisease && calcOpts.rotation.Pestilence > 0f))
                {
                    float FFDmg = FrostFeverAPMult * stats.AttackPower + 25.6f;
                    dpsFrostFever  = FFDmg;
                    dpsFrostFever *= 1.15f;     // Patch 3.2: Diseases hit 15% harder.
                    dpsWPFromFF    = dpsFrostFever * combatTable.physCrits;
                }
            }
            #endregion

            #region Blood Plague
            {
                if (calcOpts.rotation.PlagueStrike > 0f || talents.GlyphofDisease)
                {
                    float BPDmg = BloodPlagueAPMult * stats.AttackPower + 31.1f;
                    dpsBloodPlague  = BPDmg;
                    dpsBloodPlague *= 1.15f; // Patch 3.2: Diseases hit 15% harder.
                    dpsWPFromBP     = dpsBloodPlague * combatTable.physCrits;
                }
            }
            #endregion

            #region Death Strike
            {
                if (calcOpts.rotation.DeathStrike > 0f)
                {
                    float DSCD = 1;
                    // TODO: This should be changed to make use of the new glyph stats:
                    float DSDmg = ((combatTable.MH.baseDamage + ((stats.AttackPower / 14f) * combatTable.normalizationFactor)) * 0.75f) + 222.75f;
                    DSDmg         *= 1f + 0.15f * (float)talents.ImprovedDeathStrike;
                    dpsDeathStrike = DSDmg / DSCD;
                    float DSCritDmgMult = 1f + (.15f * (float)talents.MightOfMograine) + stats.BonusCritMultiplier;
                    float DSCrit        = 1f + ((combatTable.physCrits +
                                                 (.03f * (float)talents.ImprovedDeathStrike) +
                                                 stats.BonusDeathStrikeCrit) * DSCritDmgMult);
                    dpsDeathStrike *= DSCrit;
                }
            }
            #endregion

            #region Heart Strike
            {
                if (talents.HeartStrike > 0 && calcOpts.rotation.HeartStrike > 0f)
                {
                    float HSCD  = 1;
                    float HSDmg = ((combatTable.MH.baseDamage + ((stats.AttackPower / 14f) * combatTable.normalizationFactor)) *
                                   0.5f) + 368f;
                    HSDmg         *= 1f + 0.1f * (float)calcOpts.rotation.AvgDiseaseMult * (1f + stats.BonusPerDiseaseHeartStrikeDamage);
                    dpsHeartStrike = HSDmg / HSCD;
                    //float HSCrit = 1f + combatTable.physCrits + ( .03f * (float)talents.Subversion );
                    float HSCritDmgMult = 1f + (.15f * (float)talents.MightOfMograine) + stats.BonusCritMultiplier;
                    float HSCrit        = 1f + ((combatTable.physCrits + (.03f * (float)talents.Subversion)) * HSCritDmgMult);
                    dpsHeartStrike  = (dpsHeartStrike) * HSCrit;
                    dpsHeartStrike *= 1f + (.15f * (float)talents.BloodyStrikes);
                }
            }
            #endregion

            float BCBMult          = 1f;
            float BloodPlagueMult  = 1f;
            float DeathCoilMult    = 1f;
            float FrostFeverMult   = 1f;
            float HeartStrikeMult  = 1f;
            float IcyTouchMult     = 1f;
            float NecrosisMult     = 1f;
            float DeathStrikeMult  = 1f;
            float PlagueStrikeMult = 1f;
            float WhiteMult        = 1f;

            float spellPowerMult      = 1f + stats.BonusSpellPowerMultiplier;
            float frostSpellPowerMult = 1f + stats.BonusSpellPowerMultiplier + Math.Max((stats.BonusFrostDamageMultiplier - stats.BonusShadowDamageMultiplier), 0f);
            float partialResist       = 0.94f;
            float physPowerMult       = 1f;

            #region Apply Physical Mitigation
            {
                float physMit = mitigation;
                physMit *= 1f + (!DW ? .02f * talents.TwoHandedWeaponSpecialization : 0f);

                dpsBCB           *= physMit;
                dpsHeartStrike   *= physMit;
                dpsDeathStrike   *= physMit;
                dpsPlagueStrike  *= physMit;
                WhiteMult        += physPowerMult - 1f;
                BCBMult          += physPowerMult - 1f;
                HeartStrikeMult  += physPowerMult - 1f;
                DeathStrikeMult  += physPowerMult - 1f;
                PlagueStrikeMult += physPowerMult - 1f;
            }
            #endregion

            #region Apply Magical Mitigation
            {
                // some of this applies to necrosis, I wonder if it is ever accounted for
                float magicMit = partialResist /** combatTable.spellResist*/;
                // magicMit = 1f - magicMit;

                dpsNecrosis    *= magicMit;
                dpsBloodPlague *= magicMit;
                dpsDeathCoil   *= magicMit * (1f - combatTable.spellResist);
                dpsFrostFever  *= magicMit;
                dpsIcyTouch    *= magicMit;


                NecrosisMult    += spellPowerMult - 1f;
                BloodPlagueMult += spellPowerMult - 1f;
                DeathCoilMult   += spellPowerMult - 1f;
                FrostFeverMult  += frostSpellPowerMult - 1f;
                IcyTouchMult    += frostSpellPowerMult - 1f;
            }
            #endregion


            #region Apply Multi-Ability Talent Multipliers
            {
                float BloodyVengeanceMult = .03f * (float)talents.BloodyVengeance;
                BCBMult          *= 1 + BloodyVengeanceMult;
                HeartStrikeMult  *= 1 + BloodyVengeanceMult;
                DeathStrikeMult  *= 1 + BloodyVengeanceMult;
                PlagueStrikeMult *= 1 + BloodyVengeanceMult;
                WhiteMult        *= 1 + BloodyVengeanceMult;

                float HysteriaCoeff = .2f / 2f; // current uptime is 50% for now
                float HysteriaMult  = HysteriaCoeff * (float)talents.Hysteria;
                BCBMult          *= 1 + HysteriaMult;
                HeartStrikeMult  *= 1 + HysteriaMult;
                DeathStrikeMult  *= 1 + HysteriaMult;
                PlagueStrikeMult *= 1 + HysteriaMult;
                WhiteMult        *= 1 + HysteriaMult;

                float BlackIceMult = .02f * (float)talents.BlackIce;
                FrostFeverMult  *= 1 + BlackIceMult;
                IcyTouchMult    *= 1 + BlackIceMult;
                DeathCoilMult   *= 1 + BlackIceMult;
                BloodPlagueMult *= 1 + BlackIceMult;

                float CryptFeverMult = .1f * (float)talents.CryptFever;
                float CryptFeverBuff = stats.BonusDiseaseDamageMultiplier;
                CryptFeverMult   = Math.Max(CryptFeverMult, CryptFeverBuff);
                FrostFeverMult  *= 1 + CryptFeverMult;
                BloodPlagueMult *= 1 + CryptFeverMult;
            }
            #endregion



            dpsDancingRuneWeapon = dpsWhite * WhiteMult * 17f +
                                   dpsBCB * BCBMult * 17f +
                                   dpsNecrosis * NecrosisMult * 17f +
                                   dpsDeathCoil * DeathCoilMult +
                                   dpsIcyTouch * IcyTouchMult +
                                   dpsPlagueStrike * PlagueStrikeMult +
                                   dpsFrostFever * (5f + talents.Epidemic) * FrostFeverMult +
                                   dpsBloodPlague * (5f + talents.Epidemic) * BloodPlagueMult +
                                   dpsDeathStrike * DeathStrikeMult * (talents.GlyphofDancingRuneWeapon ? 1f : 0f) +
                                   dpsHeartStrike * HeartStrikeMult * (5f + (talents.GlyphofDancingRuneWeapon ? 2f : 0f));
            dpsDancingRuneWeapon *= 0.5f;
        }
Example #5
0
 public DKCombatTable(Character c, StatsDK stats, CharacterCalculationsBase calcs, ICalculationOptionBase calcOpts, BossOptions bossOpts)
 {
     m_CState = new CombatState();
     if (c != null) {
         m_CState.m_Char = c;
         m_CState.m_Talents = c.DeathKnightTalents;
         m_CState.m_Spec = CalculationsDPSDK.GetSpec(c.DeathKnightTalents);
     }
     m_CState.m_Stats = stats;
     // TODO: Put in check here for null.
     m_Calcs = calcs as CharacterCalculationsDPSDK;
     m_Opts = calcOpts as CalculationOptionsDPSDK;
     m_CState.m_Presence = Presence.Frost;
     if (calcOpts != null && m_Opts == null) {
         //throw new Exception("Opts not converted properly.");
         m_Opts = new CalculationOptionsDPSDK();
     }
     try { m_CState.m_Presence = m_Opts.presence; } catch { } // pass  stay w/ default
     m_BO = bossOpts;
     if (m_BO == null) { m_BO = new BossOptions(); }
     // JOTHAY TODO: Kind of an Ugly Hack to do this, but it will give them a value
     m_CState.m_NumberOfTargets = m_BO.MultiTargs ? m_BO.DynamicCompiler_MultiTargs.GetAverageTargetGroupSize(m_BO.BerserkTimer) : 1f;
     //
     m_CState.m_bAttackingFromBehind = m_BO.InBack;
     m_CState.fBossArmor = m_BO.Armor;
     SetupExpertise(c);
 }
        /// <summary>
        /// GetCharacterCalculations is the primary method of each model, where a majority of the calculations
        /// and formulae will be used. GetCharacterCalculations should call GetCharacterStats(), and based on
        /// those total stats for the character, and any calculationoptions on the character, perform all the 
        /// calculations required to come up with the final calculations defined in 
        /// CharacterDisplayCalculationLabels, including an Overall rating, and all Sub ratings defined in 
        /// SubPointNameColors.
        /// </summary>
        /// <param name="character">The character to perform calculations for.</param>
        /// <param name="additionalItem">An additional item to treat the character as wearing.
        /// This is used for gems, which don't have a slot on the character to fit in, so are just
        /// added onto the character, in order to get gem calculations.</param>
        /// <returns>A custom CharacterCalculations object which inherits from CharacterCalculationsBase,
        /// containing all of the final calculations defined in CharacterDisplayCalculationLabels. See
        /// CharacterCalculationsBase comments for more details.</returns>
        public override CharacterCalculationsBase GetCharacterCalculations(Character character, Item additionalItem, bool referenceCalculation, bool significantChange, bool needsDisplayCalculations)
        {
            // First things first, we need to ensure that we aren't using bad data
            CharacterCalculationsDPSDK calc = new CharacterCalculationsDPSDK();
            if (character == null) { return calc; }
            CalculationOptionsDPSDK calcOpts = character.CalculationOptions as CalculationOptionsDPSDK;
            if (calcOpts == null) { return calc; }
            //
            StatsDK stats = new StatsDK();
            DeathKnightTalents talents = character.DeathKnightTalents;

            // Setup initial Boss data.
            // Get Boss from BossOptions data.
            BossOptions hBossOptions = character.BossOptions;
            if (hBossOptions == null) hBossOptions = new BossOptions(); 
            int targetLevel = hBossOptions.Level;

            stats = GetCharacterStats(character, additionalItem) as StatsDK;
            calc.BasicStats = stats.Clone() as StatsDK;
            ApplyRatings(calc.BasicStats);

            DKCombatTable combatTable = new DKCombatTable(character, calc.BasicStats, calc, calcOpts, hBossOptions);
            if (needsDisplayCalculations) combatTable.PostAbilitiesSingleUse(false);
            Rotation rot = new Rotation(combatTable);
            Rotation.Type RotT = rot.GetRotationType(character.DeathKnightTalents);

            // TODO: Fix this so we're not using pre-set rotations/priorities.
            if (RotT == Rotation.Type.Frost)
                rot.PRE_Frost();
            else if (RotT == Rotation.Type.Unholy)
                rot.PRE_Unholy();
            else if (RotT == Rotation.Type.Blood)
                rot.PRE_BloodDiseased();
            else
                rot.Solver();

            //TODO: This may need to be handled special since it's to update stats.
            AccumulateSpecialEffectStats(stats, character, calcOpts, combatTable, rot); // Now add in the special effects.
            ApplyRatings(stats);
            #region Cinderglacier
            if (stats.CinderglacierProc > 0)
            {
                // How many frost & shadow abilities do we have per min.?
                float CGabs = ((rot.m_FrostSpecials + rot.m_ShadowSpecials) / rot.CurRotationDuration) * 60f;
                float effCG = 0;
                if (CGabs > 0)
                    // Since 3 of those abilities get the 20% buff
                    // Get the effective ammount of CinderGlacier that would be applied across each ability.
                    // it is a proc after all.
                    effCG = 3 / CGabs;
                stats.BonusFrostDamageMultiplier += (.2f * effCG);
                stats.BonusShadowDamageMultiplier += (.2f * effCG);
            }
            #endregion

            // refresh w/ updated stats.
            combatTable = new DKCombatTable(character, stats, calc, calcOpts, hBossOptions);
            combatTable.PostAbilitiesSingleUse(false);
            rot = new Rotation(combatTable);
            RotT = rot.GetRotationType(character.DeathKnightTalents);

            // TODO: Fix this so we're not using pre-set rotations.
            if (RotT == Rotation.Type.Frost)
                rot.PRE_Frost();
            else if (RotT == Rotation.Type.Unholy)
                rot.PRE_Unholy();
            else if (RotT == Rotation.Type.Blood)
                rot.PRE_BloodDiseased();
            else
                rot.Solver();

            #region Pet Handling 
            // For UH, this is valid.  For Frost/Blood, we need to have this be 1/3 of the value since it has an uptime of 1 min for every 3.
            float ghouluptime = 1f;
            calc.dpsSub[(int)DKability.Gargoyle] = 0;
            if (RotT != Rotation.Type.Unholy) ghouluptime = 1f / 3f;
            else 
            {
                // Unholy will also have gargoyles.
                Pet Gar = new Gargoyle(stats, talents, hBossOptions, calcOpts.presence);
                float garuptime = .5f/3f;
                calc.dpsSub[(int)DKability.Gargoyle] = Gar.DPS * garuptime;
                calc.damSub[(int)DKability.Gargoyle] = Gar.DPS * 30f; // Duration 30 seconds.
            }
            Pet ghoul = new Ghoul(stats, talents, hBossOptions, calcOpts.presence);
            calc.dpsSub[(int)DKability.Ghoul] = ghoul.DPS * ghouluptime;
            calc.damSub[(int)DKability.Ghoul] = ghoul.DPS * 60f; // Duration 1 min.

            #endregion

            // Stats as Fire damage additive value proc.
            if (stats.ArcaneDamage > 1) calc.dpsSub[(int)DKability.OtherArcane] += stats.ArcaneDamage;
            if (stats.FireDamage > 1) calc.dpsSub[(int)DKability.OtherFire] += stats.FireDamage;
            if (stats.FrostDamage > 1) calc.dpsSub[(int)DKability.OtherFrost] += stats.FrostDamage;
            if (stats.HolyDamage > 1) calc.dpsSub[(int)DKability.OtherHoly] += stats.HolyDamage;
            if (stats.NatureDamage > 1) calc.dpsSub[(int)DKability.OtherNature] += stats.NatureDamage;
            if (stats.ShadowDamage > 1) calc.dpsSub[(int)DKability.OtherShadow] += stats.ShadowDamage;
            // Fire Dam Multiplier.

            calc.RotationTime = rot.CurRotationDuration;
            calc.Blood = rot.m_BloodRunes;
            calc.Frost = rot.m_FrostRunes;
            calc.Unholy = rot.m_UnholyRunes;
            calc.Death = rot.m_DeathRunes;
            calc.RP = rot.m_RunicPower;
            calc.FreeRERunes = rot.m_FreeRunesFromRE;

            calc.EffectiveArmor = stats.Armor;

            calc.OverallPoints = calc.DPSPoints = rot.m_DPS 
                // Add in supplemental damage from other sources
                + calc.dpsSub[(int)DKability.Ghoul] 
                + calc.dpsSub[(int)DKability.Gargoyle]
                + calc.dpsSub[(int)DKability.OtherArcane] + calc.dpsSub[(int)DKability.OtherFire] + calc.dpsSub[(int)DKability.OtherFrost] + calc.dpsSub[(int)DKability.OtherHoly] + calc.dpsSub[(int)DKability.OtherNature] + calc.dpsSub[(int)DKability.OtherShadow];
            if (needsDisplayCalculations)
            {
                AbilityDK_Base a = rot.GetAbilityOfType(DKability.White);
                if (rot.ml_Rot.Count > 1)
                {
                    AbilityDK_Base b;
                    b = rot.GetAbilityOfType(DKability.ScourgeStrike);
                    if (b == null) b = rot.GetAbilityOfType(DKability.FrostStrike);
                    if (b == null) b = rot.GetAbilityOfType(DKability.DeathStrike);
                    calc.YellowHitChance = b.HitChance;
                }
                calc.WhiteHitChance = (a == null ? 0 : a.HitChance + a.CritChance + .23f); // + glancing
                calc.MHWeaponDPS = (a == null ? 0 : rot.GetAbilityOfType(DKability.White).DPS);
                if (null != combatTable.MH)
                {
                    calc.MHWeaponDamage = combatTable.MH.damage;
                    calc.MHAttackSpeed = combatTable.MH.hastedSpeed;
                    calc.DodgedAttacks = combatTable.MH.chanceDodged;
                    calc.AvoidedAttacks = combatTable.MH.chanceDodged;
                    if (!hBossOptions.InBack)
                        calc.AvoidedAttacks += combatTable.MH.chanceParried;
                    calc.MissedAttacks = combatTable.MH.chanceMissed;
                }
                if (null != combatTable.OH)
                {
                    a = rot.GetAbilityOfType(DKability.WhiteOH);
                    calc.OHWeaponDPS = (a == null ? 0 : rot.GetAbilityOfType(DKability.WhiteOH).DPS);
                    calc.OHWeaponDamage = combatTable.OH.damage;
                    calc.OHAttackSpeed = combatTable.OH.hastedSpeed;
                }
                calcOpts.szRotReport = rot.ReportRotation();
                calc.m_RuneCD = (float)rot.m_SingleRuneCD / 1000;

                calc.DPSBreakdown(rot);
            }  

            return calc;
        }