Пример #1
0
        public static async Task <bool> AoEDashing(int count)
        {
            #region Multi-Target Fel Rush
            // use this in combination with vengeful retreat
            if (await S.GCD(SB.FelRush, C.CombatColor,
                            HS.HavocFelRushAoe &&
                            !S.OnCooldown(SB.VengefulRetreat) &&
                            T.HavocFelMastery &&
                            Me.CurrentTarget.Distance <= 18, "AoED", sleep: false))
            {
                return(true);
            }

            // use to engage
            if (await S.GCD(SB.FelRush, C.CombatColor,
                            HS.HavocFelRushAoe &&
                            !S.OnCooldown(SB.VengefulRetreat) &&
                            T.HavocFelMastery &&
                            Me.CurrentTarget.Distance <= 18, "AoED", sleep: false))
            {
                return(true);
            }
            #endregion

            return(false);
        }
Пример #2
0
        public static async Task <bool> VengefulRush(bool aoe = false)
        {
            if (!aoe)
            {
                // single target

                if (HS.HavocVengefulReatreatSingleTarget && HS.HavocFelRushSingleTarget)
                {
                    // make sure we can even use this
                    if (!S.OnCooldown(SB.VengefulRetreat) && FelRushCheckCharge(true))
                    {
                        // Vengeful is ready and FelRush is ready (or almost)
                        await S.Cast(SB.VengefulRetreat, C.CombatColor, addLog : "VengefulRush", sleep : false);

                        await Coroutine.Sleep(100);

                        await Coroutine.Sleep(Styx.CommonBot.SpellManager.GlobalCooldownLeft);

                        await S.Cast(SB.FelRush, C.CombatColor, addLog : "VengefulRush", sleep : false);

                        return(true);
                    }
                }
                return(false);
            }
            else
            {
                // aoe
                if (HS.HavocVengefulReatreatAoe && HS.HavocFelRushAoe)
                {
                    // make sure we can even use this
                }
            }
            return(false);
        }
Пример #3
0
        public static async Task <bool> GapCloser()
        {
            if (await S.Cast(SB.ThrowGlaive, C.CombatColor,
                             !Me.IsWithinMeleeRangeOf(CurrentTarget) &&
                             CurrentTarget.Distance <= 30, "GapCloser - GlaiveTimer: " + glaiveTossTimer.ElapsedMilliseconds + "ms"))
            {
                glaiveTossTimer.Restart();
                return(true);
            }
            if (await S.Cast(SB.FelBlade, C.CombatColor,
                             T.VengeanceFelblade &&
                             !CurrentTarget.IsWithinMeleeRangeOf(Me) &&
                             CurrentTarget.MeleeDistance() <= 15,
                             "ST Gap Closer"))
            {
                return(true);
            }

            if (await S.CastGround(SB.InfernalStrike, C.CombatColor,
                                   VS.VengeanceCombatInfernalStrikeGapCloser &&
                                   !CurrentTarget.IsWithinMeleeRangeOf(Me) &&
                                   CurrentTarget.MeleeDistance() <= infernalStrikeRange &&
                                   (S.GetSpellChargeInfo(SB.InfernalStrike).ChargesLeft > 0),
                                   "ST Gap Closer"))
            {
                return(true);
            }

            return(false);
        }
Пример #4
0
        static bool FelRushCheckCharge(bool needForVengeful)
        {
            // if we are already almost at max charges, go for it
            if (FelRushAlmostMaxCharge())
            {
                return(true);
            }

            SpellChargeInfo sci = S.GetSpellChargeInfo(SB.FelRush);

            // if we have no charges, but almost 1 charge available, go for it
            if (sci.ChargesLeft == 0)
            {
                return(sci.TimeUntilNextCharge.TotalMilliseconds < 500);
            }

            if (sci.ChargesLeft == 1)
            {
                if (needForVengeful)
                {
                    return(true);
                }
                // if we have 1 charge, but the cooldown time fo vengeful retreat is less than next charge time, go for it
                if (sci.TimeUntilNextCharge.TotalMilliseconds <= S.CooldownTimeLeft(SB.VengefulRetreat))
                {
                    return(true);
                }
            }
            // don't go for it.
            return(false);
        }
Пример #5
0
        public static async Task <bool> RotationSelector()
        {
            // we are playing manual, i am not alive, or I am mounted or on taxi, do not continue
            if (HK.manualOn || !Me.IsAlive || (Me.OnTaxi))
            {
                return(true);
            }

            // face taret, ensure melee, interrupt and taunt do not need to return as they are off of global cooldown.
            await C.FaceTarget(CurrentTarget);

            await C.EnsureMeleeRange(CurrentTarget);

            await InterruptTarget();

            if (await S.GCD(SB.Torment, C.CombatColor, !CurrentTarget.IsTargetingMeOrPet && VS.VengeanceAllowTaunt,
                            string.Format($"CT:{CurrentTarget.SafeName} not targeting me. Taunting!")))
            {
                return(true);
            }

            if (CurrentTarget.IsValidCombatUnit())
            {
                if (await ActiveMitigation())
                {
                    return(true);
                }

                if (await GapCloser())
                {
                    return(true);
                }

                if ((HK.VengeanceAoEOn || U.activeEnemies(Me.Location, 8f).Count() >= 3))
                {
                    if (await MultipleTarget())
                    {
                        return(true);
                    }
                }

                // default to single target if nothing else
                return(await SingleTarget());
            }
            return(false);
        }
Пример #6
0
        public static async Task <bool> RushST()
        {
            if (!Me.IsWithinMeleeRangeOf(CurrentTarget))
            {
                return(false);
            }
            // only use if we have FelRush available and Vengeful Retreat is not available
            if (!S.OnCooldown(SB.FelRush) && S.OnCooldown(SB.VengefulRetreat))
            {
                WoWMovement.Move(WoWMovement.MovementDirection.Backwards, 500);
                WoWMovement.Move(WoWMovement.MovementDirection.JumpAscend, 500);
                S.Cast2(SB.FelRush, C.CombatColor, HS.HavocFelRushSingleTarget, "RushST");
                await Coroutine.Yield();

                return(true);
            }
            return(false);
        }
