Example #1
0
        private static void StealthedCombat()
        {
            if (Me.CurrentTarget == null || Me.CurrentTarget.IsDead ||
                (!Me.CurrentTarget.IsHostile && !Unit.IsTrainingDummy(Me.CurrentTarget)) ||
                !Me.CurrentTarget.Attackable)
            {
                return;
            }

            if ((!Me.IsStealthed && !Buff.PlayerHasActiveBuff("Vanish")) || !SafeToBreakStealth)
            {
                return;
            }

            // If we're not behind, attempt to shadowstep and wait for next pulse.
            if (SpellManager.HasSpell("Shadowstep") && !StyxWoW.Me.IsBehind(Me.CurrentTarget) &&
                Spell.CanCast("Shadowstep", Me.CurrentTarget))
            {
                CLULogger.Log(" [Casting] Shadowstep on {0} @ StealthedCombat", CLULogger.SafeName(Me.CurrentTarget));
                SpellManager.Cast("Shadowstep");
            }
            else if (Me.Behind(Me.CurrentTarget) && (Me.CurrentEnergy >= 60 || HasShadowFocus))
            {
                CLULogger.Log(" [Casting] Ambush on {0} @ StealthCombat", CLULogger.SafeName(Me.CurrentTarget));
                SpellManager.Cast("Ambush");
            }
        }
Example #2
0
        /// <summary>
        ///  Returns true if we meet the requirements of the weapon
        /// </summary>
        /// <param name="slot">Inventory slot to check</param>
        /// <returns>true if the weapon is suitable</returns>
        public static bool HasSuitableWeapon(WoWInventorySlot slot)
        {
            switch (slot)
            {
            case WoWInventorySlot.OffHand:
            {
                var suitableOffhand = Me.Inventory.Equipped.OffHand != null &&
                                      Me.Inventory.Equipped.OffHand.ItemInfo.ItemClass == WoWItemClass.Weapon &&
                                      Me.Inventory.Equipped.MainHand != null &&
                                      StyxWoW.Me.Inventory.Equipped.MainHand.TemporaryEnchantment != null;

                if (!suitableOffhand)
                {
                    CLULogger.Log("Please Ensure your weapons are correct for the TalentSpec you are using");
                }

                return(suitableOffhand);
            }

            case WoWInventorySlot.MainHand:
            {
                var suitableMainhand = Me.Inventory.Equipped.MainHand.ItemInfo.ItemClass == WoWItemClass.Weapon &&
                                       Me.Inventory.Equipped.MainHand != null;

                if (!suitableMainhand)
                {
                    CLULogger.Log("Please Ensure your weapons are correct for the TalentSpec you are using");
                }

                return(suitableMainhand);
            }
            }

            return(false);
        }
Example #3
0
        /// <summary>Returns a summoned pet</summary>
        /// <param name="nameID">the id of the spell</param>
        /// <param name="cond">The conditions that must be true</param>
        /// <param name="label">A descriptive label for the clients GUI logging output</param>
        /// <returns>The cast pet summon spell.</returns>
        public static Composite CastPetSummonSpell(int nameID, CanRunDecoratorDelegate cond, string label)
        {
            WoWSpell summonPet = WoWSpell.FromId(nameID);

            if (summonPet.CastTime > 0)
            {
                Spell.KnownChanneledSpells.Add(summonPet.Name);
            }

            return(new Decorator(
                       delegate(object a)
            {
                if (!cond(a))
                {
                    return false;
                }

                if (!Spell.CanCast(summonPet.ToString()))
                {
                    return false;
                }

                return true;
            },
                       new Decorator(ret => !Me.GotAlivePet && PetTimer.IsFinished,
                                     new Sequence(
                                         new Action(a => CLULogger.Log(" {0}", label)),
                                         new Action(a => SpellManager.Cast(summonPet)),
                                         Spell.CreateWaitForLagDuration(),
                                         new Wait(5, a => Me.GotAlivePet || !Me.IsCasting,
                                                  new PrioritySelector(
                                                      new Decorator(a => StyxWoW.Me.IsCasting, new Action(ret => SpellManager.StopCasting())),
                                                      new ActionAlwaysSucceed()))))));
        }
