private Composite SubBehaviorPS_UpdatePathWaypoint() { return (new Decorator(ret => PathPatrol.Peek().Distance2DSquared(DragonVehicle.Location) <= (30 * 30), new ActionFail(ret => PathPatrol.Dequeue()))); }
private Composite StateBehaviorPS_CompletingObjectives() { return(new PrioritySelector( // If for some reason no longer in the vehicle, go fetch another... new Decorator(context => !Query.IsViable(DragonVehicle), new Action(context => { QBCLog.Warning("We've been jettisoned from vehicle unexpectedly--will try again."); BehaviorState = BehaviorStateType.MountingVehicle; })), // If quest is complete, then head back... new Decorator(context => Me.IsQuestComplete(GetQuestId()), new Action(context => { BehaviorState = BehaviorStateType.ReturningToBase; })), new CompositeThrottle(Throttle.UserUpdate, new ActionFail(context => { TreeRoot.StatusText = "Completing Quest Objectives"; })), SubBehaviorPS_UpdatePathWaypoint(), SubBehaviorPS_Heal(), // We go after the Ballistas first... // NB: Soldiers will be collateral damage of pursing Ballistas. // If the soldiers don't complete after doing Ballistas, we'll clean up // the Soldiers next. new Decorator(context => !IsViableTarget(SelectedTarget), new PrioritySelector( // Try to find target... new ActionFail(context => { SelectedTarget = FindMobToKill(!Me.IsQuestObjectiveComplete(GetQuestId(), 2) ? MobId_ScarletBallista : MobId_TirisfalCrusader); }), // If no target found, move toward next waypoint... new Decorator(context => !IsViableTarget(SelectedTarget), new Action(context => { Flightor.MoveTo(PathPatrol.Peek(), (float)FlightorMinHeight); })) )), new Action(context => { // NB: We would've preferred to strafe in this algorithm; however, // strafing triggers Flightor's unstuck handler too much. Probably because // this is a vehicle/transport, instead of a 'flying mount'. // Show the target we're pursuing... Utility.Target(SelectedTarget); var myLocation = WoWMovement.ActiveMover.Location; var selectedTargetLocation = SelectedTarget.Location; var distance2DSqrToTarget = myLocation.Distance2DSquared(selectedTargetLocation); // Deal with needed evasion... if (StationPoint.HasValue) { if (myLocation.Distance(StationPoint.Value) > FlyingPathPrecision) { Flightor.MoveTo(StationPoint.Value); return RunStatus.Success; } StationPoint = null; } // See if we need a new 'on station' location... if (!StationPoint.HasValue) { // If our weapon is not ready or we can't see target, move around station until it is... if (!Weapon_FrozenDeathbolt.IsWeaponReady() || (IsViableTarget(SelectedTarget) && !SelectedTarget.InLineOfSight) || IsIncomingMissile()) { StationPoint = FindNewStationPoint(SelectedTarget); return RunStatus.Success; } } // If we are too far from selected target, close the distance... if (distance2DSqrToTarget > (TargetDistance2DMax * TargetDistance2DMax)) { Flightor.MoveTo(FindDistanceClosePoint(SelectedTarget, PathPatrol.Peek().Z)); return RunStatus.Success; } // If we are too close to selected target, put some distance between us... if (distance2DSqrToTarget < (TargetDistance2DMin * TargetDistance2DMin)) { Flightor.MoveTo(FindDistanceGainPoint(SelectedTarget, TargetDistance2DMin)); return RunStatus.Success; } // If weapon is not ready, just keep on station/evading... if (!Weapon_FrozenDeathbolt.IsWeaponReady()) { return RunStatus.Success; } // If the weapon cannot address the target, blacklist target and find another... if (!Weapon_FrozenDeathbolt.WeaponAim(SelectedTarget)) { _targetBlacklist.Add(SelectedTarget, TimeSpan.FromSeconds(5)); } // If weapon cannot fire for some reason, try again... if (!Weapon_FrozenDeathbolt.WeaponFire()) { return RunStatus.Success; } return RunStatus.Failure; // fall through }), // NB: Need to delay a bit for the weapon to actually launch. Otherwise // it screws the aim up if we move again before projectile is fired. new Sleep(ctx => Delay.LagDuration + Delay.AfterWeaponFire) //new Wait(Delay.LagDuration, context => Weapon_FrozenDeathbolt.IsWeaponReady(), new ActionAlwaysSucceed()) )); }