private Composite SubBehavior_CombatWithViableMob() { return(new PrioritySelector(context => SelectedTarget = Me.CurrentTarget, // Recall pet, if necessary... new Decorator(context => (SelectedTarget.HealthPercent < RecallPetAtMobPercentHealth) && (Me.GotAlivePet && Me.Pet.GotTarget), new ActionFail(context => { QBCLog.Info("Recalling Pet from '{0}' (health: {1:F1})", SelectedTarget.SafeName, SelectedTarget.HealthPercent); PetControl.SetStance_Passive(); PetControl.Follow(); })), // If we are beyond the max range allowed to use the item, move within range... new Decorator(context => SelectedTarget.Distance > MaxRangeToUseItem, new ActionRunCoroutine( interactUnitContext => UtilityCoroutine.MoveTo( SelectedTarget.Location, string.Format("within {0} feet of {1}", MaxRangeToUseItem, SelectedTarget.SafeName), MovementBy, (float)MaxRangeToUseItem))), // If time to use the item, do so... new Decorator(context => IsUseItemNeeded(SelectedTarget), new PrioritySelector( new ActionRunCoroutine(context => CommonCoroutines.StopMoving()), // Halt combat until we are able to use the item... new Decorator(context => ((UseItemStrategy == UseItemStrategyType.UseItemContinuouslyOnTargetDontDefend) || (UseItemStrategy == UseItemStrategyType.UseItemOncePerTargetDontDefend)), new ActionFail(context => { // We use LUA to stop casting, since SpellManager.StopCasting() doesn't seem to work... if (Me.IsCasting) { Lua.DoString("SpellStopCasting()"); } if (Me.IsAutoAttacking) { Lua.DoString("StopAttack()"); } TreeRoot.StatusText = string.Format("Combat halted--waiting for {0} to become usable.", Utility.GetItemNameFromId(ItemId)); })), new Sequence( new ActionRunCoroutine(ctx => UtilityCoroutine.UseItemOnTarget( ItemId, SelectedTarget, () => BehaviorDone(string.Format("Terminating behavior due to missing {0}", Utility.GetItemNameFromId(ItemId))))), // Allow a brief time for WoWclient to apply aura to mob... new WaitContinue(TimeSpan.FromMilliseconds(5000), context => ItemUseAlwaysSucceeds || SelectedTarget.HasAura(ItemAppliesAuraId), new ActionAlwaysSucceed()), new ActionFail(context => { _waitTimerAfterUsingItem.Reset(); if (ItemUseAlwaysSucceeds || SelectedTarget.HasAura(ItemAppliesAuraId)) { // Count our success if no associated quest... if (!VariantQuestIds.Any()) { ++Counter; } // If we can only use the item once per target, blacklist this target from subsequent selection... if ((UseItemStrategy == UseItemStrategyType.UseItemOncePerTarget) || (UseItemStrategy == UseItemStrategyType.UseItemOncePerTargetDontDefend)) { SelectedTarget.BlacklistForInteracting(TimeSpan.FromSeconds(InteractBlacklistTimeInSeconds)); } // If we can't defend ourselves from the target, blacklist it for combat and move on... if (Query.IsViable(SelectedTarget) && ((UseItemStrategy == UseItemStrategyType.UseItemContinuouslyOnTargetDontDefend) || (UseItemStrategy == UseItemStrategyType.UseItemOncePerTargetDontDefend))) { SelectedTarget.BlacklistForCombat(TimeSpan.FromSeconds(InteractBlacklistTimeInSeconds)); BotPoi.Clear(); Me.ClearTarget(); SelectedTarget = null; } } if ((ItemAppliesAuraId > 0) && !SelectedTarget.HasAura(ItemAppliesAuraId)) { var auraNamesOnMob = ((SelectedTarget.Auras.Keys.Count > 0) ? string.Join(", ", SelectedTarget.Auras.Keys) : "none"); QBCLog.Warning("{1} did not acquire expected AuraId, \"{2}\"--retrying.{0}" + " Auras on {1}: {3}", Environment.NewLine, SelectedTarget.SafeName, Utility.GetSpellNameFromId(ItemAppliesAuraId), auraNamesOnMob); } }), // Prevent combat, if we're not supposed to defend... new Decorator(context => ((UseItemStrategy == UseItemStrategyType.UseItemContinuouslyOnTargetDontDefend) || (UseItemStrategy == UseItemStrategyType.UseItemOncePerTargetDontDefend)), new ActionAlwaysSucceed()) ))) )); }