Example #4
0
 /// <summary>Cast's a pet spell</summary>
 /// <param name="name">the pet spell to cast</param>
 /// <param name="cond">The conditions that must be true</param>
 /// <param name="label">A descriptive label for the clients GUI logging output</param>
 /// <returns>The cast pet spell.</returns>
 public static Composite CastPetSpell(string name, CanRunDecoratorDelegate cond, string label)
 {
     return(new Decorator(
                a => cond(a) && CanCastPetSpell(name),
                new Sequence(
                    new Action(a => CLULogger.Log(" [Pet Spell] {0} ", label)), new Action(a => CastMyPetSpell(name)))));
 }
Example #5
0
        /// <summary>
        /// sets the character's active rotation.
        /// Print the help located in the specific rotation
        /// </summary>
        /// <param name="rb">an instance of the rotationbase</param>
        private void SetActiveRotation(RotationBase rb)
        {
            CLULogger.Log(" Greetings, level {0} user!", Me.Level);
            CLULogger.Log(" I am CLU.");
            CLULogger.Log(" I will create the perfect system for you.");
            CLULogger.Log(" I suggest we use the " + rb.Name + " rotation. Revision: " + rb.Revision);
            CLULogger.Log(" as I know you have " + rb.KeySpell);
            CLULogger.Log(" BotBase: {0}  ({1})", BotManager.Current.Name, BotChecker.SupportedBotBase() ? "Supported" : "Currently Not Supported");
            CLULogger.Log(rb.Help);
            CLULogger.Log(" You can Access CLU's Settings by clicking the CLASS CONFIG button");
            CLULogger.Log(" Let's execute the plan!");

            this._rotationBase = rb;

            this.PulseEvent  = null;
            this.PulseEvent += rb.OnPulse;

            // Check for Instancebuddy and warn user that healing is not supported.
            if (BotChecker.BotBaseInUse("Instancebuddy") && this.ActiveRotation.GetType().BaseType == typeof(HealerRotationBase))
            {
                CLULogger.Log(" [BotChecker] Instancebuddy Detected. *UNABLE TO HEAL WITH CLU*");
                StopBot("You cannot use CLU with InstanceBuddy as Healer");
            }

            if (this.ActiveRotation.GetType().BaseType == typeof(HealerRotationBase))
            {
                CLULogger.TroubleshootLog(" [HealingChecker] HealerRotationBase Detected. *Activating Automatic HealableUnit refresh*");
                IsHealerRotationActive = true;
            }
        }
Example #6
0
 /// <summary>Runs Lua MacroText</summary>
 /// <param name="macro">the macro text to run</param>
 /// <param name="cond">The conditions that must be true</param>
 /// <param name="label">A descriptive label for the clients GUI logging output</param>
 /// <returns>The run macro text.</returns>
 public static Composite RunMacroText(string macro, CanRunDecoratorDelegate cond, string label)
 {
     return(new Decorator(
                cond,
                new Sequence(
                    new Action(a => CLULogger.Log(" [RunMacro] {0} ", label)),
                    new Action(a => Lua.DoString("RunMacroText(\"" + Spell.RealLuaEscape(macro) + "\")")))));
 }
Example #7
0
 public static Composite HandleTotemRecall()
 {
     return(new Decorator(
                ret => Totems.NeedToRecallTotems,
                new Sequence(
                    new Action(ret => CLULogger.Log(" [Totems] Recalling Totems")),
                    new Action(ret => Totems.RecallTotems()))));
 }
Example #8
0
 /// <summary>
 /// Uses the item specified (simulated click)
 /// </summary>
 /// <param name="item">The item to use</param>
 private static void UseItem(WoWItem item)
 {
     if (item != null)
     {
         CLULogger.Log(" [UseItem] {0} ", item.Name);
         item.Use();
     }
 }
Example #9
0
 public void PrintHealReport()
 {
     CLULogger.Log("CLU Healing report:");
     CLULogger.Log("------------------------------------------");
     CLULogger.Log("These are the spells from UNIT_SPELLCAST_SUCCEEDED");
     CLULogger.Log("------------------------------------------");
     foreach (KeyValuePair <DateTime, string> entry in this.healingStats)
     {
         CLULogger.Log("[" + entry.Key + "] " + entry.Value);
     }
     CLULogger.Log("------------------------------------------");
 }
Example #10
0
 /// <summary>
 /// Frees you from movement imparing effects if a usable spell exists
 /// </summary>
 /// <returns>More win then Wulf's UseRacial call</returns>
 public static Composite freeMe()
 {
     return(
         new PrioritySelector(delegate
     {
         foreach (WoWSpell s in freeMeSpellList.Where(spell => Spell.CanCast(spell.Name, StyxWoW.Me) && freeMeSpellUsage(spell)))
         {
             CLULogger.Log(" [Freeing you via] {0} ", s.Name);
             SpellManager.Cast(s.Name);
         }
         return RunStatus.Success;
     })
         );
 }
