예제 #1
0
 private static void initializeTalents(object sender, LuaEventArgs args)
 {
     L.infoLog("Event triggered: " + args.EventName, C.InfoColor);
     //WriteDebugLuaEvents(args);
     setTalents();
     //printTalents();
 }
예제 #2
0
 private static void updateTalentManager(object sender, LuaEventArgs args)
 {
     L.infoLog("------------------", C.InfoColor);
     L.infoLog("Talents changed...", C.InfoColor);
     initTalents();
     printTalents();
 }
예제 #3
0
        /// <summary>
        /// Does not specify a target when casting a spell and sleeps for lag
        /// </summary>
        /// <param name="Spell">The spell you wish to cast.</param>
        /// <param name="reqs">The requirements to cast the spell.</param>
        /// <returns></returns>
        public static async Task <bool> GCD(int Spell, System.Windows.Media.Color newColor, bool reqs = true, string addLog = "", bool sleep = true)
        {
            if (!reqs)
            {
                //L.combatLog("Trying to cast: " + WoWSpell.FromId(Spell).Name + (String.IsNullOrEmpty(addLog) ? "" : " - " + addLog));
                return(false);
            }
            //if (SpellManager.GlobalCooldown || !SpellManager.CanCast(Spell))
            //    return false;
            if (OnCooldown(Spell))
            {
                return(false);
            }
            if (!SpellManager.Cast(Spell))
            {
                return(false);
            }
            lastSpellCast = Spell;
            L.combatLog("*" + WoWSpell.FromId(Spell).Name + (String.IsNullOrEmpty(addLog) || !GeneralSettings.Instance.GeneralDebug ? "" : " - " + addLog), newColor);
            if (sleep)
            {
                await CommonCoroutines.SleepForLagDuration();
            }
            else
            {
                await Coroutine.Yield();
            }

            return(true);
        }
예제 #4
0
        public static bool Cast2(int Spell, System.Windows.Media.Color newColor, bool reqs = true, string addLog = "", bool sleep = true)
        {
            //if (Spell == Helpers.Spell_Book.Glide)
            //{
            //    L.debugLog("Glide: " + reqs.ToString());
            //}

            if (!currentTarget.IsValidCombatUnit())
            {
                return(false);
            }
            if (!reqs)
            {
                //L.combatLog("Trying to cast: " + WoWSpell.FromId(Spell).Name + (String.IsNullOrEmpty(addLog) ? "" : " - " + addLog));
                return(false);
            }

            if (!SpellManager.CanCast(WoWSpell.FromId(Spell), currentTarget, false, false, false)) //Should we check for if out currentTarget is moving? *Second false
            {
                return(false);
            }
            if (!SpellManager.Cast(Spell, currentTarget))
            {
                return(false);
            }
            lastSpellCast = Spell;
            L.combatLog("^" + WoWSpell.FromId(Spell).Name + (String.IsNullOrEmpty(addLog) || !GeneralSettings.Instance.GeneralDebug ? "" : " - " + addLog), newColor);

            return(true);
        }
예제 #5
0
        public static async Task <bool> FaceTarget(WoWUnit target)
        {
            if (target == null || Me.IsSafelyFacing(target) || !target.IsValidCombatUnit() || HK.RotationOnlyOn || !GeneralSettings.Instance.GeneralFacing)
            {
                return(false);
            }

            if (!lastTimeFaced.IsRunning || (target.Guid == lastUnitGuid && lastTimeFaced.ElapsedMilliseconds > 500))
            {
                L.infoLog("Not facing target; will attempt to", InfoColor);
            }

            target.Face();



            lastUnitGuid = target.Guid;
            if (Me.IsWithinMeleeRangeOf(target) && Me.IsMoving && GeneralSettings.Instance.GeneralMovement && !Managers.Hotkeys.RotationOnlyOn)
            {
                return(await CommonCoroutines.StopMoving());
            }
            if (!lastTimeFaced.IsRunning)
            {
                lastTimeFaced.Start();
            }
            else
            {
                lastTimeFaced.Restart();
            }
            await Coroutine.Yield();

            return(true);
        }
