예제 #1
0
        /// <summary>
        /// This a basic rotation
        /// </summary>
        public void PRE_Unholy_dynamic() // Expensive
        {
            /*
            if (_RotCacheType == Type.Unholy
                && _RotCache.Count > 100
                && Math.Abs(_cachedHaste - m_CT.m_CState.m_Stats.PhysicalHaste) <= 0.05f ) // Haste is within 5% of the cached Haste.
            {
                ml_Rot = _RotCache;
                foreach (AbilityDK_Base ab in ml_Rot)
                {
                    ab.UpdateCombatState(m_CT.m_CState);
                }
                BuildCosts();
                return;
            }
             * */
            // Because, really, Unholy should be in Unholy Presence. 
            // m_CT.m_Opts.presence = Presence.Unholy;
            m_szRotationName = "Unholy Rotation";

            ResetRotation();
            // Setup an instance of each ability.
            // No runes:
            AbilityDK_Outbreak Outbreak = new AbilityDK_Outbreak(m_CT.m_CState);
            // Single Runes:
//            AbilityDK_IcyTouch IT = new AbilityDK_IcyTouch(m_CT.m_CState);
            AbilityDK_FrostFever FF = new AbilityDK_FrostFever(m_CT.m_CState);
//            AbilityDK_PlagueStrike PS = new AbilityDK_PlagueStrike(m_CT.m_CState);
            AbilityDK_BloodPlague BP = new AbilityDK_BloodPlague(m_CT.m_CState);
            // AbilityDK_BloodStrike BS = new AbilityDK_BloodStrike(m_CT.m_CState);
            // AbilityDK_HeartStrike HS = new AbilityDK_HeartStrike(m_CT.m_CState);
            // AbilityDK_NecroticStrike NS = new AbilityDK_NecroticStrike(m_CT.m_CState);
            // AbilityDK_Pestilence Pest = new AbilityDK_Pestilence(m_CT.m_CState);
            // AbilityDK_BloodBoil BB = new AbilityDK_BloodBoil(m_CT.m_CState);
            // AbilityDK_HowlingBlast HB = new AbilityDK_HowlingBlast(m_CT.m_CState);
            // AbilityDK_ScourgeStrike SS = new AbilityDK_ScourgeStrike(m_CT.m_CState);
            // AbilityDK_DeathNDecay DnD = new AbilityDK_DeathNDecay(m_CT.m_CState);
            // Multi Runes:
            // AbilityDK_DeathStrike DS = new AbilityDK_DeathStrike(m_CT.m_CState);
            AbilityDK_FesteringStrike Fest = new AbilityDK_FesteringStrike(m_CT.m_CState);
            // AbilityDK_Obliterate OB = new AbilityDK_Obliterate(m_CT.m_CState);
            // RP:  Unlikely to start w/ RP abilities to open.
            // AbilityDK_RuneStrike RS = new AbilityDK_RuneStrike(m_CT.m_CState);
            // each RS gives a 45% chance to renew a fully depleted runes.
            // thus 20 RSs gets us 9 extra runes.
            // Same is true for DC & FS
            AbilityDK_DeathCoil DC = new AbilityDK_DeathCoil(m_CT.m_CState);
            AbilityDK_UnholyBlight UB = null;
            if (DC.ml_TriggeredAbility.Length > 0) UB = DC.ml_TriggeredAbility[0] as AbilityDK_UnholyBlight;
            // AbilityDK_FrostStrike FS = new AbilityDK_FrostStrike(m_CT.m_CState);
            DarkTranformation Dark = new DarkTranformation(m_CT.m_CState);

            // Simple ITx1, PSx1, BSx1, SSx4 & Festx4.
            // Initial rotation build.
            int[] AvailableResources = new int[EnumHelper.GetCount(typeof(DKCostTypes))];
            AvailableResources[(int)DKCostTypes.Blood] = 2;
            AvailableResources[(int)DKCostTypes.Frost] = 2;
            AvailableResources[(int)DKCostTypes.UnHoly] = 2;
            if (m_CT.m_CState.m_Talents.DarkTransformation > 0)
            {
                // this won't be there if they're not spec'd for it.
                ml_Rot.Add(Dark); // Dark Transformation.
                ProcessRunningRunes(AvailableResources, Dark.AbilityCost);
            }
            uint subrotDuration = 0;
            uint GCDdur = MIN_GCD_MS;
            // Fill the 3 mins duration 
            if (m_CT.m_Opts.presence == Presence.Unholy)
                GCDdur = MIN_GCD_MS_UH;

            subrotDuration = Outbreak.Cooldown;
            uint diseaseGCDs = 0;
            for (int count = (int)(Dark.Cooldown / subrotDuration); count > 0; count--)
            {
                if (m_CT.m_CState.m_Stats.RPp5 > 0)
                    AvailableResources[(int)DKCostTypes.RunicPower] += (int)((subrotDuration / 5000) * m_CT.m_CState.m_Stats.RPp5);
                // TODO: This still assumes that we're filling every GCD w/ an ability. 
                // We know that's not the case in most situations.
                ml_Rot.Add(Outbreak); // 60 sec CD.
                ProcessRunningRunes(AvailableResources, Outbreak.AbilityCost);
                ml_Rot.Add(FF);
                ml_Rot.Add(BP);
                // 1 GCDs

                // Fill the disease.
                diseaseGCDs = Outbreak.Cooldown / GCDdur; 
                
                float MaxRP = 100 + m_CT.m_CState.m_Stats.BonusMaxRunicPower;

                List<AbilityDK_Base> l_Abilities;

                for (; diseaseGCDs > 0; )
                {
                    bool bEnoughRP = (-1 * AvailableResources[(int)DKCostTypes.RunicPower]) > DC.RunicPower;
                    bool bOverCapRP = (AvailableResources[(int)DKCostTypes.RunicPower] + Fest.RunicPower) > MaxRP;

                    if ( (!bEnoughRP 
                        && !bOverCapRP) ) 
                    {
                        l_Abilities = GetFilteredListOfAbilities(AvailableResources, m_CT.m_CState);
                        if (l_Abilities.Count > 0)
                        {
                            foreach (AbilityDK_Base ab in l_Abilities)
                            {
                                ab.UpdateCombatState(m_CT.m_CState);
                            }
                            l_Abilities.Sort(AbilityDK_Base.CompareDPSByRunes);
                            if (l_Abilities[0].AbilityIndex == (int)DKability.BloodStrike ||
                                l_Abilities[0].AbilityIndex == (int)DKability.IcyTouch)
                            {
                                l_Abilities[0] = GetAbilityOfType(l_Abilities, DKability.FesteringStrike);
                            }
                            ProcessRunningRunes(AvailableResources, l_Abilities[0].AbilityCost);
                            ml_Rot.Add(l_Abilities[0]);

                        }
                        else
                        {
                            // If the list is 0, means all the runes have been used. 
                            // Reset runes
                            AvailableResources[(int)DKCostTypes.Blood] = 2;
                            AvailableResources[(int)DKCostTypes.Frost] = 2;
                            AvailableResources[(int)DKCostTypes.UnHoly] = 2;
                        }
                    }
                    else
                    {
                        ml_Rot.Add(DC);
                        ProcessRunningRunes(AvailableResources, DC.AbilityCost);
                    }
                    diseaseGCDs--;
                }
            }

            // How much RP do we have left at this point?
            foreach (AbilityDK_Base ab in ml_Rot)
                m_RunicPower += ab.RunicPower;

            BuildCosts();

            // subsequent:
            #region Unholy Blight
            if (UB != null)
            {
                uint mSecperDC = (uint)m_RotationDuration / Count(DKability.DeathCoil);
                uint UBCount = (uint)m_RotationDuration / Math.Max(UB.Cooldown, mSecperDC);
                for (; UBCount > 0; UBCount--)
                {
                    ml_Rot.Add(UB);
                }
            }
            #endregion
            /*
            _cachedHaste = m_CT.m_CState.m_Stats.PhysicalHaste;
            _RotCacheType = Type.Unholy;
            _RotCache = ml_Rot;
             * */
        }