Example #11
0
        /// <summary>
        ///  Blows your wad all over the floor
        /// </summary>
        /// <returns>Nothing but win</returns>
        public static Composite UseRacials()
        {
            return(new PrioritySelector(delegate
            {
                if (!CLUSettings.Instance.UseRacials)
                {
                    return false;                                   // gtfo if we do not want to use racials.
                }
                foreach (WoWSpell r in CurrentRacials.Where(racial => Spell.CanCast(racial.Name, StyxWoW.Me) && RacialUsageSatisfied(racial)))
                {
                    CLULogger.Log(" [Racial Abilitie] {0} ", r.Name);
                    SpellManager.Cast(r.Name);
                }

                return RunStatus.Success;
            }));
        }
Example #12
0
        /// <summary>Casts a Pet spell at the units location</summary>
        /// <param name="name">the name of the spell to cast</param>
        /// <param name="onUnit">The on Unit.</param>
        /// <param name="cond">The conditions that must be true</param>
        /// <param name="label">A descriptive label for the clients GUI logging output</param>
        /// <returns>The cast spell at location.</returns>
        public static Composite CastPetSpellAtLocation(string name, CLU.UnitSelection onUnit, CanRunDecoratorDelegate cond, string label)
        {
            // CLU.DebugLog(" [CastSpellAtLocation] name = {0} location = {1} and can we cast it? {2}", name, SysLog.SafeName(unit), CanCast(name));
            return(new Decorator(
                       delegate(object a)
            {
                if (!CLUSettings.Instance.UseAoEAbilities)
                {
                    return false;
                }

                if (Me.CurrentTarget == null)
                {
                    return false;
                }

                WoWPoint currTargetLocation = Me.CurrentTarget.Location;
                if (Unit.NearbyControlledUnits(currTargetLocation, 20, false).Any())
                {
                    return false;
                }

                if (!cond(a))
                {
                    return false;
                }

                if (!CanCastPetSpell(name))
                {
                    return false;
                }

                return onUnit != null;
            },
                       new Sequence(
                           new Action(a => CLULogger.Log(" [Pet Casting at location] {0} ", label)),
                           new Action(a => CastMyPetSpell(name)),

                           // new WaitContinue(
                           //    0,
                           //    ret => StyxWoW.Me.CurrentPendingCursorSpell != null &&
                           //           StyxWoW.Me.CurrentPendingCursorSpell.Name == name,
                           //    new ActionAlwaysSucceed()),
                           new Action(a => SpellManager.ClickRemoteLocation(onUnit(a).Location)))));
        }
Example #13
0
        /// <summary>Attempts to use the bag item provided it is usable and its not on cooldown</summary>
        /// <param name="name">the name of the bag item to use</param>
        /// <param name="cond">The conditions that must be true</param>
        /// <param name="label">A descriptive label for the clients GUI logging output</param>
        /// <returns>The use bag item.</returns>
        public static Composite UseBagItem(string name, CanRunDecoratorDelegate cond, string label)
        {
            WoWItem item = null;

            return(new Decorator(
                       delegate(object a)
            {
                if (!cond(a))
                {
                    return false;
                }
                item = Me.BagItems.FirstOrDefault(x => x.Name == name && x.Usable && x.Cooldown <= 0);
                return item != null;
            },
                       new Sequence(
                           new Action(a => CLULogger.Log(" [BagItem] {0} ", label)),
                           new Action(a => item.UseContainerItem()))));
        }
Example #14
0
        /// <summary>Returns a summoned pet</summary>
        /// <param name="name">the name of the spell</param>
        /// <param name="cond">The conditions that must be true</param>
        /// <param name="label">A descriptive label for the clients GUI logging output</param>
        /// <returns>The cast pet summon spell.</returns>
        public static Composite CastPetSummonSpell(string name, CanRunDecoratorDelegate cond, string label)
        {
            try
            {
                var isWarlock = Me.Class == WoWClass.Warlock && SpellManager.Spells[name].Name.StartsWith("Summon ");
                if (isWarlock)
                {
                    Spell.KnownChanneledSpells.Add(name);
                }

                return(new Decorator(
                           delegate(object a)
                {
                    if (!cond(a))
                    {
                        return false;
                    }

                    if (!Spell.CanCast(name, Me))
                    {
                        return false;
                    }

                    return true;
                },
                           new Decorator(ret => !Me.GotAlivePet && PetTimer.IsFinished,
                                         new Sequence(
                                             new Action(a => CLULogger.Log(" {0}", label)),
                                             new Action(a => SpellManager.Cast(name)),
                                             Spell.CreateWaitForLagDuration(),
                                             new Wait(5, a => Me.GotAlivePet || !Me.IsCasting,
                                                      new PrioritySelector(
                                                          new Decorator(a => StyxWoW.Me.IsCasting, new Action(ret => SpellManager.StopCasting())),
                                                          new ActionAlwaysSucceed()))))));
            }
            catch
            {
                CLULogger.DiagnosticLog("Summon Spell {0} not supported for your Class / Specc ({1}/{2})", name, Me.Class, Me.Specialization);
                return(null);
            }
        }
