/// <summary> /// creates Composite that if we are too close to melee range /// will pick a safe point away and run to it, doing jump turns /// if non-null <paramref name="attack"/> composite provided /// </summary> /// <param name="attack">attack rotation of instant spells. jump turn disabled if 'null'</param> /// <returns>Composite to add in behavior</returns> public static Composite CreateKitingWithJump(Composite attack) { return new Decorator( ret => !SingularSettings.Instance.DisableAllMovement, new PrioritySelector( // BACK PEDDLE new Decorator(ret => IsKitingNeeded(), new Action(ret => BeginKitingToSafeArea())), // IN PROGRESS ? new Decorator( ret => state != JumpTurnState.None, // do this to do fewer if's during 95% of combat new PrioritySelector( // RESET IF NOT READY new Decorator(ret => stopKiting < DateTime.Now, new Action(ret => EndKiting("BPWJ: back peddle timed out, cancelling"))), new Decorator(ret => !StyxWoW.IsInGame, new Action(ret => EndKiting("BPWJ: not in game so cancelling"))), new Decorator(ret => !Me.IsAlive, new Action(ret => EndKiting("BPWJ: i am dead so cancelling"))), new Decorator(ret => !Me.GotTarget, new Action(ret => EndKiting("BPWJ: no target, cancelling"))), new Decorator(ret => !Me.CurrentTarget.IsAlive, new Action(ret => EndKiting("BPWJ: target dead, cancelling"))), // new DecoratorContinue(ret => Me.IsMoving, new Action( a => movementCheck = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, 1000)))), new Decorator(ret => movementCheck < DateTime.Now && !Me.IsMoving, new Action( delegate { if (Me.Stunned || Me.IsStunned()) EndKiting("BPWJ: stunned so cancelling"); else if (Me.Rooted || Me.IsRooted()) EndKiting("BPWJ: rooted so cancelling"); else return RunStatus.Failure; return RunStatus.Success; })), // STOP IF NEAR DEST new Decorator( ret => bpwjDest.Distance(Me.Location) < DISTANCE_CLOSE_ENOUGH_TO_DESTINATION, new Action(ret => EndKiting("BPWJ: reached destination"))), // STOP IF TOO FAR AWAY FROM DEST new Decorator( ret => bpwjDest.Distance(Me.Location) > DISTANCE_TOO_FAR_FROM_DESTINATION, new Action(ret => EndKiting(String.Format("BPWJ: cancel, too far from destination @ {0:F1} yds", bpwjDest.Distance(Me.Location))))), // STOP IF JUMP TIMED OUT new Decorator( ret => IsStateJumping() && stopJump <= DateTime.Now, new Action(ret => EndKiting("BPWJ: cancel, jump turn timeout"))), // GOBLINS ROCKET JUMP IF WE CAN AND MAKES SENSE Spell.BuffSelf("Rocket Jump", ret => IsRocketJumpNeeded()), // DO JUMP TURN NOW (MUST APPEAR AFTER GCD / CASTING CHECK SO JUMP NOT STARTED WHILE ABILITY CANNOT BE CAST new Decorator(ret => state == JumpTurnState.RunAway, new Action(ret => StartJumpTurn())), // JUMPED AND TURNED, SO WAITING TO ATTACK new Decorator(ret => state == JumpTurnState.WaitBeforeAttack, new Action(ret => WaitingBeforeAttack())), // ATTACK IN MID-AIR new Decorator( ret => state == JumpTurnState.Attacking && Me.IsSafelyFacing(Me.CurrentTarget), new Sequence( new Decorator(ret => attack != null, attack), new Action(ret => Logger.WriteDebug( Color.Cyan, "BPWJ: post-attack")), new Action(ret => state = JumpTurnState.WaitAfterAttack) ) ), // ATTACKED, SO WAITING TO TURN BACK AND MOVE AWAY new Decorator(ret => state == JumpTurnState.WaitAfterAttack, new Action(ret => WaitingAfterAttack())), // CATCH ALL new Action(ret => Logger.WriteDebug( Color.Cyan, "BPWJ: current state {0}...", state.ToString())) ) ) ) ); }
private static RunStatus WaitingBeforeAttack() { Debug.Assert(state == JumpTurnState.WaitBeforeAttack, "State is not WAITBEFOREATTACK"); Logger.WriteDebug(Color.Cyan, "BPWJ: pre-attack"); if (waitBeforeJumpTurnAttack > DateTime.Now) { return RunStatus.Success; } waitAfterJumpTurnAttack = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, WAIT_AFTER_ATTACK )); Logger.WriteDebug( Color.Cyan, "BPWJ: transition to attack"); state = JumpTurnState.Attacking; return RunStatus.Failure; }
private static RunStatus WaitingAfterAttack() { Debug.Assert(state == JumpTurnState.WaitAfterAttack, "State is not WAITAFTERATTACK"); Logger.WriteDebug(Color.Cyan, "BPWJ: waiting to turn back and move away"); if (waitAfterJumpTurnAttack > DateTime.Now) { return RunStatus.Success; } Logger.WriteDebug( Color.Cyan, "BPWJ: turning back and move away"); WoWMovement.StopFace(); WoWMovement.MoveStop(WoWMovement.MovementDirection.JumpAscend); Navigator.MoveTo(bpwjDest); state = JumpTurnState.RunAway; return RunStatus.Success; }
private static RunStatus StartJumpTurn() { Debug.Assert(state == JumpTurnState.RunAway, "State is not RUNAWAY"); if (!SingularSettings.Instance.Hunter.UseJumpTurn) return RunStatus.Failure; if (SpellManager.GlobalCooldown || Me.IsCasting) return RunStatus.Failure; if (Me.IsSwimming) { Logger.WriteDebug( Color.Cyan, "BPWJ: swimming so Jump Turn skipped"); return RunStatus.Failure; } stopJump = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, 750)); waitBeforeJumpTurnAttack = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, WAIT_BEFORE_ATTACK )); WoWMovement.Move(WoWMovement.MovementDirection.JumpAscend); Me.CurrentTarget.Face(); Logger.WriteDebug( Color.Cyan, "Jump Turn"); state = JumpTurnState.WaitBeforeAttack; return RunStatus.Success; }
private static RunStatus EndKiting(string s) { state = JumpTurnState.None; Logger.WriteDebug( Color.Gold, s); WoWMovement.StopFace(); WoWMovement.MoveStop(WoWMovement.MovementDirection.All); return RunStatus.Success; }
/* private static RunStatus BeginKiting() { bpwjDest = WoWMathHelper.CalculatePointFrom(Me.Location, Me.CurrentTarget.Location, Spell.MeleeRange + DISTANCE_WE_NEED_TO_START_BACK_PEDAL); if (Navigator.CanNavigateFully(StyxWoW.Me.Location, bpwjDest)) { state = JumpTurnState.RunAway; Logger.WriteDebug( Color.Cyan, "Back peddling"); movementCheck = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, 500)); Navigator.MoveTo(bpwjDest); } return RunStatus.Success; } */ private static RunStatus BeginKitingToSafeArea() { SafeArea sa = new SafeArea(); sa.MinScanDistance = Spell.MeleeRange + 15; sa.IncrementScanDistance = 5; sa.MaxScanDistance = sa.MinScanDistance + sa.IncrementScanDistance; sa.RaysToCheck = 18; sa.MinSafeDistance = 15; bpwjDest = sa.FindLocation(); if (bpwjDest != WoWPoint.Empty) { state = JumpTurnState.RunAway; Logger.WriteDebug( Color.Cyan, "Back peddling"); Navigator.MoveTo(bpwjDest); movementCheck = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, 1000)); stopKiting = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, 8000)); return RunStatus.Success; } return RunStatus.Failure; }