protected override Composite CreateBehavior() { return(_root ?? (_root = new PrioritySelector( // first state catches if we are done just in case new Decorator(ret => _isBehaviorDone, new Action(delegate { return RunStatus.Success; })), // if we hit the load screen and we are back in game new Decorator(ret => _isInPortal && ObjectManager.IsInGame && StyxWoW.Me != null, new Action(delegate { _isBehaviorDone = true; UtilLogMessage("info", "Went thru portal."); Thread.Sleep(500); WoWMovement.MoveStop(); Thread.Sleep(500); return RunStatus.Success; })), // if zone name changed new Decorator(ret => ZoneText != StyxWoW.Me.ZoneText, new Action(ret => _isInPortal = true)), // if load screen is visible new Decorator(ret => !ObjectManager.IsInGame || StyxWoW.Me == null, new Action(ret => _isInPortal = true)), // if we are within 2 yards of calculated end point we should never reach new Decorator(ret => MovePoint.Distance(Me.Location) < 2, new Action(delegate { _isBehaviorDone = true; WoWMovement.MoveStop(); UtilLogMessage("fatal", "Unable to reach end point. Failed to go through portal."); return RunStatus.Success; })), new Decorator(ret => Timeout != 0 && Timeout < System.Environment.TickCount, new Action(delegate { _isBehaviorDone = true; WoWMovement.MoveStop(); UtilLogMessage("fatal", "Timed out after {0} ms. Failed to go through portal", Timeout); return RunStatus.Success; })), new Decorator(ret => !StyxWoW.Me.IsMoving, new Action(delegate { UtilLogMessage("info", "Moving to {0}", MovePoint); WoWMovement.ClickToMove(MovePoint); return RunStatus.Success; })) ) )); }