Example #15
0
        public void PrintReport()
        {
            // var spells = spellList.OrderByDescending(x => x.Value);
            // var seconds = DateTime.Now.Subtract(start).TotalSeconds;
            var minutes = DateTime.Now.Subtract(this.start).TotalMinutes;

            var apm = (int)(this.spellCasts / minutes);

            CLULogger.Log("CLU stats report:");
            CLULogger.Log("Runtime: {0} minutes", Math.Round(minutes * 10.0) / 10.0);
            CLULogger.Log("Spells cast: {0}", this.spellCasts > 1000 ? ((Math.Round(this.spellCasts / 100.0) * 10) + "k") : this.spellCasts.ToString(CultureInfo.InvariantCulture));
            CLULogger.Log("Average APM: {0}", apm);
            CLULogger.Log("------------------------------------------");
            foreach (KeyValuePair <string, int> spell in this.spellList)
            {
                CLULogger.Log(spell.Key + " was cast " + spell.Value + " time(s).");
            }

            CLULogger.Log("------------------------------------------");

            foreach (KeyValuePair <string, List <DateTime> > spell in this.spellInterval)
            {
                var lastInterval = this.start;
                var output       = "0 ";

                for (int x = 0; x < spell.Value.Count - 1; ++x)
                {
                    var interval   = spell.Value[x];
                    var difference = interval - lastInterval;
                    output       = output + string.Format(", {0} ", Math.Round(difference.TotalSeconds * 100.0) / 100.0);
                    lastInterval = interval;
                }

                CLULogger.Log(spell.Key + " intervals: ");
                Logging.Write(" " + output);
            }
        }
Example #16
0
        /// <summary>This will: loop assemblies,
        /// loop types,
        /// filter types that are a subclass of RotationBase and not the abstract,
        /// create an instance of a RotationBase subclass so we can interigate KeySpell within the RotationBase subclass,
        /// Check if the character has the Keyspell,
        /// Set the active rotation to the matching RotationBase subclass.</summary>
        private void QueryClassTree()
        {
            try
            {
                Type type = typeof(RotationBase);

                //no need to get ALL Assemblies, need only the executed ones
                IEnumerable <Type> types = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsSubclassOf(type));

                //_rotations.AddRange(new TypeLoader<RotationBase>(null));

                this._rotations = new List <RotationBase>();
                foreach (Type x in types)
                {
                    ConstructorInfo constructorInfo = x.GetConstructor(new Type[] { });
                    if (constructorInfo != null)
                    {
                        var rb = constructorInfo.Invoke(new object[] { }) as RotationBase;
                        if (rb != null && SpellManager.HasSpell(rb.KeySpellId))
                        {
                            CLULogger.TroubleshootLog(" Using " + rb.Name + " rotation. Character has " + rb.KeySpell);
                            this._rotations.Add(rb);
                        }
                        else
                        {
                            if (rb != null)
                            {
                                //TroubleshootLog(" Skipping " + rb.Name + " rotation. Character is missing " + rb.KeySpell);
                            }
                        }
                    }
                }

                // If there is more than one rotation then display the selector for the user, otherwise just load the one and only.

                if (this._rotations.Count > 1)
                {
                    string value = "null";
                    if (
                        GUIHelpers.RotationSelector
                            ("[CLU] " + Version + " Rotation Selector", this._rotations,
                            "Please select your prefered rotation:", ref value) == DialogResult.OK)
                    {
                        this.SetActiveRotation(this._rotations.First(x => value != null && x.Name == value));
                    }
                }
                else
                {
                    if (this._rotations.Count == 0)
                    {
                        CLULogger.Log("Couldn't finde a rotation for you, Contact us!");
                        StopBot("Unable to find Active Rotation");
                    }
                    else
                    {
                        RotationBase r = this._rotations.FirstOrDefault();
                        if (r != null)
                        {
                            CLULogger.Log("Found rotation: " + r.Name);
                            this.SetActiveRotation(r);
                        }
                    }
                }
            }
            catch (ReflectionTypeLoadException ex)
            {
                var sb = new StringBuilder();
                foreach (Exception exSub in ex.LoaderExceptions)
                {
                    sb.AppendLine(exSub.Message);
                    if (exSub is FileNotFoundException)
                    {
                        var exFileNotFound = exSub as FileNotFoundException;
                        if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
                        {
                            sb.AppendLine("CLU Log:");
                            sb.AppendLine(exFileNotFound.FusionLog);
                        }
                    }
                    sb.AppendLine();
                }
                string errorMessage = sb.ToString();
                CLULogger.Log(" Woops, we could not set the rotation.");
                CLULogger.Log(errorMessage);
                StopBot(" Unable to find Active Rotation: " + ex);
            }
        }