예제 #2
0
        /// <summary>
        /// This a basic preset rotation consuming the full CD of Dark Transformation.
        /// </summary>
        public void PRE_Unholy()
        {
            ResetRotation();

            m_szRotationName = "Unholy Rotation";
            // Because, really, Unholy should be in Unholy Presence. 
            if (m_CT.m_Opts.presence != Presence.Unholy)
            {
                m_szRotationName += "\nYou should be in Unholy Presence.";
            }
            // Setup an instance of each ability.
            // No runes:
            AbilityDK_Outbreak Outbreak = new AbilityDK_Outbreak(m_CT.m_CState);
            // Single Runes:
            //            AbilityDK_IcyTouch IT = new AbilityDK_IcyTouch(m_CT.m_CState);
            AbilityDK_FrostFever FF = new AbilityDK_FrostFever(m_CT.m_CState);
            //            AbilityDK_PlagueStrike PS = new AbilityDK_PlagueStrike(m_CT.m_CState);
            AbilityDK_BloodPlague BP = new AbilityDK_BloodPlague(m_CT.m_CState);
            // AbilityDK_BloodStrike BS = new AbilityDK_BloodStrike(m_CT.m_CState);
            AbilityDK_ScourgeStrike SS = new AbilityDK_ScourgeStrike(m_CT.m_CState);
            AbilityDK_FesteringStrike Fest = new AbilityDK_FesteringStrike(m_CT.m_CState);
            AbilityDK_DeathCoil DC = new AbilityDK_DeathCoil(m_CT.m_CState);
            AbilityDK_UnholyBlight UB = null;
            if (DC.ml_TriggeredAbility != null && DC.ml_TriggeredAbility.Length > 0) UB = DC.ml_TriggeredAbility[0] as AbilityDK_UnholyBlight;
            DarkTranformation Dark = new DarkTranformation(m_CT.m_CState);
            AbilityDK_DeathNDecay DnD = new AbilityDK_DeathNDecay(m_CT.m_CState);

            // Simple outbreak, Festx2 SSx6 & Fill w/ DCs
            int[] AvailableResources = new int[EnumHelper.GetCount(typeof(DKCostTypes))];
            if (m_CT.m_CState.m_Talents.DarkTransformation > 0)
            {
                // this won't be there if they're not spec'd for it.
                ml_Rot.Add(Dark); // Dark Transformation.
                ProcessRunningRunes(AvailableResources, Dark.AbilityCost);
            }
            uint subrotDuration = 0;
            uint GCDdur = MIN_GCD_MS;
            // Fill the 3 mins duration 
            if (m_CT.m_Opts.presence == Presence.Unholy)
                GCDdur = MIN_GCD_MS_UH;

            subrotDuration = Outbreak.Cooldown;
            uint diseaseGCDs = Outbreak.Cooldown / GCDdur;
            for (int count = (int)(Dark.Cooldown / subrotDuration); count > 0; count--)
            {
                if (m_CT.m_CState.m_Stats.RPp5 > 0)
                    AvailableResources[(int)DKCostTypes.RunicPower] += (int)((subrotDuration / 5000) * m_CT.m_CState.m_Stats.RPp5);
                // TODO: This still assumes that we're filling every GCD w/ an ability. 
                // We know that's not the case in most situations.
                ml_Rot.Add(Outbreak); // 60 sec CD.
                ProcessRunningRunes(AvailableResources, Outbreak.AbilityCost);
                ml_Rot.Add(FF);
                ml_Rot.Add(BP);
                // 1 GCDs

                // Fill the disease.
                for (uint i = 3; i > 0; i--)
                {
                    if (i == 3)
                    {
                        ml_Rot.Add(DnD); diseaseGCDs--;
                        AvailableResources[(int)DKCostTypes.RunicPower] += DnD.RunicPower;
                    }
                    else
                    {
                        ml_Rot.Add(SS); diseaseGCDs--;
                        AvailableResources[(int)DKCostTypes.RunicPower] += SS.RunicPower;
                    }
                    ml_Rot.Add(SS); diseaseGCDs--;
                    ml_Rot.Add(Fest); diseaseGCDs--;
                    ml_Rot.Add(Fest); diseaseGCDs--;
                    ml_Rot.Add(SS); diseaseGCDs--;
                    ml_Rot.Add(SS); diseaseGCDs--;
                    ml_Rot.Add(SS); diseaseGCDs--;
                    ml_Rot.Add(SS); diseaseGCDs--;
                    AvailableResources[(int)DKCostTypes.RunicPower] += SS.RunicPower * 5;
                    AvailableResources[(int)DKCostTypes.RunicPower] += Fest.RunicPower * 2;
                }
            }
            m_RunicPower = -1 * AvailableResources[(int)DKCostTypes.RunicPower];
            // Burn All of the RP we can.
            for (float RSCount = Math.Abs((float)m_RunicPower / (float)DC.RunicPower); RSCount > 0; RSCount--)
            {
                if (RSCount >= 1)
                {
                    ml_Rot.Add(DC);
                    m_RunicPower += DC.RunicPower;
                }
                else
                {
                    AbilityDK_DeathCoil DCPartial = new AbilityDK_DeathCoil(m_CT.m_CState);
                    DCPartial.fPartialValue = RSCount;
                    DCPartial.bPartial = true;
                    DCPartial.szName = "DC (partial)";
                    DCPartial.RunicPower = (int)((float)DC.RunicPower * DCPartial.fPartialValue);
                    m_RunicPower += DCPartial.RunicPower;
                    ml_Rot.Add(DCPartial);
                }
            }
            BuildCosts();

            #region Sudden Doom
            if (m_CT.m_CState.m_Talents.SuddenDoom > 0)
            {
                AbilityDK_Base ability;
                float fRimeMod = this.Count(DKability.White) * (.05f * (float)m_CT.m_CState.m_Talents.SuddenDoom);
                // 30% chance to proc 2 SDs rather than 1.
                if (m_CT.m_CState.m_Stats.b2T13_DPS)
                    fRimeMod *= 1.3f;
                if (fRimeMod > 1)
                {
                    for (; fRimeMod > 1; fRimeMod--)
                    {
                        ability = new AbilityDK_DeathCoil(m_CT.m_CState);
                        ability.szName = "DC (SuddenDoom)";
                        // These are free DCs.
                        ability.AbilityCost[(int)DKCostTypes.Blood] = 0;
                        ability.AbilityCost[(int)DKCostTypes.Frost] = 0;
                        ability.AbilityCost[(int)DKCostTypes.UnHoly] = 0;
                        ability.AbilityCost[(int)DKCostTypes.Death] = 0;
                        ability.AbilityCost[(int)DKCostTypes.RunicPower] = 0;
                        ml_Rot.Add(ability);
                    }
                }
                if (fRimeMod > 0 && fRimeMod < 1)
                {
                    // we want 1 full use, and then any sub values.
                    ability = new AbilityDK_DeathCoil(m_CT.m_CState);
                    ability.szName = "DC (SD_Partial)";
                    ability.bPartial = true;
                    ability.fPartialValue = fRimeMod;
                    // These are free DCs.
                    ability.AbilityCost[(int)DKCostTypes.Blood] = 0;
                    ability.AbilityCost[(int)DKCostTypes.Frost] = 0;
                    ability.AbilityCost[(int)DKCostTypes.UnHoly] = 0;
                    ability.AbilityCost[(int)DKCostTypes.Death] = 0;
                    ability.AbilityCost[(int)DKCostTypes.RunicPower] = 0;
                    ml_Rot.Add(ability);
                }
            }
            #endregion

            #region Unholy Blight
            if (UB != null)
            {
                uint mSecperDC = (uint)m_RotationDuration / Count(DKability.DeathCoil);
                uint UBCount = (uint)m_RotationDuration / Math.Max(UB.uDuration, mSecperDC);
                for (; UBCount > 0; UBCount--)
                {
                    ml_Rot.Add(UB);
                }
            }
            #endregion
            BuildCosts();

        }