private Composite CreateMainBehavior()
        {
            return(new PrioritySelector(

                       // If quest is done, behavior is done...
                       new Decorator(context => IsDone,
                                     new Action(context =>
            {
                _isBehaviorDone = true;
                QBCLog.Info("Finished");
            })),


                       // Stateful Operation:
                       new Switch <StateType_MainBehavior>(context => State_MainBehavior,
                                                           #region State: DEFAULT
                                                           new Action(context => // default case
            {
                QBCLog.MaintenanceError("StateType_MainBehavior({0}) is unhandled", State_MainBehavior);
                TreeRoot.Stop();
                _isBehaviorDone = true;
            }),
                                                           #endregion


                                                           #region State: Dropping Off Victim
                                                           new SwitchArgument <StateType_MainBehavior>(StateType_MainBehavior.DroppingOffVictim,
                                                                                                       new PrioritySelector(
                                                                                                           // If Watchman dropped off, go get another...
                                                                                                           new Decorator(context => !Me.HasAura(AuraId_RescueDrowningWatchman),
                                                                                                                         new Action(context =>
            {
                WoWMovement.MoveStop();
                _currentPath = null;
                SelectedTarget = null;
                State_MainBehavior = StateType_MainBehavior.PathingOutToVictim;
            })),

                                                                                                           // Move to drop off spot...
                                                                                                           new Decorator(context => Me.Location.Distance(PositionToMakeLandfall) > Navigator.PathPrecision,
                                                                                                                         new ActionRunCoroutine(
                                                                                                                             context => UtilityCoroutine.MoveTo(
                                                                                                                                 PositionToMakeLandfall,
                                                                                                                                 "back to shore")))
                                                                                                           )),
                                                           #endregion


                                                           #region State: Pathing Out to Victim
                                                           new SwitchArgument <StateType_MainBehavior>(StateType_MainBehavior.PathingOutToVictim,
                                                                                                       new PrioritySelector(
                                                                                                           // If our selected target is no good, find another...
                                                                                                           new Decorator(context => !IsViableDrowningWatchman(SelectedTarget),
                                                                                                                         new Action(context =>
            {
                QBCLog.Info("Finding new Drowning Watchman to save");
                _currentPath = null;
                SelectedTarget = FindDrowningWatchman();
            })),

                                                                                                           // Show user which target we're after...
                                                                                                           new Decorator(context => Me.CurrentTarget != SelectedTarget,
                                                                                                                         new Action(context => { SelectedTarget.Target(); })),

                                                                                                           // If we don't have a path to victim, find one...
                                                                                                           new Decorator(context => _currentPath == null,
                                                                                                                         new Action(context => { _currentPath = FindPath(Me.Location, SelectedTarget.Location); })),

                                                                                                           // If path completely consumed, we're done...
                                                                                                           new Decorator(context => _currentPath.Count() <= 0,
                                                                                                                         new Action(context => { State_MainBehavior = StateType_MainBehavior.Rescuing; })),

                                                                                                           // If we've arrived at the current waypoint, dequeue it...
                                                                                                           new Decorator(context => Navigator.AtLocation(_currentPath.Peek()),
                                                                                                                         new Action(context => { _currentPath.Dequeue(); })),

                                                                                                           // Follow the prescribed path...
                                                                                                           new ActionRunCoroutine(
                                                                                                               context => UtilityCoroutine.MoveTo(
                                                                                                                   _currentPath.Peek(),
                                                                                                                   "out to Drowned Watcman"))
                                                                                                           )),
                                                           #endregion


                                                           #region State: Rescuing
                                                           new SwitchArgument <StateType_MainBehavior>(StateType_MainBehavior.Rescuing,
                                                                                                       new PrioritySelector(
                                                                                                           // If we've got the Watchman, start heading in...
                                                                                                           new Decorator(context => Me.HasAura(AuraId_RescueDrowningWatchman),
                                                                                                                         new Action(context =>
            {
                _currentPath = null;
                State_MainBehavior = StateType_MainBehavior.PathingIntoShore;
            })),

                                                                                                           // If our selected target is no good, find another...
                                                                                                           new Decorator(context => !IsViableDrowningWatchman(SelectedTarget),
                                                                                                                         new Action(context =>
            {
                _currentPath = null;
                SelectedTarget = null;
                State_MainBehavior = StateType_MainBehavior.PathingOutToVictim;
            })),

                                                                                                           // Go get a fresh Drowning Watchman...
                                                                                                           UtilityBehavior_InteractWithMob(context => SelectedTarget)
                                                                                                           )),
                                                           #endregion


                                                           #region State: Pathing Into Shore
                                                           new SwitchArgument <StateType_MainBehavior>(StateType_MainBehavior.PathingIntoShore,
                                                                                                       new PrioritySelector(
                                                                                                           // If we don't have a path, find the correct one...
                                                                                                           new Decorator(context => _currentPath == null,
                                                                                                                         new Action(context => { _currentPath = FindPath(Me.Location, PositionToMakeLandfall); })),

                                                                                                           // If path completely consumed, we're done...
                                                                                                           new Decorator(context => _currentPath.Count() <= 0,
                                                                                                                         new Action(context => { State_MainBehavior = StateType_MainBehavior.DroppingOffVictim; })),

                                                                                                           // If we've lost the Watchman we rescued, go fetch another...
                                                                                                           new Decorator(context => !Me.HasAura(AuraId_RescueDrowningWatchman),
                                                                                                                         new Action(context =>
            {
                _currentPath = null;
                SelectedTarget = null;
                State_MainBehavior = StateType_MainBehavior.PathingOutToVictim;
            })),

                                                                                                           // If we've arrived at the current waypoint, dequeue it...
                                                                                                           new Decorator(context => Navigator.AtLocation(_currentPath.Peek()),
                                                                                                                         new Action(context => { _currentPath.Dequeue(); })),

                                                                                                           // Follow the prescribed path...
                                                                                                           new ActionRunCoroutine(
                                                                                                               context => UtilityCoroutine.MoveTo(
                                                                                                                   _currentPath.Peek(),
                                                                                                                   "in to drop off Drowned Watchman"))
                                                                                                           ))
                                                           #endregion
                                                           )));
        }