Пример #7
0
        public static async Task <bool> InterruptTarget()
        {
            if (!M.VengeanceAllowInterrupt)
            {
                return(false);
            }
            // use consume magic at 20 yards first
            //WoWUnit interruptTarget = GetInterruptTarget(20f);
            //L.debugLog(string.Format($"Interrupt target 20yd: {CurrentTarget.SafeName}"));
            if (await S.GCD(SB.ConsumeMagic, C.DefensiveColor,
                            VS.VengeanceAllowInterruptConsumeMagic &&
                            CurrentTarget.IsValidCombatUnit() &&
                            CurrentTarget.ShouldInterrupt(VS.VengeanceInterruptMinimumTime, VS.VengeanceInterruptTimeLeft),
                            string.Format($"Interrupt: {CurrentTarget.SafeName}, casting: {CurrentTarget.CastingSpell?.Name}")
                            ))
            {
                return(true);
            }


            //interruptTarget = GetInterruptTarget(30f);
            //if (interruptTarget != null)
            //{
            //    L.debugLog(string.Format($"Interrupt target 30yd: {interruptTarget.SafeName} casting: {interruptTarget.CastingSpell?.Name}"));
            //    // now look for sigil of silence
            if (await S.CastGround(SB.SigilOfSilence, C.DefensiveColor, VS.VengeanceAllowInterruptSigilOfSilence &&
                                   CurrentTarget.ShouldInterrupt(VS.VengeanceInterruptMinimumTime, VS.VengeanceInterruptTimeLeft),
                                   string.Format($"Interrupt: {CurrentTarget.SafeName}, casting: {CurrentTarget.CastingSpell?.Name}")))
            {
                return(true);
            }

            // now look for sigil of misery
            if (await S.CastGround(SB.SigilOfMisery, C.DefensiveColor, VS.VengeanceAllowInterruptSigilOfMisery &&
                                   CurrentTarget.ShouldInterrupt(VS.VengeanceInterruptMinimumTime, VS.VengeanceInterruptTimeLeft),
                                   string.Format($"Interrupt: {CurrentTarget.SafeName}, casting: {CurrentTarget.CastingSpell?.Name}")))
            {
                return(true);
            }

            //}

            return(false);
        }
Пример #8
0
        public static async Task <bool> Pull()
        {
            if (CurrentTarget.IsValidCombatUnit())
            {
                await C.EnsureMeleeRange(CurrentTarget);

                await C.FaceTarget(CurrentTarget);

                if (await S.Cast(SB.ThrowGlaive, C.CombatColor, CurrentTarget.Distance <= 30, "Pull - GlaiveTimer: " + glaiveTossTimer.ElapsedMilliseconds + "ms"))
                {
                    glaiveTossTimer.Restart(); return(true);
                }

                // use to engage if you have the charges to do so
                if (await S.CastGround(SB.InfernalStrike, C.CombatColor,
                                       VS.VengeanceCombatInfernalStrikePull &&
                                       CurrentTarget.Distance <= infernalStrikeRange &&
                                       !CurrentTarget.IsWithinMeleeRangeOf(Me) &&
                                       !VS.VengeancePreferPullWithFelblade
                                       , "Pull"))
                {
                    return(true);
                }

                // need to change this to check to see if we want to pull with Fel Blade or Infernal Strike (or which we prefer)
                if (await S.Cast(SB.FelBlade, C.CombatColor, T.VengeanceFelblade &&
                                 !CurrentTarget.IsWithinMeleeRangeOf(Me) &&
                                 CurrentTarget.Distance <= 15, "Pull"))
                {
                    return(true);
                }

                // now use in case felblade was on cd, but don't check prefer
                if (await S.CastGround(SB.InfernalStrike, C.CombatColor,
                                       CurrentTarget.Distance <= infernalStrikeRange &&
                                       VS.VengeanceCombatInfernalStrikePull &&
                                       !CurrentTarget.IsWithinMeleeRangeOf(Me)
                                       , "Pull"))
                {
                    return(true);
                }
            }
            return(false);
        }
Пример #9
0
        public static async Task <bool> CombatBuffing()
        {
            if (HK.manualOn || !Me.IsAlive || (!Me.GotTarget || !CurrentTarget.IsAlive) || (Me.OnTaxi))
            {
                return(true);
            }
            if (!Me.IsAutoAttacking && CurrentTarget.IsValidCombatUnit())
            {
                Lua.DoString("StartAttack()"); return(true);
            }

            if (await S.Cast(SB.ChaosBlades, C.CombatColor,
                             HS.HavocUseChaosBlades == CooldownTypes.Cooldown || // use it on cooldown
                             (HS.HavocUseChaosBlades == CooldownTypes.BossOnly && Me.CurrentTarget.IsBoss) || // use if only is a boss
                             (HS.HavocUseChaosBlades == CooldownTypes.EliteBoss && (Me.CurrentTarget.IsBoss || Me.CurrentTarget.Elite)) // use boss or elite

                             ))
            {
                return(true);
            }

            if (await S.Cast(SB.Nemesis, C.CombatColor,
                             HS.HavocUseNemesis == CooldownTypes.Cooldown || // use it on cooldown
                             (HS.HavocUseNemesis == CooldownTypes.BossOnly && Me.CurrentTarget.IsBoss) || // use if only is a boss
                             (HS.HavocUseNemesis == CooldownTypes.EliteBoss && (Me.CurrentTarget.IsBoss || Me.CurrentTarget.Elite)) // use boss or elite

                             ))
            {
                return(true);
            }


            //if (await I.UseItem(I.GetItemByName("Draenic Agility Potion"),
            //    HS.HavocUseAgilityPotionCooldown == CooldownTypes.Cooldown // use it on cooldown
            //    || (HS.HavocUseAgilityPotionCooldown == CooldownTypes.BossOnly && Me.CurrentTarget.IsBoss) // use if only is a boss
            //    || (HS.HavocUseAgilityPotionCooldown == CooldownTypes.EliteBoss && (Me.CurrentTarget.IsBoss || Me.CurrentTarget.Elite)) // use boss or eltie
            //))
            //{ return true; }

            return(false);
        }
Пример #10
0
        public static async Task <bool> Pull()
        {
            if (CurrentTarget.IsValidCombatUnit())
            {
                if (!CurrentTarget.IsWithinMeleeRangeOf(Me) && GS.GeneralMovement)
                {
                    //L.infoLog("Tried to pull");
                    await C.EnsureMeleeRange(CurrentTarget);
                }

                if (GS.GeneralFacing)
                {
                    // check to see if we need to face target
                    await C.FaceTarget(CurrentTarget);
                }



                // throw a glaive first
                if (await S.Cast(SB.ThrowGlaive, C.CombatColor,
                                 CurrentTarget.Distance <= 30))
                {
                    return(true);
                }

                if (await S.Cast(SB.FelBlade, C.CombatColor,
                                 CurrentTarget.Distance <= 15))
                {
                    return(true);
                }

                // use to engage
                return(await S.GCD(SB.FelRush, C.CombatColor, CurrentTarget.Distance <= 20 &&
                                   HS.HavocFelRushOnPull));
            }

            return(true);
        }
