/// <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())))))); }
static public Composite Cast(string spellName, CanRunDecoratorDelegate cond, WoWUnitDelegate target) { if (spellName.Equals("Hemorrhage")) { spellName = "Sinister Strike"; } if (spellName.Equals("Dispatch")) { spellName = "Sinister Strike"; } if (spellName.Equals("Envenom")) { spellName = "Eviscerate"; } return(new Decorator(ret => target(ret) != null && cond(ret) && CanCast(spellName), new Action(ret => { SpellManager.Cast(spellName, target(ret)); if (target(ret).IsPlayer) { Logging.Write(LogLevel.Normal, "Casting " + spellName + " on Player at " + Math.Round(target(ret).HealthPercent, 0) + "% with " + Helpers.Rogue.mComboPoints + "CP and " + Rogue.mCurrentEnergy + " energy"); } else { Logging.Write(LogLevel.Normal, "Casting " + spellName + " on " + target(ret).Name + " at " + Math.Round(target(ret).HealthPercent, 0) + "% with " + Helpers.Rogue.mComboPoints + "CP and " + Rogue.mCurrentEnergy + " energy"); } }) )); }
public static Composite CastFocus(int spell, CanRunDecoratorDelegate condition) { return new Decorator( ret => condition(ret) && SpellManager.CanCast(spell, Helpers.Focus) && SpellManager.Cast(spell, Helpers.Focus), new SpellLog(spell, Helpers.Focus)); }
/// <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))))); }
public DecoratorIfElse(CanRunDecoratorDelegate runFunc, params Composite [] children) : base(children) { Debug.Assert(runFunc != null); Debug.Assert(children.Count() == 2); Runner = runFunc; }
public DecoratorIfElse(CanRunDecoratorDelegate runFunc, params Composite []children) : base(children) { Debug.Assert(runFunc != null); Debug.Assert(children.Count() == 2); Runner = runFunc; }
static public Composite Cast(int spellId, CanRunDecoratorDelegate cond, WoWUnitDelegate target) { return(new Decorator(ret => target != null && cond(ret) && CanCast(spellId), new Action(ret => { SpellManager.Cast(spellId, target(ret)); Logging.Write(LogLevel.Diagnostic, Colors.White, "" + WoWSpell.FromId(spellId).Name); string temp; if (target(ret).IsPlayer) { temp = "Casting " + WoWSpell.FromId(spellId).Name + " on Player at " + Math.Round(target(ret).HealthPercent, 0) + " with " + Helpers.Rogue.me.ComboPoints + "CP and " + Rogue.mCurrentEnergy + " energy"; } else { temp = "Casting " + WoWSpell.FromId(spellId).Name + " on " + target(ret).Name + " at " + Math.Round(target(ret).HealthPercent, 0) + " with " + Helpers.Rogue.me.ComboPoints + "CP and " + Rogue.mCurrentEnergy + " energy"; } Logging.Write(LogLevel.Normal, temp); } ) )); }
/// <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) + "\")"))))); }
/// <summary>Targeting myself when no target</summary> /// <param name="cond">The conditions that must be true</param> /// <returns>Target myself</returns> public static Composite EnsureTarget(CanRunDecoratorDelegate cond) { return(new Decorator( cond, new Sequence( new Action(a => CLULogger.TroubleshootLog("[CLU] " + CLU.Version + ": CLU targeting activated. I dont have a target, someone must have died. Targeting myself")), new Action(a => Me.Target())))); }
public static Composite HealGround(string spell, CanRunDecoratorDelegate reqs = null) { return(new Decorator( ret => Targeting.AoeHealPoint != Vector3.Zero && (reqs == null || reqs(ret)) && Targeting.ShouldAoeHeal, CastOnGround(spell, ret => Targeting.AoeHealPoint, ret => true))); }
private static Composite FindTarget(CanRunDecoratorDelegate cond, TargetFilter filter, RefineFilter refineFilter, Comparison <HealableUnit> compare, string label, params Composite[] children) { return(new Decorator( cond, new Sequence( // get a target new Action( delegate { var targetPerformanceTimer = new Stopwatch(); // lets see if we can get some performance on this one. targetPerformanceTimer.Start(); // lets see if we can get some performance on this one. //CrabbyProfiler.Instance.Runs.Add(new Run("FindTarget")); // Nothing to filter against if (!UnitsFilter(filter).Any()) { HealableUnit.HealTarget = null; return RunStatus.Failure; } // Filter the Healable Units var raid = UnitsFilter(filter).Where(x => x != null && (ObjectManager.ObjectList.Any(y => y.Guid == x.ToUnit().Guid) && refineFilter(x)) && x.ToUnit().Distance2DSqr < 40 * 40 && !x.ToUnit().ToPlayer().IsGhost&& !x.ToUnit().HasAura("Deep Corruption")).ToList(); // Nothing to heal. if (!IsPlayingWoW() || !raid.Any()) { HealableUnit.HealTarget = null; return RunStatus.Failure; } raid.Sort(compare); var target = raid.FirstOrDefault(); if (target != null) { Log( label, CLULogger.SafeName(target.ToUnit()), target.MaxHealth, target.CurrentHealth, target.MaxHealth - target.CurrentHealth, targetPerformanceTimer.ElapsedMilliseconds); // lets see if we can get some performance on this one. //target.ToUnit().Target(); HealableUnit.HealTarget = target; return RunStatus.Success; } HealableUnit.HealTarget = null; //CrabbyProfiler.Instance.EndLast(); return RunStatus.Failure; }), new Action(a => StyxWoW.SleepForLagDuration()), // if success, keep going. Else quit sub routine new PrioritySelector(children)))); }
public static Composite FunkyTownPortal() { CanRunDecoratorDelegate canRunDelegateReturnToTown = FunkyTPOverlord; ActionDelegate actionDelegateReturnTown = FunkyTPBehavior; Sequence sequenceReturnTown = new Sequence( new Action(actionDelegateReturnTown) ); return(new Decorator(canRunDelegateReturnToTown, sequenceReturnTown)); }
public Composite Wait(CanRunDecoratorDelegate del = null, String reason = "") { var d = del ?? (ret => true); return(new Decorator(_ret => { var r = d(_ret) && moving; //LogDebug("wait" + " " + reason + " => " + r); return r; }, new ActionAlwaysSucceed())); }
public static Composite RunMacroText(string macro, CanRunDecoratorDelegate cond) { return(new Decorator( cond, //new PrioritySelector( new Sequence( new Action(a => Lua.DoString("RunMacroText(\"" + RealLuaEscape(macro) + "\")")), new Action(a => Logging.WriteDiagnostic("Running Macro Text: {0}", macro)) ) )); }
static public Composite TryToInterruptFocus(CanRunDecoratorDelegate cond) { return(new Decorator(cond, new PrioritySelector( Helpers.Spells.CastFocusRaw("Kick", ret => !Helpers.Aura.ShadowDance && Helpers.Rogue.mTarget.CanInterruptCurrentSpellCast), Helpers.Spells.CastFocusRaw("Gouge", ret => !Helpers.Aura.ShadowDance && Helpers.Focus.rawFocusTarget.IsSafelyFacing(Helpers.Rogue.me)), Helpers.Spells.CastFocusRaw("Cheap Shot", ret => !Helpers.Aura.IsTargetImmuneStun && (Helpers.Aura.Stealth || Helpers.Aura.Vanish || Helpers.Aura.ShadowDance)) ) )); }
static public Composite UseItem(WoWItemDelegate item, CanRunDecoratorDelegate cond) { return(new Decorator(ret => item(ret) != null && cond(ret) && ItemUsable(item(ret)), new Action(ret => { item(ret).Use(); Logging.Write(LogLevel.Normal, item(ret).Name); return RunStatus.Failure; } ) )); }
public TaskDetail(string mobName, int mobId, Vector3 positionForLaunch, Vector3 positionToTarget, double neededAzimuth, Vector3 positionToJumpDownOffBoat, CanRunDecoratorDelegate isTaskComplete) { IsTaskComplete = isTaskComplete; MobId = mobId; MobName = mobName; NeededAzimuth = neededAzimuth; PositionForLaunch = positionForLaunch; PositionToJumpDownOffBoat = positionToJumpDownOffBoat; PositionToLand = positionToTarget; }
static public Composite UseSpecialAbilities(CanRunDecoratorDelegate cond) { return(new PrioritySelector( UseItem(ret => mTrinket1, ret => cond(ret) && mTrinket1Usable), UseItem(ret => mTrinket2, ret => cond(ret) && mTrinket2Usable), UseItem(ret => mGloves, ret => cond(ret) && mGlovesUsable), new Decorator(ret => mRacialName != null && Helpers.Rogue.mCurrentEnergy < 65 && mRacialName.Equals("Arcane Torrent"), Spells.CastSelf(mRacialName)), new Decorator(ret => mRacialName != null && mRacialName.Length > 3 && !mRacialName.Equals("Arcane Torrent"), Spells.CastSelf(mRacialName)) )); }
public Composite StopPyroChain(CanRunDecoratorDelegate del = null, String reason = "") { var d = del ?? (ret => true); return(new Decorator(_ret => { var r = d(_ret) && moving; //LogDebug("stop_pyro_chain" + " " + reason + " => " + r); return r; }, new Action(delegate { pyro_chain = false; return RunStatus.Failure; }))); }
/// <summary> /// Finds Raid or Party members that need healing /// </summary> /// <param name="cond">The conditions that must be true</param> /// <param name="minAverageHealth">Minimum Average health of the Party Members</param> /// <param name="maxAverageHealth">MaximumAverage health of the Party Members</param> /// <param name="maxDistanceBetweenPlayers">The maximum distance between other party members from the targeted party member</param> /// <param name="minUnits">Minumum units to be affected</param> /// <param name="reason">text to indicate the reason for using this method </param> /// <param name="children">Execute the child subroutines</param> /// <returns>A Raid/Party member</returns> public Composite FindAreaHeal(CanRunDecoratorDelegate cond, int minAverageHealth, int maxAverageHealth, float maxDistanceBetweenPlayers, int minUnits, string reason, params Composite[] children) { return(new Decorator( cond, new Sequence( new PrioritySelector( FindAreaHealSubroutine(minAverageHealth, maxAverageHealth, maxDistanceBetweenPlayers, minUnits, "[CLU TARGETING] " + CLU.Version + ": " + "Target AREA MEMBER: {0} REASON: " + reason) ), new Action(a => StyxWoW.SleepForLagDuration()), // if success, keep going. Else quit sub routine new PrioritySelector(children) ) )); }
internal static void HookCombat() { CanRunDecoratorDelegate canRunDelegateCombatTargetCheck = PreCombat.PreCombatOverlord; ActionDelegate actionDelegateCoreTarget = PreCombat.HandleTarget; Sequence sequencecombat = new Sequence ( new Zeta.TreeSharp.Action(actionDelegateCoreTarget) ); Decorator Precombat = new Decorator(canRunDelegateCombatTargetCheck, sequencecombat); //Record GUID for checking PrecombatCompositeGUID = Precombat.Guid; //Insert precombat! SetHookValue(HookType.Combat, 0, Precombat, true); }
public Composite PoolResource(String spell, CanRunDecoratorDelegate pool = null, CanRunDecoratorDelegate del = null, WoWUnit target = null, String Reason = "") { return(null); /*return new Decorator(del ?? (ret => true), * new PrioritySelector( * new Decorator(ret => pool(null), * new Action(delegate * { * LuaDoString("_G[\"kane_spd\"] = \"" + "Pooling: " + spell + "\";"); * //Write(DateTime.Now+": Pooling Energy for " + spell + " " + Energy.current + "/" + energy); * return RunStatus.Success; * })), * Cast(spell, del, target, Reason) * ) * );*/ }
/// <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())))); }
public Composite UseItem(int id, CanRunDecoratorDelegate del = null, String Reason = "") { return(new Decorator(del ?? (ret => true), new Action(delegate { var item = Me.Inventory.Equipped.PhysicalItems.FirstOrDefault(it => it.ItemInfo.Id == id); if (item == default(WoWItem)) { return RunStatus.Failure; } ; if (item.Cooldown <= 0) { item.Use(); } return RunStatus.Failure; }))); }
/// <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); } }
public static Composite Cast(int spellId, CanRunDecoratorDelegate cond, WoWUnitDelegate target) { return new Decorator(ret => target != null && cond(ret) && CanCast(spellId), new Action(ret => { SpellManager.Cast(spellId, target(ret)); Logging.Write(LogLevel.Diagnostic, Colors.White, "" + WoWSpell.FromId(spellId).Name); string temp; if (target(ret).IsPlayer) temp = "Casting " + WoWSpell.FromId(spellId).Name + " on Player at " + Math.Round(target(ret).HealthPercent, 0) + " with " + Helpers.Rogue.me.ComboPoints + "CP and " + Rogue.mCurrentEnergy + " energy"; else temp = "Casting " + WoWSpell.FromId(spellId).Name + " on " + target(ret).Name + " at " + Math.Round(target(ret).HealthPercent, 0) + " with " + Helpers.Rogue.me.ComboPoints + "CP and " + Rogue.mCurrentEnergy + " energy"; Logging.Write(LogLevel.Normal, temp ); } ) ); }
public static Composite CancelMyAura(string name, CanRunDecoratorDelegate cond) { name = LocalizeSpellName(name); var macro = String.Format("/cancelaura {0}", name); return(new Decorator( delegate(object a) { if (name.Length == 0) { return false; } if (!cond(a)) { return false; } return true; }, new Sequence( new Action(a => Lua.DoString("RunMacroText(\"" + RealLuaEscape(macro) + "\")"))))); }
public Composite UsePotion(String name, CanRunDecoratorDelegate del = null, String Reason = "") { var n = UppercaseFirst(name.Split('_')[0]) + " " + UppercaseFirst(name.Split('_')[1]); var item = Me.BagItems.FirstOrDefault(ret => ret.Name.Contains(n) && ret.Name.Contains("Potion")); if (item == default(WoWItem)) { return(new ActionAlwaysFail()); } return(new PrioritySelector(new Action(context => { Potion = item; return RunStatus.Failure; }), new Decorator(del ?? (ret => true), new Action(delegate { if (item.Cooldown <= 0) { LuaDoString("UseItemByName(\"" + item.Name + "\")"); } return RunStatus.Failure; })))); }
static public Composite TryToInterrupt(CanRunDecoratorDelegate cond) { return(new Decorator(cond, new PrioritySelector( new Decorator(ret => Helpers.Rogue.mTarget.CanInterruptCurrentSpellCast, new PrioritySelector( Helpers.Spells.CastCooldown("Kick", ret => true) )), new Decorator(ret => !Helpers.Rogue.mTarget.CanInterruptCurrentSpellCast, new PrioritySelector( Helpers.Spells.CastCooldown("Kidney Shot", ret => Helpers.Rogue.me.ComboPoints > 1 && !Helpers.Aura.IsTargetImmuneStun) )), Helpers.Spells.CastCooldown("Gouge", ret => Helpers.Rogue.mTarget.IsSafelyFacing(Helpers.Rogue.me)), Helpers.Spells.CastCooldown("Deadly Throw", ret => Helpers.Rogue.mTarget.CanInterruptCurrentSpellCast && Helpers.Rogue.mComboPoints > 4 && Helpers.Rogue.mTarget.Distance > 5) ) )); }
/// <summary> /// Casts a spell and executes <paramref name="onSuccess"/> if successful. /// This method will not log anything by default. /// </summary> /// <param name="spell">Id of the spell to cast.</param> /// <param name="conditions">Conditions to test before casting.</param> /// <param name="onSuccess">Action to run on success.</param> /// <returns><see cref="Decorator"/> that casts a spell and performs a custom action.</returns> public static Composite Cast(int spell, CanRunDecoratorDelegate conditions, Action onSuccess) { return new Decorator(ret => conditions(ret) && SpellManager.CanCast(spell) && SpellManager.Cast(spell), onSuccess); }
/// <summary>Targeting myself when no target</summary> /// <param name="cond">The conditions that must be true</param> /// <returns>Target myself</returns> public static Composite EnsureTarget(CanRunDecoratorDelegate cond) { return new Decorator( cond, new Sequence( new Action(a => CLULogger.TroubleshootLog("[CLU] " + CLU.Version + ": CLU targeting activated. I dont have a target, someone must have died. Targeting myself")), new Action(a => Me.Target()))); }
private static Composite FindTarget(CanRunDecoratorDelegate cond, TargetFilter filter, RefineFilter refineFilter, Comparison<HealableUnit> compare, string label, params Composite[] children) { return new Decorator( cond, new Sequence( // get a target new Action( delegate { var targetPerformanceTimer = new Stopwatch(); // lets see if we can get some performance on this one. targetPerformanceTimer.Start(); // lets see if we can get some performance on this one. //CrabbyProfiler.Instance.Runs.Add(new Run("FindTarget")); // Nothing to filter against if (!UnitsFilter(filter).Any()) { HealableUnit.HealTarget = null; return RunStatus.Failure; } // Filter the Healable Units var raid = UnitsFilter(filter).Where(x => x != null && (ObjectManager.ObjectList.Any(y => y.Guid == x.ToUnit().Guid) && refineFilter(x)) && x.ToUnit().Distance2DSqr < 40 * 40 && !x.ToUnit().ToPlayer().IsGhost && !x.ToUnit().HasAura("Deep Corruption")).ToList(); // Nothing to heal. if (!IsPlayingWoW() || !raid.Any()) { HealableUnit.HealTarget = null; return RunStatus.Failure; } raid.Sort(compare); var target = raid.FirstOrDefault(); if (target != null) { Log( label, CLULogger.SafeName(target.ToUnit()), target.MaxHealth, target.CurrentHealth, target.MaxHealth - target.CurrentHealth, targetPerformanceTimer.ElapsedMilliseconds); // lets see if we can get some performance on this one. //target.ToUnit().Target(); HealableUnit.HealTarget = target; return RunStatus.Success; } HealableUnit.HealTarget = null; //CrabbyProfiler.Instance.EndLast(); return RunStatus.Failure; }), new Action(a => StyxWoW.SleepForLagDuration()), // if success, keep going. Else quit sub routine new PrioritySelector(children))); }
public Composite FindThreats(CanRunDecoratorDelegate cond, RefineFilter filter, Comparison<HealableUnit> compare, string reason, params Composite[] children) { return FindTarget(cond, TargetFilter.Threats, filter, compare, "[CLU TARGETING] " + CLU.Version + ": " + "Targeting THREAT {0}: Max {1}, Current {2}, Defecit {3}, TimeTaken: {4} ms, REASON: " + reason, children); }
/// <summary> /// Allows waiting for SleepForLagDuration() but ending sooner if condition is met /// </summary> /// <param name="orUntil">if true will stop waiting sooner than lag maximum</param> /// <returns></returns> public static Composite CreateWaitForLagDuration( CanRunDecoratorDelegate orUntil) { return new WaitContinue(TimeSpan.FromMilliseconds((StyxWoW.WoWClient.Latency * 2) + 150), orUntil, new ActionAlwaysSucceed()); }
/// <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) + "\")")))); }
internal static void HookBehaviorTree() { HookHandler.StoreHook(HookHandler.HookType.VendorRun); Logger.DBLog.InfoFormat("[FunkyTownRun] Treehooks.."); #region VendorRun // Wipe the vendorrun and loot behavior trees, since we no longer want them Logger.DBLog.DebugFormat("[FunkyTownRun] VendorRun..."); Decorator GilesDecorator = HookHandler.ReturnHookValue(HookHandler.HookType.VendorRun)[0] as Decorator; //PrioritySelector GilesReplacement = GilesDecorator.Children[0] as PrioritySelector; PrioritySelector GilesReplacement = GilesDecorator.Children[0] as PrioritySelector; //HookHandler.PrintChildrenTypes(GilesReplacement.Children); CanRunDecoratorDelegate canRunDelegateReturnToTown = TownPortalBehavior.FunkyTPOverlord; ActionDelegate actionDelegateReturnTown = TownPortalBehavior.FunkyTPBehavior; ActionDelegate actionDelegateTownPortalFinish = TownPortalBehavior.FunkyTownPortalTownRun; Sequence sequenceReturnTown = new Sequence( new Zeta.TreeSharp.Action(actionDelegateReturnTown), new Zeta.TreeSharp.Action(actionDelegateTownPortalFinish) ); GilesReplacement.Children[1] = new Decorator(canRunDelegateReturnToTown, sequenceReturnTown); Logger.DBLog.DebugFormat("[FunkyTownRun] Town Portal - hooked..."); ActionDelegate actionDelegatePrePause = TownRunManager.GilesStashPrePause; ActionDelegate actionDelegatePause = TownRunManager.GilesStashPause; #region Idenify CanRunDecoratorDelegate canRunDelegateFunkyIDManual = TownRunManager.IdenifyItemManualOverlord; ActionDelegate actionDelegateIDManual = TownRunManager.IdenifyItemManualBehavior; ActionDelegate actionDelegateIDFinish = TownRunManager.IdenifyItemManualFinishBehavior; Sequence sequenceIDManual = new Sequence( new Zeta.TreeSharp.Action(actionDelegateIDManual), new Zeta.TreeSharp.Action(actionDelegateIDFinish) ); CanRunDecoratorDelegate canRunDelegateFunkyIDBookOfCain = TownRunManager.IdenifyItemBookOfCainOverlord; ActionDelegate actionDelegateIDBookOfCainMovement = TownRunManager.IdenifyItemBookOfCainMovementBehavior; ActionDelegate actionDelegateIDBookOfCainInteraction = TownRunManager.IdenifyItemBookOfCainInteractionBehavior; Sequence sequenceIDBookOfCain = new Sequence( new Zeta.TreeSharp.Action(actionDelegateIDBookOfCainMovement), new Zeta.TreeSharp.Action(actionDelegateIDBookOfCainInteraction), new Zeta.TreeSharp.Action(actionDelegateIDFinish) ); PrioritySelector priorityIDItems = new PrioritySelector( new Decorator(canRunDelegateFunkyIDManual, sequenceIDManual), new Decorator(canRunDelegateFunkyIDBookOfCain, sequenceIDBookOfCain) ); CanRunDecoratorDelegate canRunDelegateFunkyIDOverlord = TownRunManager.IdenifyItemOverlord; GilesReplacement.Children[2] = new Decorator(canRunDelegateFunkyIDOverlord, priorityIDItems); Logger.DBLog.DebugFormat("[FunkyTownRun] Idenify Items - hooked..."); #endregion // Replace the pause just after identify stuff to ensure we wait before trying to run to vendor etc. CanRunDecoratorDelegate canRunDelegateEvaluateAction = TownRunManager.ActionsEvaluatedOverlord; ActionDelegate actionDelegateEvaluateAction = TownRunManager.ActionsEvaluatedBehavior; Sequence sequenceEvaluate = new Sequence( new Zeta.TreeSharp.Action(actionDelegatePrePause), new Zeta.TreeSharp.Action(actionDelegatePause), new Zeta.TreeSharp.Action(actionDelegateEvaluateAction) ); GilesReplacement.Children[3] = new Decorator(canRunDelegateEvaluateAction, sequenceEvaluate); #region Salvage // Replace DB salvaging behavior tree with my optimized & "one-at-a-time" version CanRunDecoratorDelegate canRunDelegateSalvageGilesOverlord = TownRunManager.GilesSalvageOverlord; ActionDelegate actionDelegatePreSalvage = TownRunManager.GilesOptimisedPreSalvage; ActionDelegate actionDelegateSalvage = TownRunManager.GilesOptimisedSalvage; ActionDelegate actionDelegatePostSalvage = TownRunManager.GilesOptimisedPostSalvage; Sequence sequenceSalvage = new Sequence( new Zeta.TreeSharp.Action(actionDelegatePreSalvage), new Zeta.TreeSharp.Action(actionDelegateSalvage), new Zeta.TreeSharp.Action(actionDelegatePostSalvage), new Sequence( new Zeta.TreeSharp.Action(actionDelegatePrePause), new Zeta.TreeSharp.Action(actionDelegatePause) ) ); GilesReplacement.Children[4] = new Decorator(canRunDelegateSalvageGilesOverlord, sequenceSalvage); Logger.DBLog.DebugFormat("[FunkyTownRun] Salvage - hooked..."); #endregion #region Stash // Replace DB stashing behavior tree with my optimized version with loot rule replacement CanRunDecoratorDelegate canRunDelegateStashGilesOverlord = TownRunManager.StashOverlord; ActionDelegate actionDelegatePreStash = TownRunManager.PreStash; ActionDelegate actionDelegatePostStash = TownRunManager.PostStash; ActionDelegate actionDelegateStashMovement = TownRunManager.StashMovement; ActionDelegate actionDelegateStashUpdate = TownRunManager.StashUpdate; ActionDelegate actionDelegateStashItems = TownRunManager.StashItems; Sequence sequencestash = new Sequence( new Zeta.TreeSharp.Action(actionDelegatePreStash), new Zeta.TreeSharp.Action(actionDelegateStashMovement), new Zeta.TreeSharp.Action(actionDelegateStashUpdate), new Zeta.TreeSharp.Action(actionDelegateStashItems), new Zeta.TreeSharp.Action(actionDelegatePostStash), new Sequence( new Zeta.TreeSharp.Action(actionDelegatePrePause), new Zeta.TreeSharp.Action(actionDelegatePause) ) ); GilesReplacement.Children[5] = new Decorator(canRunDelegateStashGilesOverlord, sequencestash); Logger.DBLog.DebugFormat("[FunkyTownRun] Stash - hooked..."); #endregion #region Vendor // Replace DB vendoring behavior tree with my optimized & "one-at-a-time" version CanRunDecoratorDelegate canRunDelegateSellGilesOverlord = TownRunManager.GilesSellOverlord; ActionDelegate actionDelegatePreSell = TownRunManager.GilesOptimisedPreSell; ActionDelegate actionDelegateMovement = TownRunManager.VendorMovement; ActionDelegate actionDelegateSell = TownRunManager.GilesOptimisedSell; ActionDelegate actionDelegatePostSell = TownRunManager.GilesOptimisedPostSell; Sequence sequenceSell = new Sequence( new Zeta.TreeSharp.Action(actionDelegatePreSell), new Zeta.TreeSharp.Action(actionDelegateMovement), new Zeta.TreeSharp.Action(actionDelegateSell), new Zeta.TreeSharp.Action(actionDelegatePostSell), new Sequence( new Zeta.TreeSharp.Action(actionDelegatePrePause), new Zeta.TreeSharp.Action(actionDelegatePause) ) ); GilesReplacement.Children[6] = new Decorator(canRunDelegateSellGilesOverlord, sequenceSell); Logger.DBLog.DebugFormat("[FunkyTownRun] Vendor - hooked..."); #endregion #region Interaction Behavior CanRunDecoratorDelegate canRunDelegateInteraction = TownRunManager.InteractionOverlord; ActionDelegate actionDelegateInteractionMovementhBehavior = TownRunManager.InteractionMovement; ActionDelegate actionDelegateInteractionClickBehaviorBehavior = TownRunManager.InteractionClickBehavior; ActionDelegate actionDelegateInteractionLootingBehaviorBehavior = TownRunManager.InteractionLootingBehavior; ActionDelegate actionDelegateInteractionFinishBehaviorBehavior = TownRunManager.InteractionFinishBehavior; Sequence sequenceInteraction = new Sequence( new Zeta.TreeSharp.Action(actionDelegateInteractionFinishBehaviorBehavior), new Zeta.TreeSharp.Action(actionDelegateInteractionMovementhBehavior), new Zeta.TreeSharp.Action(actionDelegateInteractionClickBehaviorBehavior), new Zeta.TreeSharp.Action(actionDelegateInteractionLootingBehaviorBehavior), new Zeta.TreeSharp.Action(actionDelegateInteractionFinishBehaviorBehavior) ); GilesReplacement.InsertChild(7, new Decorator(canRunDelegateInteraction, sequenceInteraction)); Logger.DBLog.DebugFormat("[FunkyTownRun] Interaction Behavior - Inserted..."); #endregion #region Gambling Behavior CanRunDecoratorDelegate canRunDelegateGambling = TownRunManager.GamblingRunOverlord; ActionDelegate actionDelegateGamblingMovementBehavior = TownRunManager.GamblingMovement; ActionDelegate actionDelegateGamblingInteractionBehavior = TownRunManager.GamblingInteraction; ActionDelegate actionDelegateGamblingStartBehavior = TownRunManager.GamblingStart; ActionDelegate actionDelegateGamblingFinishBehavior = TownRunManager.GamblingFinish; Sequence sequenceGambling = new Sequence( new Zeta.TreeSharp.Action(actionDelegateGamblingStartBehavior), new Zeta.TreeSharp.Action(actionDelegateGamblingMovementBehavior), new Zeta.TreeSharp.Action(actionDelegateGamblingInteractionBehavior), new Zeta.TreeSharp.Action(actionDelegateGamblingFinishBehavior) ); GilesReplacement.InsertChild(8, new Decorator(canRunDelegateGambling, sequenceGambling)); Logger.DBLog.DebugFormat("[FunkyTownRun] Gambling Behavior - Inserted..."); #endregion #region Finish Behavior int childrenCount = GilesReplacement.Children.Count; ActionDelegate actionFinishReset = TownRunManager.ActionsEvaluatedEndingBehavior; ActionDelegate actionDelegateFinishBehavior = TownRunManager.FinishBehavior; var finish = GilesReplacement.Children[childrenCount - 1]; Sequence FinishSequence = new Sequence ( finish, new Zeta.TreeSharp.Action(actionFinishReset), new Zeta.TreeSharp.Action(actionDelegateFinishBehavior) ); GilesReplacement.Children[childrenCount - 1] = FinishSequence; Logger.DBLog.DebugFormat("[FunkyTownRun] Created Sequence Finish Behavior."); #endregion CanRunDecoratorDelegate canRunDelegateGilesTownRunCheck = TownRunManager.TownRunCheckOverlord; VendorCanRunDelegate = canRunDelegateGilesTownRunCheck; VendorPrioritySelector = GilesReplacement; var VendorComposite = new Decorator(canRunDelegateGilesTownRunCheck, GilesReplacement); VendorGUID = VendorComposite.Guid; HookHandler.SetHookValue(HookHandler.HookType.VendorRun, 0, VendorComposite); Logger.DBLog.DebugFormat("[FunkyTownRun] Vendor Run tree hooking finished."); #endregion initTreeHooks = true; }
public static Composite BuffSelfAndWaitPassive(SimpleStringDelegate name, SimpleBooleanDelegate requirements = null, int expirSecs = 0, CanRunDecoratorDelegate until = null, HasGcd gcd = HasGcd.Yes) { if (requirements == null) requirements = req => true; if (until == null) until = u => StyxWoW.Me.HasAura(u as string); return new PrioritySelector( ctx => { string spellName = name(ctx); SpellFindResults sfr; if (SpellManager.FindSpell(spellName, out sfr)) { spellName = (sfr.Override ?? sfr.Original).Name; } return spellName; }, new Decorator( req => SpellManager.HasSpell( req as string) && !Me.HasAura(req as string) && !DoubleCastContains(Me, req as string), new Sequence( Spell.Cast( sp => sp as string, mov => true, on => Me, requirements, cancel => false, LagTolerance.Yes, false, null, gcd: gcd), new PrioritySelector( new DynaWait( time => TimeSpan.FromMilliseconds(Me.Combat ? 500 : 1000), until, new Action( r => UpdateDoubleCast( r as string, Me, 3000 )) ), new Action(r => { Logger.WriteDiagnostic("BuffSelfAndWaitPassive: buff of [{0}] failed", name(r)); return RunStatus.Failure; }) ) ) ) ); }
public static Composite BuffSelfAndWait(string name, SimpleBooleanDelegate requirements = null, int expirSecs = 0, CanRunDecoratorDelegate until = null, bool measure = false, HasGcd gcd = HasGcd.Yes) { return BuffSelfAndWait(b => name, requirements, expirSecs, until, measure, gcd); }
public Composite CreateSpellCheckAndCast(string name, CanRunDecoratorDelegate extra) { return new Decorator(ret => extra(ret) && SpellManager.CanCast(name), new Action(delegate { SpellManager.Cast(name); Logging.Write("[DWCC]: " + name + "."); Logging.WriteDiagnostic("[DWCC]: Attempting to cast " + name + " on " + Me.CurrentTarget.Name.Remove(3, Me.CurrentTarget.Name.Length - 3) + "*** @ " + Me.CurrentTarget.CurrentHealth + "/" + Me.CurrentTarget.MaxHealth + " (" + Math.Round(Me.CurrentTarget.HealthPercent, 2) + "%)"); Logging.WriteDiagnostic("[DWCC]: Target: IsCasting: " + Me.CurrentTarget.IsCasting + " | IsPlayer: " + Me.CurrentTarget.IsPlayer + " | Distance: " + Math.Round(Me.CurrentTarget.Distance, 2) + " | Level: " + Me.CurrentTarget.Level + " | IsElite: " + Me.CurrentTarget.Elite + " | Adds: " + detectAdds().Count); Logging.WriteDiagnostic("[DWCC]: We are in: " + Me.ZoneText + " | Instance: " + Me.IsInInstance + " | Outdoors: " + Me.IsOutdoors + " | Battleground: " + Styx.WoWInternals.Battlegrounds.IsInsideBattleground + " | Indoors: " + Me.IsIndoors + " | Party: " + Me.GroupInfo.IsInParty + " | Raid: " + Me.GroupInfo.IsInRaid + " | Members: " + Me.PartyMembers.Count + "/" + Me.RaidMembers.Count + " | Health: " + Me.CurrentHealth + "/" + Me.MaxHealth + " (" + Math.Round(Me.HealthPercent, 2) + "%) | BattleStance: " + BattleStance + " | DefStance: " + DefStance + " | BerserkerStance: " + BersiStance); } )); }
public static Composite HeroicLeap(CanRunDecoratorDelegate cond) { return new Decorator(ret => Me.CurrentTarget != null && SpellManager.CanCast("Heroic Leap") && !Me.CurrentTarget.HasAura("Charge Stun") && Me.CurrentTarget.Attackable && cond(ret) && !Me.CurrentTarget.IsFlying && Me.CurrentTarget.Distance < 40 && Me.CurrentTarget.Distance >= 8, new Sequence( new Action(a => Logging.Write("[DWCC]: Heroic Leap.")), new Action(a => SpellManager.Cast("Heroic Leap")), new Action(ret => SpellManager.ClickRemoteLocation(Me.CurrentTarget.Location)))); }
public DecoratorContinue(CanRunDecoratorDelegate func, Composite decorated) : base(func, decorated) { }
public static Composite Cast(int spell, CanRunDecoratorDelegate conditions) { return new Decorator(ret => conditions(ret) && SpellManager.CanCast(spell) && SpellManager.Cast(spell), new SpellLog(spell)); }
public DecoratorThrottled(TimeSpan throttleTime, CanRunDecoratorDelegate canRun, Composite composite) :base(canRun, composite) { _throttleTime = throttleTime; _throttle = new Stopwatch(); _throttle.Reset(); _throttle.Start(); }
public static Composite Cast(int spell, WoWUnit target, CanRunDecoratorDelegate condition) { return new Decorator( ret => condition(ret) && SpellManager.CanCast(spell, target) && SpellManager.Cast(spell, target), new SpellLog(spell, target)); }
public static Composite BuffSelfAndWait(SimpleStringDelegate name, SimpleBooleanDelegate requirements = null, int expirSecs = 0, CanRunDecoratorDelegate until = null, bool measure = false, HasGcd gcd = HasGcd.Yes) { if (requirements == null) requirements = req => true; if (until == null) until = u => StyxWoW.Me.HasAura(name(u)); return new Sequence( BuffSelf(name, requirements, expirSecs, gcd), new PrioritySelector( new DynaWait( time => TimeSpan.FromMilliseconds(Me.Combat ? 500 : 1000), until, new ActionAlwaysSucceed(), measure ), new Action(r => { Logger.WriteDiagnostic("BuffSelfAndWait: buff of [{0}] failed", name(r)); return RunStatus.Failure; }) ) ); }
/// <summary> /// Creates a new Wait decorator with an 'infinite' timeout, the specified run delegate, and a child composite. /// </summary> /// <param name = "runFunc"></param> /// <param name = "child"></param> public Wait(CanRunDecoratorDelegate runFunc, Composite child) : this(int.MaxValue, runFunc, child) { }
/// <summary> /// Creates a new Wait decorator using the specified timeout, run delegate, and child composite. /// </summary> /// <param name = "timeoutSeconds"></param> /// <param name = "runFunc"></param> /// <param name = "child"></param> public Wait(int timeoutSeconds, CanRunDecoratorDelegate runFunc, Composite child) : base(runFunc, child) { Timeout = new TimeSpan(0, 0, timeoutSeconds); }
/// <summary> /// Finds a target that does not have the specified spell and applys it. /// </summary> /// <param name="cond">The conditions that must be true</param> /// <param name="spell">The spell to be cast</param> /// <returns>success we have aquired a target and failure if not.</returns> public static Composite FindMultiDotTarget(CanRunDecoratorDelegate cond, string spell) { return new Decorator( cond, new Sequence( // get a target new Action( delegate { if (!CLUSettings.Instance.EnableMultiDotting) { return RunStatus.Failure; } WoWUnit target = EnemyRangedUnits.FirstOrDefault(u => !u.HasAura(spell) && u.Distance2DSqr < 40 * 40); if (target != null) { CLULogger.DiagnosticLog(target.Name); target.Target(); return RunStatus.Success; } return RunStatus.Failure; }), new Action(a => StyxWoW.SleepForLagDuration()), // if success, keep going. Else quit new PrioritySelector(Buff.CastDebuff(spell, cond, spell)))); }
/// <summary> /// Allows waiting for SleepForLagDuration() but ending sooner if condition is met /// </summary> /// <param name="orUntil">if true will stop waiting sooner than lag maximum</param> /// <returns></returns> public static Composite CreateWaitForLagDuration(CanRunDecoratorDelegate orUntil) { return(new WaitContinue(TimeSpan.FromMilliseconds((StyxWoW.WoWClient.Latency * 2) + 150), orUntil, new ActionAlwaysSucceed())); }
public Composite FaceAoEPummel(CanRunDecoratorDelegate extra) { return new Decorator(ret => extra(ret) && !Me.IsFacing((WoWUnit)AoECastingAdds().FirstOrDefault()), new Action(delegate { ((WoWUnit)AoECastingAdds().FirstOrDefault()).Face(); Logging.Write("[DWCC]: Facing AoE Pummel target."); } )); }
public static Composite CastStatus(int spell, CanRunDecoratorDelegate conditions) { return new Decorator(ret => conditions(ret) && SpellManager.CanCast(spell), new Action(context => { if (SpellManager.Cast(spell)) { LogSpell(spell); return RunStatus.Success; } return RunStatus.Failure; })); }
/// <summary> /// Creates a new Wait decorator using the specified timeout, run delegate, and child composite. /// </summary> /// <param name = "timeoutSeconds"></param> /// <param name = "runFunc"></param> /// <param name = "child"></param> public Wait(int timeoutSeconds, CanRunDecoratorDelegate runFunc, Composite child) : base(runFunc, child) { Timeout = TimeSpan.FromSeconds(timeoutSeconds); }
public Composite TargetAoEPummel(CanRunDecoratorDelegate extra) { return new Decorator(ret => extra(ret) && Me.CurrentTarget != ((WoWUnit)AoECastingAdds().FirstOrDefault()), new Action(delegate { ((WoWUnit)AoECastingAdds().FirstOrDefault()).Target(); Logging.Write("[DWCC]: Targeting AoE Pummel target."); } )); }
/// <summary> /// Sets a trap at the specified targets location /// </summary> /// <param name="trapName">The name of the trap to use</param> /// <param name="onUnit">The unit to place the trap on</param> /// <param name="cond">Check conditions supplied are true</param> /// <returns></returns> public static Composite pvpTrapBehavior(string trapName, CLU.UnitSelection onUnit, CanRunDecoratorDelegate cond) { return( new PrioritySelector( new Decorator(delegate(object a) { if (!cond(a)) { return false; } return onUnit != null && onUnit(a) != null && onUnit(a).DistanceSqr <= 20 * 20 && SpellManager.HasSpell(trapName) && !SpellManager.Spells[trapName].Cooldown; }, new PrioritySelector( Buff.CastBuff("Trap Launcher", ret => !Buff.PlayerHasBuff("Trap Launcher"), "Trap Launcher"), Spell.CastSpell("Scatter Shot", ret => true, "Scatter Shot"), new Decorator(ret => Buff.PlayerHasBuff("Trap Launcher"), new Sequence( new Action(ret => Lua.DoString(string.Format("CastSpellByName(\"{0}\")", trapName))), new WaitContinue(TimeSpan.FromMilliseconds(200), ret => false, new ActionAlwaysSucceed()), new Action(ret => SpellManager.ClickRemoteLocation(onUnit(ret).Location))))) ))); }
public static Composite UseItem(WoWItemDelegate item, CanRunDecoratorDelegate cond) { return new Decorator(ret => item(ret) != null && cond(ret) && ItemUsable(item(ret)), new Action(ret => { item(ret).Use(); Logging.Write(LogLevel.Normal, item(ret).Name); return RunStatus.Failure; } ) ); }
public static Composite UseSpecialAbilities(CanRunDecoratorDelegate cond) { return new PrioritySelector( UseItem(ret => mTrinket1, ret => cond(ret) && mTrinket1Usable), UseItem(ret => mTrinket2, ret => cond(ret) && mTrinket2Usable), UseItem(ret => mGloves, ret => cond(ret) && mGlovesUsable), new Decorator(ret => mRacialName != null && Helpers.Rogue.mCurrentEnergy < 65 && mRacialName.Equals("Arcane Torrent"), Spells.CastSelf(mRacialName)), new Decorator(ret => mRacialName != null && mRacialName.Length > 3 && !mRacialName.Equals("Arcane Torrent"), Spells.CastSelf(mRacialName)) ); }
/// <summary> /// Finds a Party that needs healing /// </summary> /// <param name="cond">The conditions that must be true</param> /// <param name="minAverageHealth">Minimum Average health of the Party Members</param> /// <param name="maxAverageHealth">MaximumAverage health of the Party Members</param> /// <param name="maxDistanceBetweenPlayers">The maximum distance between other party members from the targeted party member</param> /// <param name="minUnits">Minumum units to be affected</param> /// <param name="reason">text to indicate the reason for using this method </param> /// <param name="children">Execute the child subroutines</param> /// <returns>A party member</returns> public Composite FindParty(CanRunDecoratorDelegate cond, int minAverageHealth, int maxAverageHealth, float maxDistanceBetweenPlayers, int minUnits, string reason, params Composite[] children) { return new Decorator( cond, new Sequence( new PrioritySelector( FindPartySubroutine(0, minAverageHealth, maxAverageHealth, maxDistanceBetweenPlayers, minUnits, "[CLU TARGETING] " + CLU.Version + ": " + "Target PARTY 1 MEMBER: {0} REASON: " + reason), FindPartySubroutine(1, minAverageHealth, maxAverageHealth, maxDistanceBetweenPlayers, minUnits, "[CLU TARGETING] " + CLU.Version + ": " + "Target PARTY 2 MEMBER: {0} REASON: " + reason), FindPartySubroutine(2, minAverageHealth, maxAverageHealth, maxDistanceBetweenPlayers, minUnits, "[CLU TARGETING] " + CLU.Version + ": " + "Target PARTY 3 MEMBER: {0} REASON: " + reason), FindPartySubroutine(3, minAverageHealth, maxAverageHealth, maxDistanceBetweenPlayers, minUnits, "[CLU TARGETING] " + CLU.Version + ": " + "Target PARTY 4 MEMBER: {0} REASON: " + reason), FindPartySubroutine(4, minAverageHealth, maxAverageHealth, maxDistanceBetweenPlayers, minUnits, "[CLU TARGETING] " + CLU.Version + ": " + "Target PARTY 5 MEMBER: {0} REASON: " + reason), FindPartySubroutine(5, minAverageHealth, maxAverageHealth, maxDistanceBetweenPlayers, minUnits, "[CLU TARGETING] " + CLU.Version + ": " + "Target PARTY 6 MEMBER: {0} REASON: " + reason), FindPartySubroutine(6, minAverageHealth, maxAverageHealth, maxDistanceBetweenPlayers, minUnits, "[CLU TARGETING] " + CLU.Version + ": " + "Target PARTY 7 MEMBER: {0} REASON: " + reason), FindPartySubroutine(7, minAverageHealth, maxAverageHealth, maxDistanceBetweenPlayers, minUnits, "[CLU TARGETING] " + CLU.Version + ": " + "Target PARTY 8 MEMBER: {0} REASON: " + reason) ), new Action(a => StyxWoW.SleepForLagDuration()), // if success, keep going. Else quit sub routine new PrioritySelector(children) ) ); }
/// <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()))); }