Exemple #2
0
        public Composite CreateMainBehavior()
        {
            // NB: We need to allow lower BT nodes to run when the behavior is finished; otherwise, HB will not
            // process the change of _isBehaviorDone state.
            return(new PrioritySelector(

                       // If quest is done, behavior is done...
                       new Decorator(context => IsDone,
                                     new Action(context =>
            {
                _isBehaviorDone = true;
                QBCLog.Info("Finished");
            })),

                       // If using cannon, start spanking targets...
                       new Decorator(context => Query.IsInVehicle(),
                                     // Ready, Aim, Fire!
                                     new Action(context =>
            {
                // If ejected from vehicle, try to re-locate it...
                if ((CannonVehicle == null) || !CannonVehicle.IsValid)
                {
                    CannonVehicle = FindUnitsFromId(VehicleId_NurongsCannon).FirstOrDefault();
                    return;
                }

                // If target is no longer valid, select another...
                if (!IsViableTarget(CannonVehicle, SelectedTarget))
                {
                    SelectedTarget = ChooseTarget(CannonVehicle, SelectedTarget);
                    if (SelectedTarget == null)
                    {
                        return;
                    }
                    SelectedTarget.Target();
                }

                AimAndFireCannon(CannonVehicle, SelectedTarget);
            })),

                       // If not using cannon, get in cannon vehicle...
                       new Decorator(context => !Query.IsInVehicle(),
                                     new PrioritySelector(cannonContext => FindUnitsFromId(MobId_NurongsCannon).FirstOrDefault(),

                                                          // If unable to locate cannon, warn user and stop...
                                                          new Decorator(cannonContext => cannonContext == null,
                                                                        new PrioritySelector(
                                                                            // The Wait is a defensive bumper against a WoWclient/HBcore race condition...
                                                                            // Sometimes, the toon is ejected from the vehicle before the quest is marked as 'complete'.
                                                                            // We don't want this situation to cause the profile to stop, so we wait for a short while
                                                                            // before declaring a profile problem.
                                                                            new Wait(TimeSpan.FromMilliseconds(5000), cannonContext => IsDone, new ActionAlwaysSucceed()),
                                                                            new Action(cannonContext =>
            {
                QBCLog.Error("PROFILE ERROR: Nurong's Cannon is not in the area--please repair profile");
                TreeRoot.Stop();
                _isBehaviorDone = true;
            })
                                                                            )),

                                                          // Move close enough, and interact with cannon...
                                                          new Decorator(cannonContext => ((WoWUnit)cannonContext).Distance > ((WoWUnit)cannonContext).InteractRange,
                                                                        new Action(cannonContext => { Navigator.MoveTo(((WoWUnit)cannonContext).Location); })),
                                                          new Decorator(cannonContext => !Me.IsFacing((WoWUnit)cannonContext),
                                                                        new Action(cannonContext => { ((WoWUnit)cannonContext).Face(); })),
                                                          new Decorator(cannonContext => Me.IsMoving,
                                                                        new Action(cannonContext => { WoWMovement.MoveStop(); })),
                                                          new Decorator(cannonContext => !Query.IsInVehicle(),
                                                                        new Action(cannonContext =>
            {
                ((WoWUnit)cannonContext).Interact();
                CannonVehicle = null;
            })),
                                                          new Wait(TimeSpan.FromMilliseconds(5000), cannonContext => Query.IsInVehicle(), new ActionAlwaysSucceed())
                                                          ))
                       ));
        }