public Composite CreateBehavior_SelectTarget(BehaviorFailIfNoTargetsDelegate failIfNoTargets) { return( new PrioritySelector( // If we haven't engaged the mob when the auto-blacklist timer expires, give up on it and move on... new Decorator(ret => ((CurrentTarget != null) && (_currentTargetAutoBlacklistTimer.Elapsed > _currentTargetAutoBlacklistTime)), new Action(delegate { QBCLog.Warning("Taking too long to engage '{0}'--blacklisting", CurrentTarget.SafeName); CurrentTarget.LocallyBlacklist(_delay_AutoBlacklist); CurrentTarget = null; })), // If we don't have a current target, select a new one... // Once we select a target, its 'locked in' (unless it gets blacklisted). This prevents us // from running back and forth between two equidistant targets. new Decorator(ret => ((CurrentTarget == null) || !CurrentTarget.IsValid || CurrentTarget.IsLocallyBlacklisted()), new PrioritySelector(context => CurrentTarget = ViableTargets().FirstOrDefault(), // If we found next target, we're done... new Decorator(ret => (CurrentTarget != null), new Action(delegate { _huntingGroundWaitPoint = WoWPoint.Empty; if (CurrentTarget is WoWUnit) { CurrentTarget.ToUnit().Target(); } _currentTargetAutoBlacklistTime = CalculateAutoBlacklistTime(CurrentTarget); _currentTargetAutoBlacklistTimer.Reset(); _currentTargetAutoBlacklistTimer.Start(); })), // If we've exhausted mob/object supply in area, and we need to wait, do so... new Decorator(ret => !failIfNoTargets(), // Move back to hunting ground anchor -- new PrioritySelector( // If we've more than one hotspot, head to the next one... new Decorator(ret => (_hotSpots.Count() > 1), new Sequence(context => FindNextHotspot(), new Action(nextHotspot => TreeRoot.StatusText = "No targets--moving to hotspot " + (WoWPoint)nextHotspot), CreateBehavior_InternalMoveTo(() => FindNextHotspot()) )), // We find a point 'near' our anchor at which to wait... // This way, if multiple people are using the same profile at the same time, // they won't be standing on top of each other. new Decorator(ret => (_huntingGroundWaitPoint == WoWPoint.Empty), new Action(delegate { _huntingGroundWaitPoint = HuntingGroundAnchor.FanOutRandom(CollectionDistance * 0.25); TreeRoot.StatusText = "No targets--moving near hunting ground anchor point to wait"; _repopWaitingTime.Reset(); _repopWaitingTime.Start(); })), // Move to our selected random point... new Decorator(ret => !Navigator.AtLocation(_huntingGroundWaitPoint), CreateBehavior_InternalMoveTo(() => _huntingGroundWaitPoint)), // Tell user what's going on... new Sequence( new Action(delegate { TreeRoot.GoalText = this.GetType().Name + ": Waiting for Repops"; TreeRoot.StatusText = "No targets in area--waiting for repops. " + BuildTimeAsString(_repopWaitingTime.Elapsed); }), new WaitContinue(_delay_RepopWait, ret => false, new ActionAlwaysSucceed())) )) )), // Re-select target, if it was lost (perhaps, due to combat)... new Decorator(ret => ((CurrentTarget is WoWUnit) && (Me.CurrentTarget != CurrentTarget)), new Action(delegate { CurrentTarget.ToUnit().Target(); })) )); }
protected override Composite CreateBehavior() { return(_behaviorRoot ?? (_behaviorRoot = new PrioritySelector( // If the quest is complete, and we need to press a final button... new Decorator(ret => Me.IsQuestComplete(QuestId), new Sequence( new DecoratorContinue(ret => ButtonOnQuestComplete.HasValue, new Action(delegate { TreeRoot.StatusText = string.Format("Pressing Button {0} at Quest Complete.", ButtonOnQuestComplete.Value); Lua.DoString("RunMacroText(\"/click OverrideActionBarButton{0}\")", ButtonOnQuestComplete.Value); })), // If behavior done, bail... // Note that this is also an implicit "is quest complete" exit criteria, also. new Action(delegate { GuiShowProgress("quest complete"); _isBehaviorDone = true; }) )), // Find next target... _behavior_HuntingGround.CreateBehavior_SelectTarget(), // Move to next target... _behavior_HuntingGround.CreateBehavior_MoveToTarget(), new PrioritySelector(context => TargetAurasShowing(CurrentTarget, _targetAuraToButtonMap).FirstOrDefault(), // If no aura showing, blacklist the target, we're done with it... new Decorator(auraShowing => (auraShowing == null), new Action(delegate { TreeRoot.StatusText = string.Format("Done with '{0}'... moving on", CurrentTarget.SafeName); CurrentTarget.LocallyBlacklist(_delay_MobConsumedExpiry); })), // Push the button associated with the next aura shown... // We assume the target may have multiple auras that need redress, so we don't // blacklist the target reacting to one aura. new Sequence( new Action(delegate { WoWMovement.MoveStop(); }), new DecoratorContinue(ret => (Me.CurrentTarget != CurrentTarget), new Action(delegate { CurrentTarget.Target(); })), new DecoratorContinue(ret => !Me.IsSafelyFacing(CurrentTarget), new Action(delegate { CurrentTarget.Face(); })), new Action(delegate { _behavior_HuntingGround.MobEngaged(CurrentTarget); }), new WaitContinue(Delay_WowClientLagTime, ret => false, new ActionAlwaysSucceed()), new Action(auraShowing => { WoWAura aura = (WoWAura)auraShowing; TreeRoot.StatusText = string.Format("Pressing Button {0} on {1} for Aura({2}).", _targetAuraToButtonMap[aura.SpellId], CurrentTarget.SafeName, aura.Name); Lua.DoString("RunMacroText(\"/click OverrideActionBarButton{0}\")", _targetAuraToButtonMap[aura.SpellId]); }), new WaitContinue(Delay_WowClientLagTime, ret => false, new ActionAlwaysSucceed()), new WaitContinue(PostInteractDelay, ret => false, new ActionAlwaysSucceed()), new Action(delegate { Me.ClearTarget(); }) ) ) ))); }