private Composite TryCast(int spellId, ProvideBoolDelegate requirements = null) { requirements = requirements ?? (context => true); return(new Decorator(context => SpellManager.CanCast(spellId) && requirements(context), new Action(context => { QBCLog.DeveloperInfo("MiniCombatRoutine used {0}", Utility.GetSpellNameFromId(spellId)); SpellManager.Cast(spellId); }))); }
private async Task <bool> MainCoroutine() { var activeMover = WoWMovement.ActiveMover; if (activeMover == null) { return(false); } var immediateDestination = FindImmediateDestination(); // Arrived at destination? if (AtLocation(activeMover.Location, immediateDestination)) { var completionMessage = string.Format("Arrived at destination '{0}'", RoughDestination.Name); // Land if we need to... // NB: The act of landing may cause us to exceed the ArrivalTolerance specified. if (Land && Me.Mounted) { await UtilityCoroutine.LandAndDismount(string.Format("Landing at destination '{0}'", RoughDestination.Name)); BehaviorDone(completionMessage); return(true); } // Done... BehaviorDone(completionMessage); return(false); } // Do not run FlyTo when there is a PoI set... if (BotPoi.Current.Type != PoiType.None) { await Coroutine.Sleep(TimeSpan.FromSeconds(10)); QBCLog.DeveloperInfo("FlyTo temporarily suspended due to {0}", BotPoi.Current); return(true); } // Move closer to destination... var parameters = new FlyToParameters(immediateDestination) { CheckIndoors = !IgnoreIndoors }; if (MinHeight.HasValue) { parameters.MinHeight = MinHeight.Value; } Flightor.MoveTo(parameters); return(true); }
private async Task <bool> AimDirection() { const double normRotation = TRAMP_LEFT_SIDE > TRAMP_RIGHT_SIDE ? 0 : 360; QBCLog.DeveloperInfo("(AimRotation) Trampoline Boundary - Left Edge: {0} Right Edge: {1}", TRAMP_LEFT_SIDE, TRAMP_RIGHT_SIDE); WoWMovement.MovementDirection whichWay; string dirCmd; // left/right - get current direction and turn until on trampoline if (Me.Transport.RotationDegrees < TRAMP_RIGHT_SIDE) { whichWay = WoWMovement.MovementDirection.TurnLeft; dirCmd = "TurnLeft"; } else if ((Me.Transport.RotationDegrees + normRotation) > (TRAMP_LEFT_SIDE + normRotation)) { whichWay = WoWMovement.MovementDirection.TurnRight; dirCmd = "TurnRight"; } else // if (whichWay == WoWMovement.MovementDirection.None) { QBCLog.DeveloperInfo("(AimRotation) Done, Ending Rotation: {0}", Me.Transport.RotationDegrees); return(false); } QBCLog.DeveloperInfo("(AimRotation) Current Rotation: {0} - {1}", Me.Transport.RotationDegrees, whichWay.ToString().ToUpper()); #if WOWMOVEMENT_TIMED_TURNS_STOPFAILING WoWMovement.Move(whichWay, TimeSpan.FromMilliseconds(10)); WoWMovement.MoveStop(whichWay); // loop until we actually move while (0.001 > (currRotation - Me.Transport.RotationDegrees)) { await CommonCoroutines.SleepForLagDuration(); } #elif WOWMOVEMENT_TURNS_STOPFAILING WoWMovement.Move(whichWay); await Coroutine.Sleep(10); WoWMovement.MoveStop(whichWay); // loop until we actually move while (0.001 > (currRotation - Me.Transport.RotationDegrees)) { await CommonCoroutines.SleepForLagDuration(); } #else // doing LUA calls these because WoWMovement API doesn't stop turning quickly enough Lua.DoString(dirCmd + "Start()"); await Coroutine.Sleep(10); Lua.DoString(dirCmd + "Stop()"); #endif return(true); }
private async Task <bool> MainCoroutine() { var activeMover = WoWMovement.ActiveMover; if (activeMover == null) { return(false); } var immediateDestination = FindImmediateDestination(); // If we've no way to reach destination, inform user and quit... if (!Flightor.CanFly && !Navigator.CanNavigateWithin(Me.Location, immediateDestination, (float)DefaultArrivalTolerance)) { QBCLog.Fatal("Toon doesn't have flying capability in this area, and there is no ground path to the destination." + " Please learn the flying skill appropriate for this area."); BehaviorDone(); return(false); } // Arrived at destination? if (AtLocation(activeMover.Location, immediateDestination)) { var completionMessage = string.Format("Arrived at destination '{0}'", RoughDestination.Name); // Land if we need to... // NB: The act of landing may cause us to exceed the ArrivalTolerance specified. if (Land && Me.Mounted) { await UtilityCoroutine.LandAndDismount(string.Format("Landing at destination '{0}'", RoughDestination.Name)); BehaviorDone(completionMessage); return(true); } // Done... BehaviorDone(completionMessage); return(false); } // Do not run FlyTo when there is a PoI set... if (BotPoi.Current.Type != PoiType.None) { await Coroutine.Sleep(TimeSpan.FromSeconds(10)); QBCLog.DeveloperInfo("FlyTo temporarily suspended due to {0}", BotPoi.Current); return(true); } // Move closer to destination... Flightor.MoveTo(immediateDestination, !IgnoreIndoors); return(true); }
/// <summary> /// A Queue for npc's we need to talk to /// </summary> //private WoWUnit CurrentUnit { get { return ObjectManager.GetObjectsOfType<WoWUnit>().FirstOrDefault(unit => unit.Entry == VehicleId); } } protected override Composite CreateBehavior() { return(_root ?? (_root = new PrioritySelector( new Decorator(ret => (QuestId != 0 && Me.QuestLog.GetQuestById((uint)QuestId) != null && Me.QuestLog.GetQuestById((uint)QuestId).IsCompleted), new Action(ret => _isBehaviorDone = true)), // Enable combat while not in a vehicle new Decorator(ctx => (LevelBot.BehaviorFlags & BehaviorFlags.Combat) == 0 && !Query.IsInVehicle(), new Action(ctx => LevelBot.BehaviorFlags |= BehaviorFlags.Combat)), // Disable combat while in a vehicle new Decorator(ctx => (LevelBot.BehaviorFlags & BehaviorFlags.Combat) != 0 && Query.IsInVehicle(), new Action(ctx => LevelBot.BehaviorFlags &= ~BehaviorFlags.Combat)), new Decorator(ret => Counter >= 1, new Action(ret => _isBehaviorDone = true)), new PrioritySelector( new Decorator(ret => IsMounted != true && _vehicleList == null, new ActionRunCoroutine(ctx => MoveToMountLocation()) ), new Decorator(ret => _vehicleList[0] != null && !_vehicleList[0].WithinInteractRange && IsMounted != true, new Action(ret => Navigator.MoveTo(_vehicleList[0].Location)) ), new Decorator(ret => StyxWoW.Me.IsMoving, new ActionRunCoroutine(ctx => CommonCoroutines.StopMoving())), new Decorator(ret => IsMounted != true, new Sequence( new Action(ctx => MountedPoint = Me.Location), new Action(ctx => _vehicleList[0].Interact()), new SleepForLagDuration(), new Action(ctx => IsMounted = true), new Action(ctx => _vehicleList = ObjectManager.GetObjectsOfType <WoWUnit>() .Where(ret => (ret.Entry == VehicleId) && !ret.IsDead).OrderBy(ret => ret.Location.Distance(MountedPoint)).ToList()), new Sleep(3000)) ), new Decorator(ret => IsMounted = true, new ActionRunCoroutine(ctx => MoveToDestination()) ), new Action(ret => QBCLog.DeveloperInfo(string.Empty)) ) ))); }
private Composite CreateBehavior_InGameCheck() { return(_behaviorTreeHook_InGameCheck ?? (_behaviorTreeHook_InGameCheck = new Action( context => { if (!SawLoadingScreen && !StyxWoW.IsInWorld) { QBCLog.DeveloperInfo("Detected a loading screen."); SawLoadingScreen = true; } return RunStatus.Failure; }))); }
private void BotEvents_OnBotStopped(EventArgs args) { QBCLog.DeveloperInfo(CfbContextForHook, "OnBotStop cleanup..."); // Uninstall the behavior from the tree... DoWhenHookRemove(); // Remove our OnNewProfileLoaded handler.... BotEvents.Profile.OnNewProfileLoaded -= BotEvents_OnNewProfileLoaded; s_persistedIsOnNewProfileLoadedHooked = false; // Remove our OnBotStop handler BotEvents.OnBotStopped -= BotEvents_OnBotStopped; s_persistedIsOnBotStopHooked = false; }
private void SetWaypointStrategy(WaypointVisitStrategyType visitStrategyType, bool logChanges) { if ((_visitStrategy == null) || (visitStrategyType != _visitStrategy.VisitStrategyType)) { _visitStrategy = GetVisitStrategyFromType(visitStrategyType); if (_visitStrategy != null && logChanges) { QBCLog.DeveloperInfo("WaypointVisitStrategy set to {0}", _visitStrategy.VisitStrategyType); } // Strategy change requires current waypoint re-evaluation... ResetWaypoints(); } }
private void ActionRemove() { var activityIdentifier = FindActivityIdentifier(); var activity = FindActivity(activityIdentifier); // If activity does not exist, that's a problem... if (activity == null) { QBCLog.Error("DoWhenActivity '{0}' is not in use.", activityIdentifier); return; } // Remove the activity... s_persistedActivities.Remove(activity); QBCLog.DeveloperInfo("DoWhenActivity '{0}' removed.", activity.ActivityIdentifier); }
public override void OnStart() { OnStart_HandleAttributeProblem(); // 1st call will install hook and 2nd call will remove it. if (s_myHook == null) { QBCLog.DeveloperInfo("Installing BarrelHook"); s_myHook = CreateHook(); TreeHooks.Instance.InsertHook("Questbot_Main", 0, s_myHook); } else { QBCLog.DeveloperInfo("Removing BarrelHook"); TreeHooks.Instance.RemoveHook("Questbot_Main", s_myHook); s_myHook = null; } }
public override void OnStart() { // Acquisition and checking of any sub-elements go here. // A common example: // HuntingGrounds = HuntingGroundsType.GetOrCreate(Element, "HuntingGrounds", HuntingGroundCenter); // IsAttributeProblem |= HuntingGrounds.IsAttributeProblem; // Let QuestBehaviorBase do basic initialization of the behavior, deal with bad or deprecated attributes, // capture configuration state, install BT hooks, etc. This will also update the goal text. var isBehaviorShouldRun = OnStart_QuestBehaviorCore(); if (isBehaviorShouldRun) { if (Command == CommandType.Remove) { if (s_avoidDictionary.ContainsKey(AvoidName)) { QBCLog.DeveloperInfo("Removing \"{0}\" avoid", AvoidName); var avoidInfo = s_avoidDictionary[AvoidName]; s_avoidDictionary.Remove(AvoidName); AvoidanceManager.RemoveAvoid(avoidInfo); } } else if (Command == CommandType.Add) { AvoidInfo avoidInfo = BuildAvoidInfo(); QBCLog.DeveloperInfo("Adding \"{0}\" avoid - Radius: {1}, ObjectId: ({2}), ObjectType: {3}", AvoidName, Radius, string.Join(", ", ObjectIds), ObjectType); s_avoidDictionary[AvoidName] = avoidInfo; AvoidanceManager.AddAvoid(avoidInfo); } } if (s_hook == null && s_avoidDictionary.Any()) { InstallHook(); } // remove hook if no avoid definitions are active else if (s_hook != null && !s_avoidDictionary.Any()) { RemoveHook(); } BehaviorDone(); }
private async Task <bool> LootClosestBear() { List <WoWUnit> bears = (from o in ObjectManager.ObjectList where o is WoWUnit let unit = o.ToUnit() where unit.Entry == _mobId_bearTargets && (15 < unit.WorldLocation.Distance(Me.Transport.WorldLocation)) orderby unit.WorldLocation.Distance(Me.Transport.WorldLocation) ascending select unit ).ToList(); foreach (WoWUnit bear in bears) { await CommonCoroutines.SleepForLagDuration(); bear.Target(); // target so we can use LUA func bool bChkLua = Lua.GetReturnVal <bool>("return CheckInteractDistance(\"target\", 1)", 0); bool bChkInt = bear.WithinInteractRange; if (!bChkLua && !bChkInt) { continue; } bear.Interact(); await WaitForCurrentSpell(); await CommonCoroutines.SleepForLagDuration(); if (IsBearCubInBags) { QBCLog.Info("(Loot Bear) grabbed a bear to throw"); return(true); } await Coroutine.Yield(); } QBCLog.DeveloperInfo("(Loot Bear) no bear at level {0}", _lvlCurrent); return(false); }
// CreateBehavior supplied by QuestBehaviorBase. // Instead, provide CreateMainBehavior definition. // Dispose provided by QuestBehaviorBase. // IsDone provided by QuestBehaviorBase. // Call the QuestBehaviorBase.BehaviorDone() method when you want to indicate your behavior is complete. // OnFinished provided by QuestBehaviorBase. public override void OnStart() { // Let QuestBehaviorBase do basic initializaion of the behavior, deal with bad or deprecated attributes, // capture configuration state, install BT hooks, etc. This will also update the goal text. var isBehaviorShouldRun = OnStart_QuestBehaviorCore(); // If the quest is complete, this behavior is already done... // So we don't want to falsely inform the user of things that will be skipped. if (isBehaviorShouldRun) { const float defaultArrivalToleranceMin = 1; // Make certain ArrivalTolerance is coherent with Navigator.PathPrecision... if (DefaultArrivalTolerance < defaultArrivalToleranceMin) { QBCLog.DeveloperInfo("ArrivalTolerance({0:F1}) is less than Minimum({1:F1})." + " Setting ArrivalTolerance to be minimum to prevent navigational issues.", DefaultArrivalTolerance, defaultArrivalToleranceMin); DefaultArrivalTolerance = defaultArrivalToleranceMin; } // Disable any settings that may cause us to dismount -- // When we mount for travel via FlyTo, we don't want to be distracted by other things. // NOTE: the ConfigMemento in QuestBehaviorBase restores these settings to their // normal values when OnFinished() is called. LevelBot.BehaviorFlags &= ~(BehaviorFlags.Loot | BehaviorFlags.Pull); // Clear any existing POI (after we've disabled Pull/Loot behaviors)... // Otherwise, FlyTo can get stuck trying to pursue the previous POI, if one was // set immediately before the behavior was launched. This is a boundary condition, // and it happens frequently enough to be really annoying. BotPoi.Clear(); // Pick our destination proper... PotentialDestinations.WaypointVisitStrategy = HuntingGroundsType.WaypointVisitStrategyType.PickOneAtRandom; RoughDestination = PotentialDestinations.CurrentWaypoint(); var actionDescription = $"Flying to '{RoughDestination.Name}' ({RoughDestination.Location})"; this.UpdateGoalText(GetQuestId(), actionDescription); TreeRoot.StatusText = actionDescription; } }
private void PopulateList() { _enemyUnits = ObjectManager.GetObjectsOfType <WoWUnit>().Where( o => o.CurrentTarget == _defendObject).OrderBy( o => o.Location.Distance(_defendObject.Location)) as List <WoWUnit>; if (_me.Location.Distance(_location) <= 30) { FindObject(); if (_defendObject == null) { _isDone = true; } } Color color = Color.LimeGreen; System.Windows.Media.Color newColor = System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B); QBCLog.DeveloperInfo("DefendObject: PopulateList()!"); }
private void ActionSetEnableState(bool wantEnabled) { var activityIdentifier = FindActivityIdentifier(); var activity = FindActivity(activityIdentifier); // If activity does not exist, that's a problem... if (activity == null) { QBCLog.Error("DoWhenActivity '{0}' is not in use.", activityIdentifier); return; } // Update activity's enabled status... var previousState = activity.UseWhenPredicate.IsEnabled; activity.UseWhenPredicate.IsEnabled = wantEnabled; QBCLog.DeveloperInfo("DoWhenActivity '{0}' {1} (was {2}).", activity.ActivityIdentifier, (wantEnabled ? "enabled" : "disabled"), (previousState ? "enabled" : "disabled")); }
private async Task <bool> EnterPortal() { var portalEntryTimer = new WaitTimer(MaxTimeToPortalEntry); portalEntryTimer.Reset(); QBCLog.DeveloperInfo("Portal Entry Timer Started"); while (true) { if (TookPortal) { return(true); } // If portal entry timer expired, deal with it... if (portalEntryTimer.IsFinished) { QBCLog.Warning( "Unable to enter portal within allotted time of {0}", Utility.PrettyTime(MaxTimeToPortalEntry)); break; } // If we are within 2 yards of calculated end point we should never reach... if (Me.Location.Distance(MovePoint) < 2) { QBCLog.Warning("Seems we missed the portal. Is Portal activated? Profile needs to pick better alignment?"); break; } // If we're not moving toward portal, get busy... if (!StyxWoW.Me.IsMoving || Navigator.AtLocation(StartingPoint)) { QBCLog.DeveloperInfo("Entering portal via {0}", MovePoint); WoWMovement.ClickToMove(MovePoint); } await Coroutine.Yield(); } return(false); }
private Composite SubBehavior_BombTarget(ProvideIntDelegate questObjectiveIndexDelegate, ProvideIntDelegate mobIdDelegate) { Contract.Requires(questObjectiveIndexDelegate != null, context => "questObjectiveIndexDelegate != null"); Contract.Requires(mobIdDelegate != null, context => "mobIdDelegate != null"); return(new Decorator(context => { var questObjectiveIndex = questObjectiveIndexDelegate(context); var mobId = mobIdDelegate(context); if (Me.IsQuestObjectiveComplete(GetQuestId(), questObjectiveIndex)) { return false; } SelectedTarget = (from wowObject in Query.FindMobsAndFactions(Utility.ToEnumerable((int)mobId)) let wowUnit = wowObject as WoWUnit where Query.IsViable(wowUnit) && wowUnit.IsAlive orderby wowUnit.DistanceSqr select wowUnit) .FirstOrDefault(); if (!Query.IsViable(SelectedTarget)) { return false; } return Me.Location.Distance(SelectedTarget.Location) <= _bombRange; }, new Action(context => { QBCLog.DeveloperInfo("Bombing {0}", SelectedTarget.SafeName); Bomb.Use(); SpellManager.ClickRemoteLocation(SelectedTarget.Location); }))); }
public override void OnStart() { _autoEquipOldValue = CharacterSettings.Instance.AutoEquip; CharacterSettings.Instance.AutoEquip = false; // Don't try to loot normally. LevelBot.BehaviorFlags = LevelBot.BehaviorFlags & ~_behaviorflagsToDisable; PlayerQuest quest = GetQuestInLog(); if (quest == null) { this.UpdateGoalText(GetQuestId(), "Fishing Item [" + CollectItemId + "]"); } else { this.UpdateGoalText((int)quest.Id, "Fishing Item for [" + quest.Name + "]"); } QBCLog.DeveloperInfo("Fishing Item (for QuestId {0}): {1}({2}) x{3}", quest?.Id ?? (uint)GetQuestId(), Utility.GetItemNameFromId(CollectItemId), CollectItemId, CollectItemCount.Value); _fishingLogic.Start(_fishingProfile); }
private void RemoveHook() { if (s_hook == null) { return; } TreeHooks.Instance.RemoveHook("Combat_Main", s_hook); Navigator.NavigationProvider = s_prevNavigator; s_prevNavigator = null; s_hook = null; foreach (var kv in s_avoidDictionary) { AvoidanceManager.RemoveAvoid(kv.Value); QBCLog.DeveloperInfo("Removed the \"{0}\" avoidance definition", kv.Key); } s_avoidDictionary.Clear(); BotEvents.OnPulse -= BotEvents_OnPulse; BotEvents.OnBotStopped -= BotEvents_OnBotStopped; BotEvents.Profile.OnNewOuterProfileLoaded -= Profile_OnNewOuterProfileLoaded; LootTargeting.Instance.RemoveTargetsFilter -= Instance_RemoveTargetsFilter; QBCLog.Info("Uninstalled avoidance system"); }
public override void OnStart() { // Let QuestBehaviorBase do basic initializaion of the behavior, deal with bad or deprecated attributes, // capture configuration state, install BT hooks, etc. This will also update the goal text. var isBehaviorShouldRun = OnStart_QuestBehaviorCore(); // If the quest is complete, this behavior is already done... // So we don't want to falsely inform the user of things that will be skipped. if (isBehaviorShouldRun) { HbProcId = System.Diagnostics.Process.GetCurrentProcess().Id; _pipeFactory = new ChannelFactory <IRemotingApi>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/HBRelog/Server")); try { HBRelogRemoteApi = _pipeFactory.CreateChannel(); IsConnected = HBRelogRemoteApi.Init(HbProcId); if (IsConnected) { QBCLog.DeveloperInfo("Connected to HBRelog Server"); CurrentProfileName = HBRelogRemoteApi.GetCurrentProfileName(HbProcId); QBCLog.DeveloperInfo(string.Format("HBRelog Current Profile: {0}", CurrentProfileName)); } else { QBCLog.Error("Could Not Connect to HBRelog Server at net.pipe://localhost/HBRelog/Server"); } } catch (Exception ex) { QBCLog.Error( "Could not make endpoint connection to HBRelog Application. You may not be running under HBRelog. Ignoring"); CurrentProfileName = string.Empty; } } }
private void ActionUpdate(IUseWhenPredicate useWhenPredicate, bool isMovementStopRequired) { var activityIdentifier = FindActivityIdentifier(); var existingActivity = FindActivity(activityIdentifier); // If activity already exists, remove it... if (existingActivity != null) { s_persistedActivities.Remove(existingActivity); } // Install new activity... IDoWhenActivity doWhenActivity = null; if (ActivityKey_ItemId > 0) { doWhenActivity = new DoWhenUseItemActivity(ActivityKey_ItemId, useWhenPredicate, isMovementStopRequired); } else if (ActivityKey_SpellId > 0) { doWhenActivity = new DoWhenCastSpellActivity(ActivityKey_SpellId, useWhenPredicate, isMovementStopRequired); } else if (!string.IsNullOrEmpty(ActivityKey_Name)) { doWhenActivity = new DoWhenNamedActivity(ActivityKey_Name, useWhenPredicate, Nodes, isMovementStopRequired); } if (doWhenActivity != null) { s_persistedActivities.Add(doWhenActivity); QBCLog.DeveloperInfo("DoWhenActivity '{0}' created:{1}", doWhenActivity.ActivityIdentifier, doWhenActivity.BuildDebugInfo(" ")); } }
public override void OnTick() { if (_enemyListTimer.IsFinished) { if (_defendObject != null) { PopulateList(); } else { try { FindObject(); QBCLog.DeveloperInfo("DefendObject: Attempting to find Defendant..."); } catch (Exception except) { QBCLog.Exception(except); IsAttributeProblem = true; } } } _enemyListTimer.Reset(); }
protected bool MoveToNextGoal(HuntingGroundsType ridingPath) { if (!IsMountedOnRam()) { return(false); } var activeMover = WoWMovement.ActiveMover; var currentWaypoint = ridingPath.CurrentWaypoint(); var moveResult = Navigator.MoveTo(currentWaypoint.Location); if (Navigator.GetRunStatusFromMoveResult(moveResult) == RunStatus.Success) { return(true); } QBCLog.DeveloperInfo( "Navigator unable to move from {0} to destination({1}, {2}) on ground.", activeMover.Location, currentWaypoint.Name, currentWaypoint.Location.ToString()); return(false); }
protected override Composite CreateBehavior_CombatMain() { return(new PrioritySelector( new Decorator(context => !IsDone && !Me.IsActuallyInCombat, new PrioritySelector( // Update Location if relative coord is used... // N.B. Relative locations are only used while on transports and because // transports are usually moving around 'Location' needs to be updated on every frame. new Decorator(context => UseRelativeLocation, new Action(context => Destination = CalculateRelativeLocation(OrigDestination))), // Initialize the timer... new Decorator(context => _runTimer == null, new Action(context => { _runTimer = new WaitTimer(Destination.MaximumTraversalTime(2.5, TimeSpan.FromSeconds(20), UpperLimitOnMovementTime)); QBCLog.DeveloperInfo("Maximum allowed time to reach destination: {0} seconds", _runTimer.WaitTime.TotalSeconds); _runTimer.Reset(); return RunStatus.Failure; })), // Stop HB if _runTimer finishes... new Decorator(context => _runTimer.IsFinished, new Action(context => { WoWMovement.MoveStop(); // N.B. set the runtimer to null so if player manually correct // problem and starts bot up it restarts the timer. _runTimer = null; QBCLog.Fatal("MyCTM is not able to reach {0} from {1}", DestinationName, WoWMovement.ActiveMover.Location); })), // Run stuckhandler CreateBehavior_Antistuck(), // Default anti-stuck has issues. // new Decorator(context => Navigator.NavigationProvider.StuckHandler.IsStuck(), // new Action(context => Navigator.NavigationProvider.StuckHandler.Unstick())), // check if bot has reached the destination. new Decorator(context => Destination.DistanceSqr(Me.Location) <= (3 * 3), new Action(context => { BehaviorDone(string.Format("Finished moving to {0}", DestinationName)); // Drop down to 'CreateBehavior_PerformCTM' to ensure ctm is performed // at least once if start and destination locations are very close on start return RunStatus.Failure; })), CreateBehavior_PerformCTM() )), // _runTimer needs to be recalculated after combat is over and stuck timer needs to rest. new Decorator(context => Me.IsActuallyInCombat, new Action(context => { _runTimer = null; _stuckTimer.Reset(); return RunStatus.Failure; })) )); }
private void BotEvents_OnNewProfileLoaded(EventArgs args) { QBCLog.DeveloperInfo(CfbContextForHook, "OnNewProfileLoaded cleanup..."); // Uninstall the behavior from the tree... DoWhenHookRemove(); }
public override void OnStart() { // Let QuestBehaviorBase do basic initialization of the behavior, deal with bad or deprecated attributes, // capture configuration state, install BT hooks, etc. This will also update the goal text. var isBehaviorShouldRun = OnStart_QuestBehaviorCore(); // If the quest is complete, this behavior is already done... // So we don't want to falsely inform the user of things that will be skipped. if (isBehaviorShouldRun) { var logInfo = new StringBuilder(); var logDeveloperInfo = new StringBuilder(); // The BotStop handler will put the original configuration settings back in place... // Note, we only want to hook it once for this behavior. if (!s_persistedIsBotStopHooked) { BotEvents.OnBotStopped += BotEvents_OnBotStopped; s_persistedIsBotStopHooked = true; } // First, process Preset request, if any... if (!string.IsNullOrEmpty(PresetName)) { var presetChangeSet = (from preset in _presetChangeSets where preset.Key == PresetName select preset.Value) .FirstOrDefault(); if (presetChangeSet == null) { QBCLog.Error("Unable to locate any preset named '{0}'", PresetName); TreeRoot.Stop(); BehaviorDone(); return; } var appliedChanges = presetChangeSet.Apply(" "); var appliedChangesBuilder = s_persistedDebugShowChangesApplied ? logInfo : logDeveloperInfo; appliedChangesBuilder.AppendFormat("Using preset '{0}'...{1}", PresetName, appliedChanges); appliedChangesBuilder.Append(Environment.NewLine); } // Second, apply any change requests... if (_userChangeRequest.Count > 0) { string appliedChanges = _userChangeRequest.Apply(" "); var appliedChangesBuilder = s_persistedDebugShowChangesApplied ? logInfo : logDeveloperInfo; appliedChangesBuilder.AppendFormat("Applied changes...{0}", appliedChanges); appliedChangesBuilder.Append(Environment.NewLine); } // Third, show state, if requested... if (DebugShowDetails) { var currentConfiguration = ChangeSet.FromCurrentConfiguration(); logInfo.AppendFormat("Details...{0}", currentConfiguration.BuildDetails(" ")); logInfo.Append(Environment.NewLine); } var diffBuilder = DebugShowDiff ? logInfo : logDeveloperInfo; diffBuilder.AppendFormat("Difference from user's original settings...{0}", ChangeSet.BuildDifferencesFromOriginalSettings(" ")); diffBuilder.Append(Environment.NewLine); // Forth, stop the bot, if requested... if (IsStopBot) { const string message = "Stopping the bot per profile request."; logInfo.AppendFormat(message); logInfo.Append(Environment.NewLine); var logInfoString = logInfo.ToString(); if (!string.IsNullOrEmpty(logInfoString)) { QBCLog.Info(logInfoString); } var logDeveloperString = logDeveloperInfo.ToString(); if (!string.IsNullOrEmpty(logDeveloperString)) { QBCLog.DeveloperInfo(logDeveloperString); } TreeRoot.Stop(message); BehaviorDone(); return; } else { var logInfoString = logInfo.ToString(); if (!string.IsNullOrEmpty(logInfoString)) { QBCLog.Info(logInfoString); } var logDeveloperString = logDeveloperInfo.ToString(); if (!string.IsNullOrEmpty(logDeveloperString)) { QBCLog.DeveloperInfo(logDeveloperString); } } BehaviorDone(); } }
public void DLog(string format, params object[] args) { // following linecount hack is to stop dup suppression of Log window QBCLog.DeveloperInfo(format + (++s_lineCount % 2 == 0 ? "" : " "), args); }
public override async Task <bool> Execute() { // If we cannot 'see' the mob yet, move to the rough location... var gossipMob = ObjectManager.GetObjectsOfType <WoWUnit>().FirstOrDefault(u => u.Entry == GossipMobId); if (gossipMob == null) { await UtilityCoroutine.MoveTo(GossipMobRoughLocation, "Gossip mob"); return(true); } // Move into interact range of mob... if (Me.Location.Distance(gossipMob.Location) > gossipMob.InteractRange) { if (await UtilityCoroutine.MoveTo(gossipMob.Location, gossipMob.Name)) { return(true); } } WoWMovement.MoveStop(); // Pull up gossip frame, if not visible if (!IsGossipFrameVisible()) { await UtilityCoroutine.Interact(gossipMob); await Coroutine.Sleep(Delay.AfterInteraction); return(true); } TreeRoot.StatusText = string.Format("Gossiping with {0}", gossipMob.Name); var gossipPageIndex = 0; while (gossipPageIndex < GossipOptions.Length) { GossipEntry gossipEntry; if (!TryGetGossipEntry(GossipOptions[gossipPageIndex], out gossipEntry)) { QBCLog.Fatal( "{0} is not offering gossip option {1} on page {2}." + " Did competing player alter NPC state?" + " Did you stop/start Honorbuddy?" + " Terminating behavior.", gossipMob.Name, GossipOptions[gossipPageIndex] + 1, gossipPageIndex + 1); Utility.CloseAllNpcFrames(); Me.ClearTarget(); return(false); } // Log the gossip option we're about to take... QBCLog.DeveloperInfo( "Selecting Gossip Option({0}) on page {1}: \"{2}\"", gossipEntry.Index + 1, gossipPageIndex + 1, gossipEntry.Text); GossipFrame.Instance.SelectGossipOption(GossipOptions[gossipPageIndex]); ++gossipPageIndex; await Coroutine.Wait((int)Delay.AfterInteraction.TotalMilliseconds, () => !IsGossipFrameVisible()); } // Gossip is complete, claim credit... Utility.CloseAllNpcFrames(); var message = string.Format("Gossip with {0} complete.", gossipMob.Name); QBCLog.DeveloperInfo(message); TreeRoot.StatusText = message; return(true); }