public static Composite CreateDisengageBehavior() { return (new Decorator( ret => IsDisengageNeeded(), new Sequence( new ActionDebugString(ret => "face away from or towards safespot as needed"), new Action(delegate { if (useRocketJump) { needFacing = Styx.Helpers.WoWMathHelper.CalculateNeededFacing(Me.Location, safeSpot); } else { needFacing = Styx.Helpers.WoWMathHelper.CalculateNeededFacing(safeSpot, Me.Location); } needFacing = WoWMathHelper.NormalizeRadian(needFacing); float rotation = WoWMathHelper.NormalizeRadian(Math.Abs(needFacing - Me.RenderFacing)); Logger.Write(Color.Cyan, "DIS: turning {0:F0} degrees {1} safe landing spot", WoWMathHelper.RadiansToDegrees(rotation), useRocketJump ? "towards" : "away from"); Me.SetFacing(needFacing); }), new ActionDebugString(ret => "wait for facing to complete"), new PrioritySelector( new Wait(new TimeSpan(0, 0, 1), ret => Me.IsDirectlyFacing(needFacing), new ActionAlwaysSucceed()), new Action(ret => { Logger.Write(Color.Cyan, "DIS: timed out waiting to face safe spot - need:{0:F4} have:{1:F4}", needFacing, Me.RenderFacing); return RunStatus.Failure; }) ), // stop facing new Action(ret => { Logger.Write(Color.Cyan, "DIS: cancel facing now we point the right way"); WoWMovement.StopFace(); }), new ActionDebugString(ret => "set time of disengage just prior"), new Sequence( new PrioritySelector( new Decorator(ret => !useRocketJump, Spell.BuffSelf("Disengage")), new Decorator(ret => useRocketJump, Spell.BuffSelf("Rocket Jump")), new Action(ret => Logger.Write(Color.Cyan, "DIS: {0} cast appears to have failed", useRocketJump ? "Rocket Jump" : "Disengage")) ), new Action(ret => { NextDisengageAllowed = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, 750)); Logger.Write(Color.Cyan, "DIS: finished {0} cast", useRocketJump ? "Rocket Jump" : "Disengage"); if (Kite.IsKitingActive()) { Kite.EndKiting(String.Format("BP: Interrupted by {0}", useRocketJump ? "Rocket Jump" : "Disengage")); } return RunStatus.Success; }) ) ) )); }