Example #17
0
        /// <summary>
        /// Main MultiCastMacro call: checks if MultiCastMacro MT or FT is active, also checks for LoS and if we can cast the specified spell
        /// If zero(0) is present: return to primary or previous rotation
        /// If one(1) is present: run MT or FT then return to primary or previous rotation
        /// </summary>
        public static void isMultiCastMacroInUse()
        {
            using (StyxWoW.Memory.AcquireFrame())
            {
                try
                {
                    MultiCastMacroMT = Lua.GetReturnVal <int>("return MultiCastMT", 0);
                    MultiCastMacroFT = Lua.GetReturnVal <int>("return MultiCastFT", 0);
                    whatSpell        = Lua.GetReturnVal <String>("return spellName", 0);
                }
                catch
                {
                    CLULogger.DiagnosticLog("Lua failed in Macro.isMultiCastMacroInUse");
                }
            }
            if (MultiCastMacroMT > 0 || MultiCastMacroFT > 0)
            {
                if (whatSpell == null)
                {
                    CLULogger.Log("Please enter a spell!");
                    resetAllMacros();
                }
                else
                {
                    SpellManager.Spells.TryGetValue(whatSpell, out _Spell);
                    if (!_Spell.IsValid)
                    {
                        CLULogger.Log("Can't Cast Spell, invalid!");
                        resetAllMacros();
                    }
                    if (_Spell.CooldownTimeLeft > SpellManager.GlobalCooldownLeft)
                    {
                        CLULogger.Log("Can't Cast Spell, on CD!");
                        resetAllMacros();
                    }
                }
            }
            if (MultiCastMacroMT > 0)
            {
                if (SpellManager.GlobalCooldown || Me.IsCasting)
                {
                    return;
                }
                if (Me.CurrentTarget.InLineOfSight)
                {
                    if (SpellManager.CanCast(whatSpell))
                    {
                        try
                        {
                            Lua.DoString("RunMacroText(\"/cast " + whatSpell + "\")");
                        }
                        catch
                        {
                            CLULogger.DiagnosticLog("Lua failed in Macro.isMultiCastMacroInUse");
                        }

                        SpellManager.ClickRemoteLocation(Me.CurrentTarget.Location);
                        CLULogger.Log("Casting " + whatSpell);
                        resetMacro("MultiCastMT");
                    }
                }
                else
                {
                    resetMacro("MultiCastMT");
                }
            }
            else if (MultiCastMacroFT > 0)
            {
                if (SpellManager.GlobalCooldown || Me.IsCasting)
                {
                    return;
                }
                if (Me.FocusedUnit.InLineOfSight)
                {
                    if (SpellManager.CanCast(whatSpell))
                    {
                        try
                        {
                            Lua.DoString("RunMacroText(\"/cast [@focus] " + whatSpell + "\")");
                        }
                        catch
                        {
                            CLULogger.DiagnosticLog("Lua failed in Macro.isMultiCastMacroInUse");
                        }

                        SpellManager.ClickRemoteLocation(Me.FocusedUnit.Location);
                        CLULogger.Log("Casting " + whatSpell);
                        resetMacro("MultiCastFT");
                    }
                }
                else
                {
                    resetMacro("MultiCastFT");
                }
            }
        }