예제 #6
0
        public static bool ShouldInterrupt(this WoWUnit unit, int minTime, int timeLeft)
        {
            if (Me.Specialization == WoWSpec.DemonHunterVengeance)
            {
                if ((unit.IsCasting || unit.IsCastingHealingSpell) && unit.CanInterruptCurrentSpellCast)
                {
                    // if casting, healing or channeling, and can interrupt
                    //L.debugLog("Unit: " + unit.SafeName + " is casting and can interrupt");

                    double castingForHowLong = new TimeSpan(DateTime.Now.Ticks - unit.CurrentCastStartTime.Ticks).TotalMilliseconds;
                    L.debugLog("Unit: " + unit.SafeName + " is casting and can interrupt. castingForHowLong: " + castingForHowLong + ", timeLeft: " + unit.CurrentCastTimeLeft.TotalMilliseconds);
                    if (minTime > 0 && timeLeft > 0)
                    {
                        if (castingForHowLong >= minTime && unit.CurrentCastTimeLeft.TotalMilliseconds < timeLeft)
                        {
                            L.debugLog("Should interrupt now");
                            return(true);
                        }
                    }
                    else
                    {
                        if ((minTime > 0 && castingForHowLong >= minTime) || (timeLeft > 0 && unit.CurrentCastTimeLeft.TotalMilliseconds < timeLeft))
                        {
                            L.debugLog("Should interrupt now");
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
예제 #7
0
        public static async Task <bool> CastGroundOnMe(int Spell, System.Windows.Media.Color newColor, bool reqs = true, string addLog = "")
        {
            foreach (var item in GroundSpellBlacklist)
            {
                if (item.SpellId == Spell && item.IsBlacklisted())
                {
                    return(false);
                }
            }
            if (!reqs)
            {
                return(false);
            }
            //L.combatLog("Trying to cast: " + WoWSpell.FromId(Spell).Name + (String.IsNullOrEmpty(addLog) ? "" : " - " + addLog));
            if (!SpellManager.CanCast(WoWSpell.FromId(Spell)))
            {
                return(false);
            }

            if (await GCD(Spell, newColor, true, "CastGround") &&
                !await Coroutine.Wait(1000, () => Me.CurrentPendingCursorSpell != null))
            {
                AddSpellToBlacklist(Spell);
                L.diagnosticsLog("No Cursor Detected");
                return(false);
            }
            lastSpellCast = Spell;
            if (SpellManager.ClickRemoteLocation(Me.Location) == false)
            {
                AddSpellToBlacklist(Spell);
            }
            await CommonCoroutines.SleepForLagDuration();

            return(true);
        }
예제 #8
0
        public static async Task <bool> EnsureMeleeRange(WoWUnit target)
        {
            if (target == null || Me.IsWithinMeleeRangeOf(target) || !target.IsValidCombatUnit() ||
                Me.IsCasting || Me.IsChanneling || HK.RotationOnlyOn || !GeneralSettings.Instance.GeneralMovement)
            {
                return(false);
            }

            L.infoLog("Getting in melee range", InfoColor);
            if (Me.IsWithinMeleeRangeOf(target))
            {
                return(await CommonCoroutines.StopMoving());
            }
            if (!Me.IsWithinMeleeRangeOf(target))
            {
                if (await Spell.Cast(Spell_Book.Glide, CombatColor, ShouldGlideForVengefulRetreat, "May have jumped too far back.  Gliding back in."))
                {
                    fallingTimeout.Reset();
                    return(true);
                }

                await CommonCoroutines.MoveTo(target.RelativeLocation, target.SafeName);
            }
            return(true);
        }
예제 #9
0
        private static void talentSpecChanged(object sender, LuaEventArgs args)
        {
            //TODO: Remove after all 3 Spec supported

            L.infoLog("PLAYER_SPECIALIZATION_CHANGED - Spec changed to {0}.- {1}", C.InfoColor, Me.Specialization, args.EventName);
            initializeTalents(sender, args);
            //onSpecChanged(args);
        }
예제 #10
0
        private static void WriteDebugLuaEvents(LuaEventArgs args)
        {
            int i = 0;

            foreach (var arg in args.Args)
            {
                L.debugLog("Arg[{0}]:{1}", i, arg);
                i += 1;
            }
        }
예제 #11
0
 public static uint luaGetMaxPower()
 {
     try
     {
         using (StyxWoW.Memory.AcquireFrame()) { return(Lua.GetReturnVal <uint>("return UnitPowerMax(\"player\");", 0)); }
     }
     catch (Exception xException)
     {
         L.diagnosticsLog("Exception in luaGetMaxPower(); ", xException);
         return(Me.CurrentPower);
     }
 }
예제 #12
0
 /// <summary>
 /// How much time (in milliseconds) is left on the cooldown of a spell
 /// </summary>
 /// <param name="Spell">The integer based spell id</param>
 /// <returns></returns>
 public static double CooldownTimeLeft(int Spell)
 {
     try
     {
         SpellFindResults Results;
         return(SpellManager.FindSpell(Spell, out Results) ? (Results.Override != null ? Results.Override.CooldownTimeLeft.TotalMilliseconds : Results.Original.CooldownTimeLeft.TotalMilliseconds) : 9999);
     }
     catch (Exception xException)
     {
         L.diagnosticsLog("Exception in cooldownTimeLeft(); ", xException);
         return(0000);
     }
 }
예제 #13
0
 public static SpellChargeInfo GetSpellChargeInfo(int Spell)
 {
     try
     {
         SpellFindResults Results;
         SpellManager.FindSpell(Spell, out Results);
         return(Results.Override != null ? Results.Override.GetChargeInfo() : Results.Original.GetChargeInfo());
     }
     catch (Exception xException)
     {
         L.diagnosticsLog("Exception in cooldownTimeLeft(); ", xException);
         return(null);
     }
 }
예제 #14
0
파일: Unit.cs 프로젝트: hbcode2/Illidari
 public static double auraTimeLeft(WoWUnit Unit, int auraID, bool isMyAura = false)
 {
     try
     {
         if (Unit == null || !Unit.IsValid)
         {
             return(0);
         }
         WoWAura Aura = isMyAura ? Unit.GetAllAuras().FirstOrDefault(A => A.SpellId == auraID && A.CreatorGuid == Me.Guid) : Unit.GetAllAuras().FirstOrDefault(A => A.SpellId == auraID);
         return(Aura != null ? Aura.TimeLeft.TotalMilliseconds : 0);
     }
     catch (Exception xException)
     {
         L.diagnosticsLog("Exception in auraExists(); ", xException);
         return(9999);
     }
 }
예제 #15
0
 /// <summary>
 /// Determine from SPellFindResults if the spell is on cooldown or not.
 /// </summary>
 /// <param name="Spell"></param>
 /// <returns></returns>
 public static bool OnCooldown(int Spell)
 {
     try
     {
         SpellFindResults Results;
         if (SpellManager.FindSpell(Spell, out Results))
         {
             return(Results.Override != null ? Results.Override.Cooldown : Results.Original.Cooldown);
         }
         return(false);
     }
     catch (Exception xException)
     {
         L.diagnosticsLog("Exception in cooldownTimeLeft(); ", xException);
         return(false);
     }
 }
예제 #16
0
파일: Unit.cs 프로젝트: hbcode2/Illidari
 public static uint auraStacks(WoWUnit Unit, int auraID, bool isMyAura = false)
 {
     try
     {
         if (Unit == null || !Unit.IsValid)
         {
             return(0);
         }
         WoWAura Aura = isMyAura ? Unit.GetAllAuras().FirstOrDefault(A => A.SpellId == auraID && A.CreatorGuid == Me.Guid) : Unit.GetAllAuras().FirstOrDefault(A => A.SpellId == auraID);
         return(Aura != null ? Aura.StackCount : 0);
     }
     catch (Exception xException)
     {
         L.diagnosticsLog("Exception in auraStacks(); ", xException);
         return(0);
     }
 }
예제 #17
0
 private bool GetNewTarget()
 {
     if (!Me.CurrentTarget.IsValidCombatUnit() && !HK.RotationOnlyOn)
     {
         var newUnits = U.activeEnemies(Me.Location, 50f).OrderBy(u => u.Distance).ThenBy(u => u.HealthPercent);
         L.debugLog("Number of new units: " + newUnits.Count());
         if (newUnits != null)
         {
             var newUnit = newUnits.FirstOrDefault();
             if (newUnit != null)
             {
                 L.pullMobLog(string.Format($"Switch target to {newUnit.SafeName} at {newUnit.Distance.ToString("F0")} yds @ {newUnit.HealthPercent.ToString("F0")}% HP"), Core.Helpers.Common.TargetColor);
                 newUnit.Target();
                 return(true);
             }
         }
     }
     return(false);
 }
예제 #18
0
        /// <summary>
        /// Casts a spell on yourself
        /// </summary>
        /// <param name="Spell">The spell you want to cast.</param>
        /// <param name="reqs">The requirements to cast the spell.</param>
        /// <returns></returns>
        public static async Task <bool> Buff(int Spell, System.Windows.Media.Color newColor, bool reqs = true, string addLog = "")
        {
            if (!reqs)
            {
                return(false);
            }
            if (!SpellManager.CanCast(WoWSpell.FromId(Spell), Me, false, false, false)) //Should we check for if we are moving? *Second false
            {
                return(false);
            }
            if (!SpellManager.Cast(Spell, Me))
            {
                return(false);
            }
            lastSpellCast = Spell;
            L.defensiveLog("~" + WoWSpell.FromId(Spell).Name + (String.IsNullOrEmpty(addLog) || !GeneralSettings.Instance.GeneralDebug ? "" : " - " + addLog), newColor);
            await CommonCoroutines.SleepForLagDuration();

            return(true);
        }
예제 #19
0
파일: Item.cs 프로젝트: hbcode2/Illidari
        public static async Task <bool> UseItem(WoWItem item, bool reqs, string log = null)
        {
            if (item == null)
            {
                return(false);
            }
            if (!reqs)
            {
                return(false);
            }
            if (!CanUseItem(item))
            {
                return(false);
            }

            L.useItemLog(string.Format($"/use {item.Name}" + (String.IsNullOrEmpty(log) || !GeneralSettings.Instance.GeneralDebug ? "" : " - " + log)), Core.Helpers.Common.ItemColor);
            item.Use();
            await CommonCoroutines.SleepForLagDuration();

            return(true);
        }
예제 #20
0
        public static async Task <bool> DeathBehavor()
        {
            if (Me.IsDead)
            {
                L.infoLog(DateTime.Now.ToString("mm:ss:ffffff") + " RepopMe()", Core.Helpers.Common.InfoColor);
                Lua.DoString("RepopMe()");
            }

            if (Me.IsGhost)
            {
                if (Battlegrounds.IsInsideBattleground || Me.CurrentMap.Name == "Ashran")
                {
                    L.infoLog(DateTime.Now.ToString("mm:ss:ffffff") + " Waiting for spirit rez", Core.Helpers.Common.InfoColor);
                    await Coroutine.Sleep(1500);
                }
                else
                {
                    L.infoLog(DateTime.Now.ToString("mm:ss:ffffff") + " Move to corpse", Core.Helpers.Common.InfoColor);
                    await CommonCoroutines.MoveTo(Me.CorpsePoint);
                }
            }
            return(false);
        }
예제 #21
0
        /// <summary>
        /// Does not specify a target when casting a spell and sleeps for lag
        /// </summary>
        /// <param name="Spell">The spell you wish to cast.</param>
        /// <param name="reqs">The requirements to cast the spell.</param>
        /// <returns></returns>
        public static async Task <bool> GcdOnTarget(int Spell, WoWUnit target, System.Windows.Media.Color newColor, bool reqs = true, string addLog = "")
        {
            if (!reqs)
            {
                //L.combatLog("Trying to cast: " + WoWSpell.FromId(Spell).Name + (String.IsNullOrEmpty(addLog) ? "" : " - " + addLog));
                return(false);
            }
            //if (SpellManager.GlobalCooldown || !SpellManager.CanCast(Spell))
            //    return false;
            if (OnCooldown(Spell))
            {
                return(false);
            }
            if (!SpellManager.Cast(Spell, target))
            {
                return(false);
            }
            lastSpellCast = Spell;
            L.combatLog("*" + WoWSpell.FromId(Spell).Name + (String.IsNullOrEmpty(addLog) || !GeneralSettings.Instance.GeneralDebug ? "" : " - " + addLog), newColor);
            await CommonCoroutines.SleepForRandomReactionTime();

            return(true);
        }
예제 #22
0
        private bool GetTauntTarget()
        {
            if (Me.Specialization == WoWSpec.DemonHunterVengeance && VengeanceSettings.Instance.VengeanceAllowTaunt && !HK.RotationOnlyOn)
            {
                U.enemiesToTauntAnnex(50f);

                if (U.activeEnemiesToTaunt(Me.Location, 40f).Any())
                {
                    IEnumerable <WoWUnit> tauntEnemies = U.activeEnemiesToTaunt(Me.Location, 40f);
                    if (tauntEnemies != null)
                    {
                        var tauntEnemy = tauntEnemies.OrderBy(u => u.Distance).FirstOrDefault();
                        if (tauntEnemy != null)
                        {
                            L.pullMobLog(string.Format($"Switch taunt target to {tauntEnemy.SafeName} at {tauntEnemy.Distance.ToString("F0")} yds @ {tauntEnemy.HealthPercent.ToString("F0")}% HP"), Core.Helpers.Common.TargetColor);
                            tauntEnemy.Target();
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
예제 #23
0
 private static void playerTalentUpdate(object sender, LuaEventArgs args)
 {
     L.infoLog("PLAYER_TALENT_UPDATE - Event triggered: " + args.EventName, C.InfoColor);
     initializeTalents(sender, args);
 }
예제 #24
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);
        }
예제 #25
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);
        }
예제 #26
0
        public Vector3 FindLocation(Vector3 ptOrigin)
        {
            DateTime startFind              = DateTime.UtcNow;
            int      countPointsChecked     = 0;
            int      countFailDiff          = 0;
            int      countFailTrace         = 0;
            int      countFailToPointNav    = 0;
            int      countFailRange         = 0;
            int      countFailSafe          = 0;
            int      countFailToPointLoS    = 0;
            int      countFailToMobLoS      = 0;
            TimeSpan spanTrace              = TimeSpan.Zero;
            TimeSpan spanNav                = TimeSpan.Zero;
            double   furthestNearMobDistSqr = 0f;
            Vector3  ptFurthest             = Vector3.Zero;
            float    facingFurthest         = 0f;

            bool    reallyCheckRangeToLineOfSightMob = CheckRangeToLineOfSightMob && Me.GotTarget;
            Vector3 ptAdjOrigin = ptOrigin;
            // ptAdjOrigin.Z += 1f;   // comment out origin adjustment since using GetTraceLinePos()

            Vector3        ptDestination = new Vector3();
            List <Vector3> mobLocations  = new List <Vector3>();
            float          arcIncrement  = ((float)Math.PI * 2) / RaysToCheck;

            mobLocations = AllEnemyMobLocationsToCheck;
            double minSafeDistSqr = MinSafeDistance * MinSafeDistance;

            float baseDestinationFacing;

            if (PreferredDirection == Direction.None && MobToRunFrom != null)
            {
                baseDestinationFacing = Styx.Helpers.WoWMathHelper.CalculateNeededFacing(MobToRunFrom.Location, Me.Location);
            }
            else if (PreferredDirection == Direction.Frontwards)
            {
                baseDestinationFacing = Me.RenderFacing;
            }
            else // if (PreferredDirection == Disengage.Direction.Backwards)
            {
                baseDestinationFacing = Me.RenderFacing + (float)Math.PI;
            }

            L.debugLog("SafeArea: facing {0:F0} degrees, looking for safespot towards {1:F0} degrees", C.DefensiveColor,
                       WoWMathHelper.RadiansToDegrees(Me.RenderFacing),
                       WoWMathHelper.RadiansToDegrees(baseDestinationFacing)
                       );

            for (int arcIndex = 0; arcIndex < RaysToCheck; arcIndex++)
            {
                // rather than tracing around the circle, toggle between clockwise and counter clockwise for each test
                // .. so we favor a position furthest away from mob
                float checkFacing = baseDestinationFacing;
                if ((arcIndex & 1) == 0)
                {
                    checkFacing += arcIncrement * (arcIndex >> 1);
                }
                else
                {
                    checkFacing -= arcIncrement * ((arcIndex >> 1) + 1);
                }

                checkFacing = WoWMathHelper.NormalizeRadian(checkFacing);
                for (float distFromOrigin = MinScanDistance; distFromOrigin <= MaxScanDistance; distFromOrigin += IncrementScanDistance)
                {
                    countPointsChecked++;

                    ptDestination = ptOrigin.RayCast(checkFacing, distFromOrigin);

                    L.debugLog("SafeArea: checking {0:F1} degrees at {1:F1} yds", WoWMathHelper.RadiansToDegrees(checkFacing), distFromOrigin);

                    DateTime start     = DateTime.UtcNow;
                    bool     failTrace = MeshTraceline(Me.Location, ptDestination);
                    spanTrace += DateTime.UtcNow - start;

                    bool failNav;
                    if (DirectPathOnly)
                    {
                        failNav = failTrace;
                        spanNav = spanTrace;
                    }
                    else
                    {
                        start   = DateTime.UtcNow;
                        failNav = false;
                        //failNav = !Navigator.CanNavigateFully(Me.Location, ptDestination);
                        spanNav += DateTime.UtcNow - start;
                    }

                    if (failTrace)
                    {
                        countFailTrace++;
                    }

                    if (failTrace != failNav)
                    {
                        countFailDiff++;
                    }

                    if (failNav)
                    {
                        // L.debugLog( Color.Cyan, "Safe Location failed navigation check for degrees={0:F1} dist={1:F1}", RadiansToDegrees(checkFacing), distFromOrigin);
                        countFailToPointNav++;
                        continue;
                    }

                    Vector3 ptNearest = NearestMobLoc(ptDestination, mobLocations);
                    if (ptNearest == Vector3.Zero)
                    {
                        if (furthestNearMobDistSqr < minSafeDistSqr)
                        {
                            furthestNearMobDistSqr = minSafeDistSqr;
                            ptFurthest             = ptDestination; // set best available if others fail
                            facingFurthest         = checkFacing;
                        }
                    }
                    else
                    {
                        double mobDistSqr = ptDestination.Distance2DSquared(ptNearest);
                        if (furthestNearMobDistSqr < mobDistSqr)
                        {
                            furthestNearMobDistSqr = mobDistSqr;
                            ptFurthest             = ptDestination; // set best available if others fail
                            facingFurthest         = checkFacing;
                        }
                        if (mobDistSqr <= minSafeDistSqr)
                        {
                            countFailSafe++;
                            continue;
                        }
                    }

                    if (reallyCheckRangeToLineOfSightMob && RangeToLineOfSightMob < ptDestination.Distance(LineOfSightMob.Location) - LineOfSightMob.MeleeDistance())
                    {
                        countFailRange++;
                        continue;
                    }

                    if (CheckLineOfSightToSafeLocation)
                    {
                        Vector3 ptAdjDest = ptDestination;
                        ptAdjDest.Z += 1f;
                        if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSight(ptAdjOrigin, ptAdjDest))
                        {
                            // L.debugLog( Color.Cyan, "Mob-free location failed line of sight check for degrees={0:F1} dist={1:F1}", degreesFrom, distFromOrigin);
                            countFailToPointLoS++;
                            continue;
                        }
                    }

                    if (CheckSpellLineOfSightToMob && LineOfSightMob != null)
                    {
                        if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSpellSight(ptDestination, LineOfSightMob.GetTraceLinePos()))
                        {
                            if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSight(ptDestination, LineOfSightMob.GetTraceLinePos()))
                            {
                                // L.debugLog( Color.Cyan, "Mob-free location failed line of sight check for degrees={0:F1} dist={1:F1}", degreesFrom, distFromOrigin);
                                countFailToMobLoS++;
                                continue;
                            }
                        }
                    }

                    L.debugLog("SafeArea: Found mob-free location ({0:F1} yd radius) at degrees={1:F1} dist={2:F1} on point check# {3} at {4}, {5}, {6}", MinSafeDistance, WoWMathHelper.RadiansToDegrees(checkFacing), distFromOrigin, countPointsChecked, ptDestination.X, ptDestination.Y, ptDestination.Z);
                    L.debugLog("SafeArea: processing took {0:F0} ms", (DateTime.UtcNow - startFind).TotalMilliseconds);
                    L.debugLog("SafeArea: meshtrace took {0:F0} ms / fullynav took {1:F0} ms", spanTrace.TotalMilliseconds, spanNav.TotalMilliseconds);
                    L.debugLog("SafeArea: stats for ({0:F1} yd radius) found within {1:F1} yds ({2} checked, {3} nav, {4} not safe, {5} range, {6} pt los, {7} mob los, {8} mesh trace)", MinSafeDistance, MaxScanDistance, countPointsChecked, countFailToPointNav, countFailSafe, countFailRange, countFailToPointLoS, countFailToMobLoS, countFailTrace);
                    return(ptDestination);
                }
            }

            L.debugLog("SafeArea: No mob-free location ({0:F1} yd radius) found within {1:F1} yds ({2} checked, {3} nav, {4} not safe, {5} range, {6} pt los, {7} mob los, {8} mesh trace)", MinSafeDistance, MaxScanDistance, countPointsChecked, countFailToPointNav, countFailSafe, countFailRange, countFailToPointLoS, countFailToMobLoS, countFailTrace);
            if (ChooseSafestAvailable && ptFurthest != Vector3.Zero)
            {
                L.debugLog("SafeArea: choosing best available spot in {0:F1} yd radius where closest mob is {1:F1} yds", MinSafeDistance, Math.Sqrt(furthestNearMobDistSqr));
                L.debugLog("SafeArea: processing took {0:F0} ms", (DateTime.UtcNow - startFind).TotalMilliseconds);
                L.debugLog("SafeArea: meshtrace took {0:F0} ms / fullynav took {1:F0} ms", spanTrace.TotalMilliseconds, spanNav.TotalMilliseconds);
                return(ChooseSafestAvailable ? ptFurthest : Vector3.Zero);
            }

            L.debugLog("SafeArea: processing took {0:F0} ms", (DateTime.UtcNow - startFind).TotalMilliseconds);
            L.debugLog("SafeArea: meshtrace took {0:F0} ms / fullynav took {1:F0} ms", spanTrace.TotalMilliseconds, spanNav.TotalMilliseconds);
            return(Vector3.Zero);
        }
예제 #27
0
 private static void printTalent(string name, int tier)
 {
     L.infoLog(string.Format("Tier {0}: {1}", tier, name), C.InfoColor);
 }
예제 #28
0
 private static void playerLeveledUp(object sender, LuaEventArgs args)
 {
     L.infoLog(string.Format($"Player leveled up!  Now level {args.Args[0]}"), C.InfoColor);
     setTalents();
 }
예제 #29
0
 private static void characterPointsChanged(object sender, LuaEventArgs args)
 {
     L.infoLog("CHARACTER_POINTS_CHANGED - Event triggered: " + args.EventName, C.InfoColor);
     initializeTalents(sender, args);
 }
예제 #30
0
 private static void learnedSpellInTab(object sender, LuaEventArgs args)
 {
     L.infoLog("LEARNED_SPELL_IN_TAB - Event triggered: " + args.EventName, C.InfoColor);
     initializeTalents(sender, args);
 }