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(); })) )); }