/// <summary> /// This a basic IT, PS, HSx4 (or BBx4), DSx3, RSx? rotation. /// </summary> public void PRE_Frost() { m_szRotationName = "Frost Rotation"; ResetRotation(); // Setup an instance of each ability. // No runes: // AbilityDK_Outbreak OutB = 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_FrostStrike FS = new AbilityDK_FrostStrike(m_CT.m_CState); // Simple ITx1, PSx1, BSx2, OBx1 RS w/ RP (x3ish). // if Glyph of HB, then HB can be used to apply FF. if (m_CT.m_CState.m_Talents.GlyphofHowlingBlast && HB.DPS > IT.DPS) { ml_Rot.Add(HB); } else { ml_Rot.Add(IT); } ml_Rot.Add(FF); ml_Rot.Add(PS); ml_Rot.Add(BP); // TODO: 4.1 Blood Runes are ALWAYS Death Runes. // These will create DeathRunes that can allow flexibility in the rotation later on. // ml_Rot.Add(BS); // ml_Rot.Add(BS); ml_Rot.Add(OB); ml_Rot.Add(OB); ml_Rot.Add(OB); ml_Rot.Add(OB); ml_Rot.Add(OB); #region RunicPower Pass 1. // How much RP do we have at this point? foreach (AbilityDK_Base ab in ml_Rot) m_RunicPower += ab.RunicPower; if (m_CT.m_CState.m_Stats.RPp5 > 0) m_RunicPower -= (int)((CurRotationDuration / 5) * m_CT.m_CState.m_Stats.RPp5); float RSCount = 0; // Burn what we can. for (RSCount = Math.Abs((float)m_RunicPower / (float)FS.RunicPower); RSCount > 0; RSCount--) { if (RSCount >= 1) { ml_Rot.Add(FS); m_RunicPower += FS.RunicPower; } // Partials at the end. } #endregion #region Talent: Rime if (m_CT.m_CState.m_Talents.Rime > 0) { AbilityDK_Base ability; // we want 1 full use, and then any sub values. if (HB.DPS > IT.DPS) { ability = new AbilityDK_HowlingBlast(m_CT.m_CState); ability.szName = "HB"; } else { ability = new AbilityDK_IcyTouch(m_CT.m_CState); ability.szName = "IT"; } ability.szName += " (Rime)"; // These are free ITs/HBs. 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; float fRimeMod = this.Count(DKability.Obliterate) * .15f * m_CT.m_CState.m_Talents.Rime; // 60% chance to proc 2 Rimes rather than 1. if (m_CT.m_CState.m_Stats.b2T13_DPS) fRimeMod *= 1.6f; if (fRimeMod >= 1f) { for (; fRimeMod >= 1; fRimeMod--) { ml_Rot.Add(ability); } } if (fRimeMod > 0f && fRimeMod < 1f) { if (HB.DPS > IT.DPS) { ability = new AbilityDK_HowlingBlast(m_CT.m_CState); ability.szName = "HB"; } else { ability = new AbilityDK_IcyTouch(m_CT.m_CState); ability.szName = "IT"; } ability.szName += " (Rime_partial)"; // These are free ITs/HBs. 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; ability.bPartial = true; ability.fPartialValue = fRimeMod; ml_Rot.Add(ability); } } #endregion BuildCosts(); #region Talent: Killing Machine float fRotInMins = CurRotationDuration / 60; float fKMPPM = 5 * (m_CT.m_CState.m_Talents.KillingMachine / 3); float KMProcCount = fKMPPM * fRotInMins; float fOBFSCount = Count(DKability.FrostStrike) + Count(DKability.Obliterate); float fPctOBFSCrit = KMProcCount / fOBFSCount; OB.SetKMCritChance(fPctOBFSCrit); FS.SetKMCritChance(fPctOBFSCrit); #endregion BuildCosts(); #region RunicPower Pass 2. // How much RP do we have at this point? if (m_CT.m_CState.m_Stats.RPp5 > 0) m_RunicPower -= (int)((CurRotationDuration / 5) * m_CT.m_CState.m_Stats.RPp5); // Burn what we can. for (RSCount = Math.Abs((float)m_RunicPower / (float)FS.RunicPower); RSCount > 0; RSCount--) { if (RSCount >= 1) { ml_Rot.Add(FS); m_RunicPower += FS.RunicPower; } else { AbilityDK_FrostStrike FSPartial = new AbilityDK_FrostStrike(m_CT.m_CState); FSPartial.fPartialValue = RSCount; FSPartial.bPartial = true; FSPartial.szName = "FS (partial)"; FSPartial.RunicPower = (int)((float)FS.AbilityCost[(int)DKCostTypes.RunicPower] * RSCount); m_RunicPower += FSPartial.RunicPower; ml_Rot.Add(FSPartial); } } #endregion BuildCosts(); }
/// <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; * */ }
/// <summary> /// This a basic IT, PS, HSx4 (or BBx4), DSx3, RSx? rotation. /// </summary> public void PRE_BloodDiseased() { m_szRotationName = "Blood Diseased Rotation"; ResetRotation(); // This will only happen while tanking... //m_CT.m_Opts.presence = Presence.Blood; // Setup an instance of each ability. // No runes: AbilityDK_Outbreak OutB = 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_FrostStrike FS = new AbilityDK_FrostStrike(m_CT.m_CState); AbilityDK_DancingRuneWeapon DRW = new AbilityDK_DancingRuneWeapon(m_CT.m_CState); // Fire DRW every chance we get. ml_Rot.Add(DRW); // Fill the 1.5 min CD w/ the sub rotation. uint subrotDuration = (9 * MIN_GCD_MS); for (int count = (int)(DRW.Cooldown / subrotDuration); count > 0; count--) { // Simple ITx1, PSx1, DSx1, HSx2 or BBx2, RS w/ RP (x3ish). if (Rawr.Properties.GeneralSettings.Default.PTRMode) { ml_Rot.Add(OutB); ml_Rot.Add(DS); } else { ml_Rot.Add(IT); ml_Rot.Add(PS); } ml_Rot.Add(FF); ml_Rot.Add(BP); // Scarlet Fever is tied to this for 4.0.6 if (HS.TotalThreat > BB.TotalThreat) { // Just HSx4 ml_Rot.Add(HS); ml_Rot.Add(HS); ml_Rot.Add(HS); ml_Rot.Add(HS); } else { // if BB does more, then BB. ml_Rot.Add(BB); ml_Rot.Add(BB); ml_Rot.Add(BB); ml_Rot.Add(BB); } // These will create DeathRunes that can allow flexibility in the rotation later on. ml_Rot.Add(DS); ml_Rot.Add(DS); ml_Rot.Add(DS); } #region Runic Power Pass 1. // How much RP do we have at this point? foreach (AbilityDK_Base ab in ml_Rot) m_RunicPower += ab.RunicPower; m_RunicPower = (int)((float)m_RunicPower); if (m_CT.m_CState.m_Stats.RPp5 > 0) m_RunicPower -= (int)((CurRotationDuration / 5) * m_CT.m_CState.m_Stats.RPp5); // Burn what we can. float RSCount = 0; for (RSCount = Math.Abs(m_RunicPower / RS.RunicPower); RSCount > 0; RSCount--) { ml_Rot.Add(RS); m_RunicPower += RS.RunicPower; } #endregion BuildCosts(); #region RunicPower Pass 2. // How much RP do we have at this point? if (m_CT.m_CState.m_Stats.RPp5 > 0) m_RunicPower -= (int)((CurRotationDuration / 5) * m_CT.m_CState.m_Stats.RPp5); // Burn what we can. for (RSCount = Math.Abs((float)m_RunicPower / (float)RS.RunicPower); RSCount > 0; RSCount--) { if (RSCount >= 1) { ml_Rot.Add(RS); m_RunicPower += RS.RunicPower; } else { AbilityDK_RuneStrike RSPartial = new AbilityDK_RuneStrike(m_CT.m_CState); RSPartial.fPartialValue = RSCount; RSPartial.bPartial = true; RSPartial.szName = "RS (partial)"; RSPartial.RunicPower = (int)((float)RS.AbilityCost[(int)DKCostTypes.RunicPower] * RSCount); m_RunicPower += RSPartial.RunicPower; ml_Rot.Add(RSPartial); } } #endregion BuildCosts(); }
/// <summary> /// This is my fire 1 of everything rotation. /// </summary> public void PRE_OneEachRot() { m_szRotationName = "One Each Rotation"; ResetRotation(); // Setup an instance of each ability. // No runes: AbilityDK_Outbreak OutB = 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); AbilityDK_DeathCoil DC = new AbilityDK_DeathCoil(m_CT.m_CState); AbilityDK_FrostStrike FS = new AbilityDK_FrostStrike(m_CT.m_CState); // For now, let's just blow everything in here one each. ml_Rot.Add(IT); ml_Rot.Add(FF); ml_Rot.Add(PS); ml_Rot.Add(BP); ml_Rot.Add(BS); ml_Rot.Add(HS); ml_Rot.Add(BB); ml_Rot.Add(NS); ml_Rot.Add(HB); ml_Rot.Add(SS); ml_Rot.Add(DnD); ml_Rot.Add(DS); ml_Rot.Add(OB); ml_Rot.Add(Fest); ml_Rot.Add(RS); ml_Rot.Add(DC); ml_Rot.Add(FS); BuildCosts(); }
/// <summary> /// This a more basic rotation that assumes Dark Tranformations will be rolled in /// </summary> public void PRE_Unholy_short() { 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; AbilityDK_DeathNDecay DnD = new AbilityDK_DeathNDecay(m_CT.m_CState); // Simple outbreak, Festx2 DnD, SSx5 & Fill w/ DCs int[] AvailableResources = new int[EnumHelper.GetCount(typeof(DKCostTypes))]; 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; 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--) { ml_Rot.Add(DnD); diseaseGCDs--; ProcessRunningRunes(AvailableResources, DnD.AbilityCost); ml_Rot.Add(SS); diseaseGCDs--; ProcessRunningRunes(AvailableResources, SS.AbilityCost); ml_Rot.Add(Fest); diseaseGCDs--; ProcessRunningRunes(AvailableResources, Fest.AbilityCost); ml_Rot.Add(Fest); diseaseGCDs--; ProcessRunningRunes(AvailableResources, Fest.AbilityCost); ml_Rot.Add(SS); diseaseGCDs--; ProcessRunningRunes(AvailableResources, SS.AbilityCost); ml_Rot.Add(SS); diseaseGCDs--; ProcessRunningRunes(AvailableResources, SS.AbilityCost); ml_Rot.Add(SS); diseaseGCDs--; ProcessRunningRunes(AvailableResources, SS.AbilityCost); ml_Rot.Add(SS); diseaseGCDs--; ProcessRunningRunes(AvailableResources, SS.AbilityCost); while (AvailableResources[(int)DKCostTypes.RunicPower] > DC.RunicPower && diseaseGCDs > 0) { ml_Rot.Add(DC); diseaseGCDs--; ProcessRunningRunes(AvailableResources, DC.AbilityCost); } BuildCosts(); } m_RunicPower = -1 * AvailableResources[(int)DKCostTypes.RunicPower]; if (m_RunicPower < 0) { AbilityDK_DeathCoil DCP = new AbilityDK_DeathCoil(m_CT.m_CState); DCP.szName = "DC (RP_Partial)"; DCP.bPartial = true; DCP.fPartialValue = (float)Math.Abs(m_RunicPower) / (float)DCP.RunicPower; DCP.RunicPower = (int)((float)DCP.RunicPower * DCP.fPartialValue); ml_Rot.Add(DCP); m_RunicPower += DCP.RunicPower; } 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); 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(); }
/// <summary> /// Generate a rotation based on available resources. /// </summary> public void PostAbilitiesSingleUse(bool bThreat) { // Setup an instance of each ability. // No runes: AbilityDK_Outbreak OutB = new AbilityDK_Outbreak(m_CState); // Single Runes: AbilityDK_IcyTouch IT = new AbilityDK_IcyTouch(m_CState); PostData(IT); AbilityDK_FrostFever FF = new AbilityDK_FrostFever(m_CState); PostData(FF); AbilityDK_PlagueStrike PS = new AbilityDK_PlagueStrike(m_CState); PostData(PS); AbilityDK_BloodPlague BP = new AbilityDK_BloodPlague(m_CState); PostData(BP); AbilityDK_BloodStrike BS = new AbilityDK_BloodStrike(m_CState); PostData(BS); AbilityDK_HeartStrike HS = new AbilityDK_HeartStrike(m_CState); PostData(HS); AbilityDK_NecroticStrike NS = new AbilityDK_NecroticStrike(m_CState); PostData(NS); // AbilityDK_Pestilence Pest = new AbilityDK_Pestilence(m_CState); AbilityDK_BloodBoil BB = new AbilityDK_BloodBoil(m_CState); PostData(BB); AbilityDK_HowlingBlast HB = new AbilityDK_HowlingBlast(m_CState); PostData(HB); AbilityDK_ScourgeStrike SS = new AbilityDK_ScourgeStrike(m_CState); PostData(SS); AbilityDK_DeathNDecay DnD = new AbilityDK_DeathNDecay(m_CState); PostData(DnD); // Multi Runes: AbilityDK_DeathStrike DS = new AbilityDK_DeathStrike(m_CState); PostData(DS); AbilityDK_FesteringStrike Fest = new AbilityDK_FesteringStrike(m_CState); PostData(Fest); AbilityDK_Obliterate OB = new AbilityDK_Obliterate(m_CState); PostData(OB); // RP: AbilityDK_RuneStrike RS = new AbilityDK_RuneStrike(m_CState); PostData(RS); AbilityDK_DeathCoil DC = new AbilityDK_DeathCoil(m_CState); PostData(DC); AbilityDK_FrostStrike FS = new AbilityDK_FrostStrike(m_CState); PostData(FS); }