Пример #11
0
        public static async Task <bool> MultipleTarget()
        {
            if (await S.Cast(SB.ThrowGlaive, C.CombatColor,
                             !glaiveTossTimer.IsRunning && VS.VengeanceCombatThrowGlaive ||
                             (glaiveTossTimer.IsRunning && VS.VengeanceCombatThrowGlaive && glaiveTossTimer.ElapsedMilliseconds > VS.VengeanceCombatThrowGlaiveSeconds), "AoE - GlaiveTimer: " + glaiveTossTimer.ElapsedMilliseconds + "ms"))
            {
                glaiveTossTimer.Restart();
                return(true);
            }

            if (await S.Cast(SB.SoulCleave, C.CombatColor,
                             C.CurrentPower >= VS.VengeanceCombatSoulCleavePain,
                             string.Format($"AoE: CP:{C.CurrentPower}>={VS.VengeanceCombatSoulCleavePain}")
                             ))
            {
                return(true);
            }

            if (await S.CastGroundOnMe(SB.InfernalStrike, C.CombatColor,
                                       VS.VengeanceCombatInfernalStrikeAoE &&
                                       Me.IsWithinMeleeRangeOf(CurrentTarget) &&
                                       S.MaxChargesAvailable(SB.InfernalStrike),
                                       "AoE Max Charges Available"))
            {
                return(true);
            }

            if (await S.Cast(SB.FelDevastation, C.CombatColor, T.VengeanceFelDevastation, addLog: "AoE Fel Devastation"))
            {
                return(true);
            }
            if (await S.Cast(SB.ImmolationAura, C.CombatColor, addLog: "AoE"))
            {
                return(true);
            }
            if (await S.Cast(SB.SpiritBomb, C.CombatColor, T.VengeanceSpiritBomb && !CurrentTarget.HasAura(SB.AuraFrailty), "AoE"))
            {
                return(true);
            }
            if (await S.Cast(SB.FelBlade, C.CombatColor, T.VengeanceFelblade, "AoE"))
            {
                return(true);
            }
            if (await S.Cast(SB.Shear, C.CombatColor, T.VengeanceBladeTurning && Me.HasAura(SB.AuraBladeTurning) && CurrentTarget.IsWithinMeleeRangeOf(Me), "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.SigilOfFlameTalented, C.CombatColor, CurrentTarget.IsWithinMeleeRangeOf(Me) && T.VengeanceConcentratedSigils, "AoE - Contentrated Sigils"))
            {
                return(true);
            }
            if (await S.CastGround(SB.SigilOfFlame, C.CombatColor, !T.VengeanceConcentratedSigils && !Me.IsWithinMeleeRangeOf(CurrentTarget), "AoE - Not in Melee; Cast on target"))
            {
                return(true);
            }
            if (await S.CastGroundOnMe(SB.SigilOfFlame, C.CombatColor, !T.VengeanceConcentratedSigils && Me.IsWithinMeleeRangeOf(CurrentTarget), "AoE - In Melee; Cast on self"))
            {
                return(true);
            }
            if (await S.CastGround(SB.SigilOfChains, C.CombatColor, T.VengeanceSigilOfChains && VS.VengeanceCombatSigilOfChains && CurrentTarget.NearbyTargets()?.Count() >= VS.VengeanceCombatSigilOfChainsUnits))
            {
                if (await S.Cast(SB.FieryBrand, C.CombatColor, T.VengeanceBurningAlive, addLog: "AoE has Burning Alive Talent"))
                {
                    return(true);
                }
            }
            if (await S.Cast(SB.Shear, C.CombatColor, addLog: "AoE"))
            {
                return(true);
            }

            return(false);
        }
Пример #12
0
        public static async Task <bool> SaveMe()
        {
            // cache number of active enemies in combat and just use that for use/logging
            int enemiesInMelee = U.activeEnemies(Me.Location, 8f).Count();

            //if (await I.UseItem(I.FindBestHealingPotion(), Me.HealthPercent < HS.HavocHealthPotionHp))
            //{
            //    return true;
            //}

            #region Blur

            if (await S.Buff(SB.Blur, C.DefensiveColor,
                             HS.HavocBlurUnits > 0 &&
                             (enemiesInMelee >= HS.HavocBlurUnits),
                             string.Format($"Units:{enemiesInMelee}>={HS.HavocBlurUnits}")))
            {
                return(true);
            }
            if (await S.Buff(SB.Blur, C.DefensiveColor,
                             HS.HavocBlurHp > 0 &&
                             Me.HealthPercent < HS.HavocBlurHp,
                             string.Format($"HP:{Me.HealthPercent.ToString("F0")}<{HS.HavocBlurHp}")))
            {
                return(true);
            }


            #endregion

            #region Darkness

            if (await S.Buff(SB.Darkness, C.DefensiveColor,
                             HS.HavocDarknessUnits > 0 &&
                             (enemiesInMelee >= HS.HavocDarknessUnits),
                             string.Format($"Units:{enemiesInMelee}>={HS.HavocDarknessUnits}")))
            {
                return(true);
            }
            if (await S.Buff(SB.Darkness, C.DefensiveColor,
                             HS.HavocDarknessHp > 0 &&
                             Me.HealthPercent < HS.HavocDarknessHp,
                             string.Format($"HP:{Me.HealthPercent.ToString("F0")}<{HS.HavocDarknessHp}")))
            {
                return(true);
            }


            #endregion

            #region Chaos Nova

            if (await S.Buff(SB.ChaosNova, C.DefensiveColor,
                             HS.HavocChaosNovaUnits > 0 &&
                             (enemiesInMelee >= HS.HavocChaosNovaUnits),
                             string.Format($"Units:{enemiesInMelee}>={HS.HavocChaosNovaUnits}")))
            {
                return(true);
            }
            if (await S.Buff(SB.ChaosNova, C.DefensiveColor,
                             HS.HavocChaosNovaHp > 0 &&
                             Me.HealthPercent < HS.HavocChaosNovaHp,
                             string.Format($"HP:{Me.HealthPercent.ToString("F0")}<{HS.HavocChaosNovaHp}")))
            {
                return(true);
            }

            #endregion

            return(false);
        }
Пример #13
0
        public static async Task <bool> ActiveMitigation()
        {
            WoWUnit stunTarget = GetStunTarget(CurrentTarget, 8f);

            if (await S.CastGround(SB.SigilOfMisery, stunTarget, C.DefensiveColor, stunTarget != null &&
                                   VS.VengeanceAllowStunSigilOfMisery))
            {
                return(true);
            }

            #region Defensive Hotkey
            // demon spikes if force defensive is on
            if (await S.Cast(SB.DemonSpikes, C.DefensiveColor,
                             HK.VengeanceDefensiveOn &&
                             HKS.HotkeyVengeanceDefensiveDemonSpikes &&
                             !Me.HasAura(SB.AuraDemonSpikes),
                             string.Format($"AM: HK.VengeanceDefensiveOn:{HK.VengeanceDefensiveOn.ToString()}, HotkeyVengeanceDefensiveDemonSpikes:{HKS.HotkeyVengeanceDefensiveDemonSpikes.ToString()}")
                             ))
            {
                return(true);
            }

            if (await S.Cast(SB.MetamorphosisSpell, C.DefensiveColor,
                             HK.VengeanceDefensiveOn &&
                             HKS.HotkeyVengeanceDefensiveMetamorphosis,
                             string.Format($"AM: HK.VengeanceDefensiveOn:{HK.VengeanceDefensiveOn.ToString()}, HotkeyVengeanceDefensiveMetamorphosis:{HKS.HotkeyVengeanceDefensiveMetamorphosis.ToString()}")
                             ))
            {
                return(true);
            }

            if (await S.Cast(SB.SoulBarrier, C.DefensiveColor,
                             HK.VengeanceDefensiveOn &&
                             HKS.HotkeyVengeanceDefensiveSoulBarrier,
                             string.Format($"AM: HK.VengeanceDefensiveOn:{HK.VengeanceDefensiveOn.ToString()}, HotkeyVengeanceDefensiveSoulBarrier:{HKS.HotkeyVengeanceDefensiveSoulBarrier.ToString()}")
                             ))
            {
                return(true);
            }

            if (await S.Cast(SB.FelDevastation, C.DefensiveColor,
                             HK.VengeanceDefensiveOn &&
                             HKS.HotkeyVengeanceDefensiveFelDevastation,
                             string.Format($"AM: HK.VengeanceDefensiveOn:{HK.VengeanceDefensiveOn.ToString()}, HotkeyVengeanceDefensiveFelDevastation:{HKS.HotkeyVengeanceDefensiveFelDevastation.ToString()}")))
            {
                if (Me.HasTankWarglaivesEquipped())
                {
                    if (await S.Cast(SB.SoulCarver, C.DefensiveColor,
                                     HK.VengeanceDefensiveOn &&
                                     HKS.HotkeyVengeanceDefensiveSoulCarver &&
                                     Me.IsWithinMeleeRangeOf(CurrentTarget) && // must be within melee range or won't work.
                                     Me.IsSafelyFacing(CurrentTarget.Location),
                                     string.Format($"AM: HK.VengeanceDefensiveOn:{HK.VengeanceDefensiveOn.ToString()}, HotkeyVengeanceDefensiveSoulCarver:{HKS.HotkeyVengeanceDefensiveSoulCarver.ToString()}")
                                     ))
                    {
                        return(true);
                    }
                }
            }

            if (await S.Cast(SB.SoulCleave, C.DefensiveColor,
                             HK.VengeanceDefensiveOn &&
                             HKS.HotkeyVengeanceDefensiveSoulCleave &&
                             CurrentTarget.IsWithinMeleeRangeOf(Me),
                             string.Format($"AM: HK.VengeanceDefensiveOn:{HK.VengeanceDefensiveOn.ToString()}, HotkeyVengeanceDefensiveSoulCleave:{HKS.HotkeyVengeanceDefensiveSoulCleave.ToString()}")
                             ))
            {
                return(true);
            }

            if (await S.Cast(SB.EmpowerWards, C.DefensiveColor,
                             HK.VengeanceDefensiveOn &&
                             HKS.HotkeyVengeanceDefensiveEmpowerWards,
                             string.Format($"AM: HK.VengeanceDefensiveOn:{HK.VengeanceDefensiveOn.ToString()}, HotkeyVengeanceDefensiveEmpowerWards:{HKS.HotkeyVengeanceDefensiveEmpowerWards.ToString()}")
                             ))
            {
                return(true);
            }

            if (await S.Cast(SB.FieryBrand, C.DefensiveColor,
                             HK.VengeanceDefensiveOn &&
                             HKS.HotkeyVengeanceDefensiveEmpowerWards,
                             string.Format($"AM: HK.VengeanceDefensiveOn:{HK.VengeanceDefensiveOn.ToString()}, HotkeyVengeanceDefensiveEmpowerWards:{HKS.HotkeyVengeanceDefensiveEmpowerWards.ToString()}")))
            {
                return(true);
            }

            #endregion

            if (await S.Cast(SB.MetamorphosisSpell, C.DefensiveColor,
                             VS.VengeanceAllowMetamorphosis &&
                             Me.HealthPercent <= VS.VengeanceMetamorphosisHp,
                             string.Format($"AM: HP:{Me.HealthPercent.ToString("F0")}<={VS.VengeanceMetamorphosisHp}")
                             ))
            {
                return(true);
            }

            // cast Demon Spikes if we have
            if (await S.Cast(SB.DemonSpikes, C.DefensiveColor,
                             VS.VengeanceAllowDemonSpikes &&
                             C.CurrentPower >= 20 &&
                             Me.HealthPercent <= VS.VengeanceDemonSpikesHp &&
                             !Me.HasAura(SB.AuraDemonSpikes) &&
                             U.activeEnemies(Me.Location, 8f).Any(),
                             string.Format($"AM: HP:{Me.HealthPercent.ToString("F0")}<={VS.VengeanceDemonSpikesHp}")
                             ))
            {
                return(true);
            }

            if (await S.Cast(SB.SoulBarrier, C.DefensiveColor, T.VengeanceSoulBarrier &&
                             VS.VengeanceAllowSoulBarrier &&
                             Me.HealthPercent <= VS.VengeanceSoulBarrierHp,
                             string.Format($"AM: HP:{Me.HealthPercent.ToString("F0")}<={VS.VengeanceSoulBarrierHp}")
                             ))
            {
                return(true);
            }

            // make sure we have tank weapons equipped (for lower level stuff)

            if (await S.Cast(SB.SoulCarver, C.DefensiveColor,
                             VS.VengeanceAllowSoulCarver &&
                             Me.HealthPercent <= VS.VengeanceSoulCarverHp,
                             string.Format($"AM: HP:{Me.HealthPercent.ToString("F0")}<={VS.VengeanceSoulCarverHp}")
                             ))
            {
                return(true);
            }

            if (await S.Cast(SB.SoulCleave, C.DefensiveColor,
                             VS.VengeanceAllowSoulCleave &&
                             C.CurrentPower >= 30 &&
                             Me.CurrentHealth <= VS.VengeanceSoulCleaveHp &&
                             CurrentTarget.IsWithinMeleeRangeOf(Me),
                             string.Format($"AM: HP:{Me.HealthPercent.ToString("F0")}<={VS.VengeanceSoulCleaveHp}")
                             ))
            {
                return(true);
            }

            if (await S.Cast(SB.EmpowerWards, C.DefensiveColor,
                             VS.VengeanceEmpowerWards &&
                             U.activeEnemies(Me.Location, 50f).Where(u =>
                                                                     u.IsTargetingMeOrPet && u.IsCasting)
                             .Any()
                             ))
            {
                return(true);
            }

            if (await S.Cast(SB.FieryBrand, C.DefensiveColor,
                             VS.VengeanceAllowFieryBrand &&
                             Me.HealthPercent <= VS.VengeanceFieryBrandHp))
            {
                return(true);
            }

            return(false);
        }
Пример #14
0
        public static async Task <bool> SingleTarget()
        {
            if (await S.Cast(SB.ThrowGlaive, C.CombatColor,
                             (!glaiveTossTimer.IsRunning && VS.VengeanceCombatThrowGlaive) ||
                             (glaiveTossTimer.IsRunning && VS.VengeanceCombatThrowGlaive && glaiveTossTimer.ElapsedMilliseconds > VS.VengeanceCombatThrowGlaiveSeconds), "ST - GlaiveTimer: " + glaiveTossTimer.ElapsedMilliseconds + "ms"))
            {
                glaiveTossTimer.Restart();
                return(true);
            }

            if (await S.Cast(SB.SoulCleave, C.CombatColor,
                             C.CurrentPower >= VS.VengeanceCombatSoulCleavePain &&
                             ((T.VengeanceSpiritBomb && CurrentTarget.HasAura(SB.AuraFrailty) && CurrentTarget.GetAuraById(SB.AuraFrailty).TimeLeft.TotalMilliseconds > 5000) ||
                              (!T.VengeanceSpiritBomb)) &&
                             CurrentTarget.IsWithinMeleeRangeOf(Me),
                             string.Format($"ST: CP:{C.CurrentPower}>={VS.VengeanceCombatSoulCleavePain}")
                             ))
            {
                return(true);
            }

            // cast infernal strike in melee only if we have max chargets
            // it is off of the gcd, so can be cast any time.
            if (await S.CastGroundOnMe(SB.InfernalStrike, C.CombatColor,
                                       VS.VengeanceCombatInfernalStrikeSingleTarget &&
                                       Me.IsWithinMeleeRangeOf(CurrentTarget) &&
                                       S.MaxChargesAvailable(SB.InfernalStrike) &&
                                       CurrentTarget.IsWithinMeleeRangeOf(Me),
                                       "ST Max Charges Available"))
            {
                return(true);
            }


            if (await S.Cast(SB.ImmolationAura, C.CombatColor, CurrentTarget.IsWithinMeleeRangeOf(Me), "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.FelBlade, C.CombatColor, T.VengeanceFelblade, "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.FelEruption, C.CombatColor, T.VengeanceFelEruption && CurrentTarget.IsWithinMeleeRangeOf(Me), "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.SpiritBomb, C.CombatColor, T.VengeanceSpiritBomb && Me.HasAura(SB.AuraSoulFragments) && (!CurrentTarget.HasAura(SB.AuraFrailty) || (CurrentTarget.HasAura(SB.AuraFrailty) && CurrentTarget.GetAuraById(SB.AuraFrailty).TimeLeft.TotalMilliseconds <= 3000)), "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.Shear, C.CombatColor, T.VengeanceBladeTurning && Me.HasAura(SB.AuraBladeTurning) && CurrentTarget.IsWithinMeleeRangeOf(Me), "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.Fracture, C.CombatColor, T.VengeanceFracture && CurrentTarget.IsWithinMeleeRangeOf(Me), "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.SigilOfFlameTalented, C.CombatColor, T.VengeanceConcentratedSigils && CurrentTarget.IsWithinMeleeRangeOf(Me), "ST - Contentrated Sigils"))
            {
                return(true);
            }
            if (await S.CastGround(SB.SigilOfFlame, C.CombatColor, !T.VengeanceConcentratedSigils && !Me.IsWithinMeleeRangeOf(CurrentTarget), "ST - Not in Melee; Cast on target"))
            {
                return(true);
            }
            if (await S.CastGroundOnMe(SB.SigilOfFlame, C.CombatColor, !T.VengeanceConcentratedSigils && Me.IsWithinMeleeRangeOf(CurrentTarget), "ST - In Melee; Cast on self"))
            {
                return(true);
            }
            if (await S.Cast(SB.Shear, C.CombatColor, CurrentTarget.IsWithinMeleeRangeOf(Me), "ST"))
            {
                return(true);
            }



            return(true);
        }
Пример #15
0
        public static async Task <bool> AoE(int count)
        {
            // use metamorphosis in aoe mode
            if (await S.CastGround(SB.MetamorphosisSpell, C.CombatColor, UseMetamorphosisCD(true)))
            {
                return(true);
            }

            // initial Fel Rush with Fel Mastery talent, near the cap, almost 2 charges at > 3 targets or trigger momentum
            if (await S.GCD(SB.FelRush, C.CombatColor,
                            HS.HavocFelRushAoe &&
                            Me.CurrentTarget.Distance <= 18 &&
                            ((T.HavocFelMastery && !S.OnCooldown(SB.VengefulRetreat) && C.MissingPower <= 30 && count >= 3) ||
                             (NeedMomentum())
                            ), "AoE Initial", sleep: false))
            {
                return(true);
            }

            #region Multi-Target Vengeful Retreat
            // use it if we have Prepared talent differently
            if (await S.GCD(SB.VengefulRetreat, C.CombatColor, HS.HavocVengefulReatreatAoe &&
                            C.MissingPower > 45 &&
                            FelRushCheckCharge(true) &&
                            T.HavocPrepared &&
                            Me.IsWithinMeleeRangeOf(CurrentTarget), "AoE")) // and cooldown timer < 500ms (2nd one)
            {
                return(true);
            }

            // use it different if we DO NOT have Prepared talent
            if (await S.GCD(SB.VengefulRetreat, C.CombatColor,
                            HS.HavocVengefulReatreatAoe &&
                            FelRushCheckCharge(true) &&
                            !T.HavocPrepared &&
                            Me.IsWithinMeleeRangeOf(CurrentTarget), "AoE"))      // and cooldown timer < 500ms (2nd one)
            {
                return(true);
            }
            #endregion

            // Fel Rush if we almost hitting max charges with 3 or more
            if (await S.GCD(SB.FelRush, C.CombatColor,
                            HS.HavocFelRushAoe &&
                            Me.CurrentTarget.Distance <= 18 && count >= 3 && FelRushAlmostMaxCharge(), "AoE Max Charges", sleep: false))
            {
                return(true);
            }

            if (await S.Cast(SB.FuryOfTheIllidari, C.CombatColor, UseFuryOfIllidariCD(count >= 3) && CanUseAbilityWithMomentum()))
            {
                return(true);
            }
            if (await S.Cast(SB.FelBarrage, C.CombatColor, count >= 3 && CanUseAbilityWithMomentum() && T.HavocFelBarrage && S.GetCharges(SB.FelBarrage) >= 4 && CurrentTarget.Distance <= 30, "AoE"))
            {
                return(true);
            }
            if (await S.GCD(SB.EyeBeam, C.CombatColor, count >= 3 && CanUseAbilityWithMomentum(), "AoE"))
            {
                return(true);
            }
            if (await S.GCD(SB.BladeDance, C.CombatColor, count >= 3, "AoE"))
            {
                return(true);
            }
            if (await S.Cast(SB.ThrowGlaive, C.CombatColor, count >= 3 && CanUseAbilityWithMomentum() && T.HavocBloodlet && CurrentTarget.Distance <= 30, "AoE"))
            {
                return(true);
            }
            if (await S.Cast(SB.ChaosStrike, C.CombatColor, T.HavocChaosCleave && count <= 3, "AoE"))
            {
                return(true);
            }
            if (await S.Cast(SB.ThrowGlaive, C.CombatColor, count >= 3 && CurrentTarget.Distance <= 30, "AoE"))
            {
                return(true);
            }
            if (await S.Cast(SB.ChaosStrike, C.CombatColor, (C.CurrentPower >= 70 && !T.HavocDemonBlades) || (C.CurrentPower >= 60 && T.HavocDemonBlades), "AoE"))
            {
                return(true);
            }
            if (await S.Cast(SB.DemonsBite, C.CombatColor, !T.HavocDemonBlades, "AoE"))
            {
                return(true);
            }

            return(false);
        }
Пример #16
0
        /// <summary>
        /// this is the opening rotation for single target. Once activated, it will continue to use these abilities until it has been fulfilled and then reset again.
        /// </summary>
        /// <returns></returns>
        public static async Task <bool> OpeningRotationSingleTarget()
        {
            //L.debugLog("UseRotation:" + (!useOpenRotation).ToString() + ", FelRushOnPull:" + (HS.HavocFelRushOnPull).ToString() + ", UseMetaCd:" + UseMetamorphosisCD(false).ToString() + ", FRMaxCharges:" + S.MaxChargesAvailable(SB.FelRush).ToString() + ", FRChargesNoFelMastery:" + (S.GetSpellChargeInfo(SB.FelRush).ChargesLeft >= 1 && !T.HavocFelMastery).ToString() + ", MetaCD:" + (!S.OnCooldown(SB.MetamorphosisSpell)).ToString());

            if ((useOpenRotation && (openRotationTimeout.ElapsedMilliseconds > 5000 && openingRotationSkillsUsed != OpenerSteps.FuryBuilder) || openRotationTimeout.ElapsedMilliseconds > 10000 && openingRotationSkillsUsed == OpenerSteps.FuryBuilder))
            {
                useOpenRotation           = false;
                openingRotationSkillsUsed = OpenerSteps.None;
                L.infoLog("Opener Rotation timed out.", C.InfoColor);
                return(false);
            }



            if (!useOpenRotation && (HS.HavocFelRushOnPull && UseMetamorphosisCD(false) &&
                                     (S.MaxChargesAvailable(SB.FelRush) ||                                      // make sure we have max charges saved up.
                                      (S.GetSpellChargeInfo(SB.FelRush).ChargesLeft >= 1 && !T.HavocFelMastery) // also check for 1 charge if no fel mastery.
                                     ) &&
                                     !S.OnCooldown(SB.MetamorphosisSpell) &&                                    // make sure metamorphosis is not on cd.
                                     CurrentTarget.Distance < 25))                                              // make sure we aren't too far away.
            {
                L.infoLog("Ready for Havoc Single Target Opener: " + openingRotationSkillsUsed, C.HavocOpenerColor);
                useOpenRotation           = true;
                openingRotationSkillsUsed = OpenerSteps.InitialFelRush;
                openRotationTimeout.Restart();
                return(true);
            }

            if (useOpenRotation)
            {
                //L.debugLog(openingRotationSkillsUsed.ToString());
                if (openingRotationSkillsUsed == OpenerSteps.InitialFelRush)
                {
                    // we haven't used an ability yet for opener, let's fel rush
                    if (await S.GCD(SB.FelRush, C.HavocOpenerColor, CurrentTarget.Distance <= 15 && Me.IsSafelyFacing(CurrentTarget), "Opener 1"))
                    {
                        openingRotationSkillsUsed = OpenerSteps.FelMasteryFelRush;
                        openRotationTimeout.Restart();
                        return(true);
                    }
                }

                if (openingRotationSkillsUsed == OpenerSteps.FelMasteryFelRush)
                {
                    //L.debugLog("Made it to FelMasteryFelRush : HasFelMastery:" + T.HavocFelMastery + ", HasMomentum: " + Me.HasAnyAura("Momentum"));
                    if (await S.GCD(SB.FelRush, C.HavocOpenerColor,
                                    T.HavocFelMastery && NeedMomentum(), "Opener 2 - Fel Mastery 2nd Fel Rush"))
                    {
                        openingRotationSkillsUsed = OpenerSteps.FuryBuilder;
                        openRotationTimeout.Restart();
                        return(true);
                    }
                    // if we don't have fel mastery talent, just bump the rotation.
                    // really should have it, but just in case someone thinks they know better ;]
                    if (!T.HavocFelMastery)
                    {
                        L.combatLog("Skipping Opener 2; No Fel Mastery talent", C.HavocOpenerColor);
                        openingRotationSkillsUsed = OpenerSteps.FuryBuilder;
                        openRotationTimeout.Restart();
                        return(true);
                    }
                }

                if (openingRotationSkillsUsed == OpenerSteps.FuryBuilder)
                {
                    if (await S.GCD(SB.DemonsBite, C.HavocOpenerColor, !T.HavocDemonBlades, "Opener 3, building Fury"))
                    {
                        return(true);
                    }


                    // if we have demon blades, we want to passively get <=20 missing fury.
                    if (T.HavocDemonBlades && C.MissingPower > 20)
                    {
                        L.combatLog("Opener 3, passively building fury", C.HavocOpenerColor);
                    }
                    if (C.MissingPower <= 20)
                    {
                        openingRotationSkillsUsed = OpenerSteps.FaceAwayFromTarget;
                        return(true);
                    }
                }

                // make sure we have max charges saved up.
                if (openingRotationSkillsUsed == OpenerSteps.FaceAwayFromTarget)
                {
                    // we don't want to be safely facing
                    if (Me.IsSafelyFacing(CurrentTarget.Location))
                    {
                        await FaceAwayFromTarget();

                        openingRotationSkillsUsed = OpenerSteps.VengefulRetreat;
                    }
                }
                //if (openingRotationSkillsUsed == OpenerSteps.VengefulRetreat && !Me.IsSafelyFacing(CurrentTarget))
                //{
                //    // wait until you are safely facing.
                //    return true;
                //}

                if (openingRotationSkillsUsed == OpenerSteps.VengefulRetreat && !Me.IsSafelyFacing(CurrentTarget.Location))
                {
                    if (await S.Cast(SB.VengefulRetreat, C.HavocOpenerColor, T.HavocPrepared || T.HavocMomentum, "Opener 4"))
                    {
                        openingRotationSkillsUsed = OpenerSteps.Nemesis;
                        return(true);
                    }
                }

                if (openingRotationSkillsUsed == OpenerSteps.Nemesis)
                {
                    if (await S.Cast(SB.Nemesis, C.HavocOpenerColor, T.HavocNemesis, "Opener 5"))
                    {
                        openingRotationSkillsUsed = OpenerSteps.Metamorphosis;
                        return(true);
                    }
                    if (!T.HavocNemesis)
                    {
                        L.combatLog("Skip Opener 5 - Nemesis.  No talent selected", C.HavocOpenerColor);
                        openingRotationSkillsUsed = OpenerSteps.Metamorphosis;
                        return(true);
                    }
                }
                if (openingRotationSkillsUsed == OpenerSteps.Metamorphosis)
                {
                    // if in melee, need to cast on yourself.  If in ranged, cast on target.
                    if (await S.CastGround(SB.MetamorphosisSpell, C.HavocOpenerColor, !Me.IsWithinMeleeRangeOf(CurrentTarget), "Opener 6 - Cast on Target"))
                    {
                        openingRotationSkillsUsed = OpenerSteps.ChaosBlades;
                        return(true);
                    }
                    if (await S.CastGroundOnMe(SB.MetamorphosisSpell, C.HavocOpenerColor, Me.IsWithinMeleeRangeOf(CurrentTarget), "Opener 6 - Cast on Me"))
                    {
                        // if we did metamorphosis then that's our last ability we can now continue single target
                        openingRotationSkillsUsed = OpenerSteps.ChaosBlades;
                        return(true);
                    }
                }
                if (openingRotationSkillsUsed == OpenerSteps.ChaosBlades)
                {
                    if (await S.Cast(SB.ChaosBlades, C.HavocOpenerColor, T.HavocChaosBlades, "Opener 7"))
                    {
                        useOpenRotation           = false;
                        openingRotationSkillsUsed = OpenerSteps.None;
                    }
                    if (!T.HavocChaosBlades)
                    {
                        useOpenRotation           = false;
                        openingRotationSkillsUsed = OpenerSteps.None;
                        return(true);
                    }
                }
                await S.Cast(SB.DemonsBite, C.HavocOpenerColor, !T.HavocDemonBlades && Me.IsWithinMeleeRangeOf(CurrentTarget), "Opener, Filler");
            }
            return(useOpenRotation);
        }
Пример #17
0
        public static async Task <bool> SingleTarget()
        {
            // we only want to use the single target rotation after the open rotation is finished.
            if (await S.CastGround(SB.MetamorphosisSpell, C.CombatColor, UseMetamorphosisCD(false)))
            {
                return(true);
            }

            if (await RushST())
            {
                return(true);
            }

            #region Single-Target Vengeful Retreat


            //use it if we have Prepared talent differently
            if (await S.GCD(SB.VengefulRetreat, C.CombatColor,
                            HS.HavocVengefulReatreatSingleTarget &&
                            C.MissingPower > 30 &&
                            (FelRushCheckCharge(true)) &&
                            T.HavocPrepared &&
                            Me.IsWithinMeleeRangeOf(CurrentTarget), "ST1", sleep: false))
            //{ felRushAfterVengefulRetreat.Restart(); C.fallingTimeout.Restart(); return true; }
            {
                return(true);
            }

            // use it if we DO NOT have Prepared talent without Fury check
            if (await S.GCD(SB.VengefulRetreat, C.CombatColor,
                            HS.HavocVengefulReatreatAoe &&
                            (FelRushCheckCharge(true)) &&
                            !T.HavocPrepared &&
                            Me.IsWithinMeleeRangeOf(CurrentTarget), "ST2", sleep: false))
            //{ felRushAfterVengefulRetreat.Restart(); C.fallingTimeout.Restart(); return true; }
            {
                return(true);
            }


            #endregion

            #region Single-Target Fel Rush
            // use this in combination with vengeful retreat
            //if (await S.Cast(SB.FelRush, C.CombatColor, HS.HavocFelRushSingleTarget && S.OnCooldown(SB.VengefulRetreat)
            //    //&& felRushAfterVengefulRetreat.ElapsedMilliseconds <= 2000
            //    && T.HavocFelMastery
            //    && Me.CurrentTarget.Distance <= 18
            //    && C.MissingPower <= 30,
            //"ST 1"))
            //{ felRushAfterVengefulRetreat.Reset(); return true; }
            //{ return true; }

            // use to engage
            if (await S.Cast(SB.FelRush, C.CombatColor, HS.HavocFelRushSingleTarget &&
                             !Me.IsWithinMeleeRangeOf(CurrentTarget) && CurrentTarget.Distance <= 18, "ST 2"))
            //{ felRushAfterVengefulRetreat.Reset(); return true; }
            {
                return(true);
            }
            #endregion

            // if we have used vengeful retreat, don't do anything else until we fel rush
            //if (felRushAfterVengefulRetreat.IsRunning && felRushAfterVengefulRetreat.ElapsedMilliseconds <= 2000) { return true; }

            // fel rush, almost max charges and needs momentum
            if (await S.Cast(SB.FelRush, C.CombatColor, HS.HavocFelRushSingleTarget && Me.IsWithinMeleeRangeOf(CurrentTarget) &&
                             FelRushAlmostMaxCharge() &&
                             NeedMomentum(true), "ST - Fel Rush for Momentum"))
            {
                return(true);
            }
            if (await S.Cast(SB.EyeBeam, C.CombatColor, T.HavocDemonic && CurrentTarget.Distance <= 10, "ST - Demonic talent"))
            {
                return(true);
            }
            if (await S.Cast(SB.FelEruption, C.CombatColor, T.HavocFelEruption && CurrentTarget.Distance <= 20, "ST"))
            {
                return(true);
            }
            L.debugLog(CanUseAbilityWithMomentum().ToString() + ", " + Me.IsWithinMeleeRangeOf(CurrentTarget).ToString() + ", " + UseFuryOfIllidariCD(false).ToString());
            if (await S.Cast(SB.FuryOfTheIllidari, C.CombatColor, CanUseAbilityWithMomentum() && Me.IsWithinMeleeRangeOf(CurrentTarget) &&
                             UseFuryOfIllidariCD(false), "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.BladeDance, C.CombatColor, CanUseAbilityWithMomentum() && T.HavocFirstBlood && Me.IsWithinMeleeRangeOf(CurrentTarget), "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.FelBlade, C.CombatColor, C.MissingPower <= 30 && CurrentTarget.Distance <= 15, "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.ThrowGlaive, C.CombatColor, CanUseAbilityWithMomentum() && T.HavocBloodlet && CurrentTarget.Distance <= 30, "ST"))
            {
                return(true);
            }
            //if (await S.Cast(SB.FelBarrage, C.CombatColor, NeedMomentum() && T.HavocFelBarrage && S.GetCharges(SB.FelBarrage) >= 5, "ST")) { return true; }
            if (await S.Cast(SB.ChaosStrike, C.CombatColor, C.MissingPower <= 30 && Me.HasAnyTempAura("Metamorphosis") && Me.IsWithinMeleeRangeOf(CurrentTarget), "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.EyeBeam, C.CombatColor, Me.HasAura(SB.AuraAnguishOfTheDeceiver) && CurrentTarget.Distance <= 10, "ST - Has Eye of the Deceiver Trait"))
            {
                return(true);
            }
            if (await S.Cast(SB.ChaosStrike, C.CombatColor, C.MissingPower <= 30 && Me.IsWithinMeleeRangeOf(CurrentTarget), "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.FelBarrage, C.CombatColor, CanUseAbilityWithMomentum() && T.HavocFelBarrage && S.GetCharges(SB.FelBarrage) >= 4 && CurrentTarget.Distance <= 30, "ST"))
            {
                return(true);
            }
            if (await S.Cast(SB.DemonsBite, C.CombatColor, !T.HavocDemonBlades && Me.IsWithinMeleeRangeOf(CurrentTarget) && !S.MaxChargesAvailable(SB.ThrowGlaive), "ST"))
            {
                return(true);
            }

            // melee range with Demon Blades
            if (await S.Cast(SB.ThrowGlaive, C.CombatColor,
                             Me.IsWithinMeleeRangeOf(CurrentTarget), "ST"))
            {
                return(true);
            }

            // nothing else to do so let's throw a glaive
            if (await S.Cast(SB.ThrowGlaive, C.CombatColor,
                             !Me.IsWithinMeleeRangeOf(CurrentTarget), "ST"))
            {
                return(true);
            }
            return(false);
        }
Пример #18
0
 static bool FelRushAlmostMaxCharge()
 {
     return(S.GetSpellChargeInfo(SB.FelRush).ChargesLeft >= 1 && S.GetSpellChargeInfo(SB.FelRush).TimeUntilNextCharge.TotalMilliseconds < 500);
 }
Пример #19
0
        public static async Task <bool> RotationSelector()
        {
            // we are playing manual, i am not alive, or I am mounted or on taxi, do not continue
            if (HK.manualOn || !Me.IsAlive || (Me.OnTaxi) || Me.IsCasting || Me.IsChanneling)
            {
                return(true);
            }
            // if I

            // i don't want facing to interfere with vengeful retreat opener.
            if (openingRotationSkillsUsed != OpenerSteps.FaceAwayFromTarget && openingRotationSkillsUsed != OpenerSteps.VengefulRetreat)
            {
                if (GS.GeneralFacing)
                {
                    // check to see if we need to face target
                    await C.FaceTarget(CurrentTarget);
                }
            }

            if (GS.GeneralMovement)
            {
                // ensure we are in melee range and not too close
                await C.EnsureMeleeRange(CurrentTarget);
            }

            if (CurrentTarget.IsValidCombatUnit())
            {
                if (await OpeningRotationSingleTarget())
                {
                    return(true);
                }

                #region Offensive Hotkey
                if (HK.HavocOffensiveOn)
                {
                    // we have offensive cooldowns enabled, let's use them if they are available first.
                    if (await I.UseItem(I.GetItemByID(HS.HavocHealthPotionID), HKS.HotkeyHavocOffensiveAgilityPotion))
                    {
                        return(true);
                    }
                    if (await S.Cast(SB.MetamorphosisSpell, C.CombatColor, HKS.HotkeyHavocOffensiveMetamorphosis))
                    {
                        return(true);
                    }
                    if (await S.Cast(SB.FuryOfTheIllidari, C.CombatColor, HKS.HotkeyHavocOffensiveFoTI))
                    {
                        return(true);
                    }
                    if (await S.Cast(SB.Nemesis, C.CombatColor, HKS.HotkeyHavocOffensiveNemesis))
                    {
                        return(true);
                    }
                    if (await S.Cast(SB.ChaosBlades, C.CombatColor, HKS.HotkeyHavocOffensiveChaosBlades))
                    {
                        return(true);
                    }
                }
                #endregion
                // see if we need any defensive cooldowns
                if (await SaveMe())
                {
                    return(true);
                }

                if ((HK.HavocAoEOn || U.activeEnemies(Me.Location, 8f).Count() >= 2))
                {
                    // try to use aoe abilities
                    if (await AoE(U.activeEnemies(Me.Location, 8f).Count()))
                    {
                        return(true);
                    }
                    // we were supposed to aoe, but nothing to use for aoe (or jumped back out of melee), so use single target
                    if (await AoEDashing(U.activeEnemies(Me.Location, 8f).Count()))
                    {
                        return(true);
                    }
                }



                // default to single target if nothing else
                return(await SingleTarget());
            }
            return(false);
        }