Example #18
0
        public static Composite CreateDefaultRestBehaviour()
        {
            return

                // Don't f*****g run the rest behavior (or any other) if we're dead or a ghost. Thats all.
                (new Decorator(
                     ret => !StyxWoW.Me.IsDead && !StyxWoW.Me.IsGhost && !StyxWoW.Me.IsCasting && CLUSettings.Instance.EnableMovement && BotPoi.Current.Type != PoiType.Loot,
                     new PrioritySelector(

                         // Make sure we wait out res sickness. F**k the classes that can deal with it. :O
                         new Decorator(
                             ret => StyxWoW.Me.HasAura("Resurrection Sickness"),
                             new Action(ret => { })),

                         // Wait while cannibalizing
                         new Decorator(
                             ret => StyxWoW.Me.CastingSpell != null && StyxWoW.Me.CastingSpell.Name == "Cannibalize" &&
                             (StyxWoW.Me.HealthPercent < 95 || (StyxWoW.Me.PowerType == WoWPowerType.Mana && StyxWoW.Me.ManaPercent < 95)),
                             new Sequence(
                                 new Action(ret => CLULogger.Log("Waiting for Cannibalize")),
                                 new ActionAlwaysSucceed())),

                         // Cannibalize support goes before drinking/eating
                         new Decorator(
                             ret =>
                             (StyxWoW.Me.HealthPercent <= CLUSettings.Instance.MinHealth ||
                              (StyxWoW.Me.PowerType == WoWPowerType.Mana && StyxWoW.Me.ManaPercent <= CLUSettings.Instance.MinMana)) &&
                             SpellManager.CanCast("Cannibalize") && CorpseAround,
                             new Sequence(
                                 new Action(ret => Navigator.PlayerMover.MoveStop()),
                                 Spell.CreateWaitForLagDuration(),
                                 new Action(ret => SpellManager.Cast("Cannibalize")),
                                 new WaitContinue(1, ret => false, new ActionAlwaysSucceed()))),

                         // Check if we're allowed to eat (and make sure we have some food. Don't bother going further if we have none.
                         new Decorator(
                             ret =>
                             !StyxWoW.Me.IsSwimming && StyxWoW.Me.HealthPercent <= CLUSettings.Instance.MinHealth && !StyxWoW.Me.HasAura("Food") &&
                             Consumable.GetBestFood(false) != null && !StyxWoW.Me.IsCasting,
                             new PrioritySelector(
                                 new Decorator(
                                     ret => StyxWoW.Me.IsMoving,
                                     new Action(ret => Navigator.PlayerMover.MoveStop())),
                                 new Sequence(
                                     new Action(
                                         ret =>
            {
                Styx.CommonBot.Rest.FeedImmediate();
            }),
                                     Spell.CreateWaitForLagDuration()))),

                         // Make sure we're a class with mana, if not, just ignore drinking all together! Other than that... same for food.
                         new Decorator(
                             ret =>

                             // TODO: Does this Druid check need to be still in here?
                             !StyxWoW.Me.IsSwimming && (StyxWoW.Me.PowerType == WoWPowerType.Mana || StyxWoW.Me.Class == WoWClass.Druid) &&
                             StyxWoW.Me.ManaPercent <= CLUSettings.Instance.MinMana &&
                             !StyxWoW.Me.HasAura("Drink") && Consumable.GetBestDrink(false) != null && !StyxWoW.Me.IsCasting,
                             new PrioritySelector(
                                 new Decorator(
                                     ret => StyxWoW.Me.IsMoving,
                                     new Action(ret => Navigator.PlayerMover.MoveStop())),
                                 new Sequence(
                                     new Action(ret =>
            {
                Styx.CommonBot.Rest.DrinkImmediate();
            }),
                                     Spell.CreateWaitForLagDuration()))),

                         // This is to ensure we STAY SEATED while eating/drinking. No reason for us to get up before we have to.
                         new Decorator(
                             ret =>
                             (StyxWoW.Me.HasAura("Food") && StyxWoW.Me.HealthPercent < 95) ||
                             (StyxWoW.Me.HasAura("Drink") && StyxWoW.Me.PowerType == WoWPowerType.Mana && StyxWoW.Me.ManaPercent < 95),
                             new ActionAlwaysSucceed()),
                         new Decorator(
                             ret =>
                             ((StyxWoW.Me.PowerType == WoWPowerType.Mana && StyxWoW.Me.ManaPercent <= CLUSettings.Instance.MinMana) ||
                              StyxWoW.Me.HealthPercent <= CLUSettings.Instance.MinHealth) && !StyxWoW.Me.CurrentMap.IsBattleground,
                             new Action(ret => CLULogger.Log("We have no food/drink. Waiting to recover our health/mana back")))
                         )));
        }