private void SelectSetLocationGossipOption() { foreach (GossipEntry entry in GossipFrame.Instance.GossipOptionEntries) { if (entry.Type == GossipEntry.GossipEntryType.Binder) { QBCLog.Info("Selecting gossip option: " + entry.Text + " - #" + entry.Index); GossipFrame.Instance.SelectGossipOption(entry.Index); } } }
public override void OnStart() { // This reports problems, and stops BT processing if there was a problem with attributes... // We had to defer this action, as the 'profile line number' is not available during the element's // constructor call. OnStart_HandleAttributeProblem(); if (!IsDone) { if (Timer == "Start") { WaitTime = 0; Lua.DoString("StartInstanceTimerMin = date(\"%M\")"); Lua.DoString("StartInstanceTimerSec = date(\"%S\")"); QBCLog.Info("Started."); } if (Timer == "Check") { var startInstanceVar1 = Lua.GetReturnVal <int>("return StartInstanceTimerMin", 0); var startInstanceVar2 = Lua.GetReturnVal <int>("return StartInstanceTimerSec", 0); Lua.DoString("EndInstanceTimerMin = date(\"%M\")"); Lua.DoString("EndInstanceTimerSec = date(\"%S\")"); var endInstanceVar1 = Lua.GetReturnVal <int>("return EndInstanceTimerMin", 0); var endInstanceVar2 = Lua.GetReturnVal <int>("return EndInstanceTimerSec", 0); if (endInstanceVar1 < startInstanceVar1) { endInstanceVar1 = endInstanceVar1 + 60; } if (endInstanceVar2 < startInstanceVar2) { endInstanceVar2 = endInstanceVar2 + 60; endInstanceVar1 = endInstanceVar1 - 1; } var calcInstanceVar = ((((endInstanceVar1 - startInstanceVar1) * 60) + (endInstanceVar2 - startInstanceVar2)) * 1000); _timeInInstance = new Common.Helpers.WaitTimer(new TimeSpan(0, 0, 0, 0, calcInstanceVar)); var timeInInstanceAsString = UtilBuildTimeAsString(_timeInInstance.WaitTime); QBCLog.Info("Your instance run took " + timeInInstanceAsString); if (calcInstanceVar >= WaitTime) { WaitTime = 0; } if (calcInstanceVar < WaitTime) { WaitTime = WaitTime - calcInstanceVar; _timeInInstance = new Common.Helpers.WaitTimer(new TimeSpan(0, 0, 0, 0, WaitTime)); timeInInstanceAsString = UtilBuildTimeAsString(_timeInInstance.WaitTime); QBCLog.Info("Waiting for " + timeInInstanceAsString); } } _timer = new Common.Helpers.WaitTimer(new TimeSpan(0, 0, 0, 0, WaitTime)); _waitTimeAsString = UtilBuildTimeAsString(_timer.WaitTime); _timer.Reset(); } }
public void UsePetSkill(string action) { var spell = StyxWoW.Me.PetSpells.FirstOrDefault(p => p.ToString() == action); if (spell == null) { return; } QBCLog.Info("[Pet] Casting {0}", action); Lua.DoString("CastPetAction({0})", spell.ActionBarIndex + 1); }
private Composite CreateBehavior_CombatOnly() { return(new PrioritySelector( // If we're in combat while in the vehicle, then exit the vehicle and eliminate the problem... new Decorator(context => Query.IsInVehicle(), new Action(context => { QBCLog.Info("Exiting vehicle to take care of hostile mob"); Lua.DoString("VehicleExit()"); })) )); }
private async Task <bool> UtilityCoroutine_MoveAndUseCatapult() { if (!Query.IsInVehicle() || !IsViable(SelectedCatapult)) { return(false); } // Move vehicle into position... if (!Navigator.AtLocation(CurrentTask.PositionForLaunch)) { Navigator.MoveTo(CurrentTask.PositionForLaunch); return(true); } // Adjust heading... if (!WoWMathHelper.IsFacing(WoWMovement.ActiveMover.Location, GetVehicleFacing(), CurrentTask.PositionToLand, WoWMathHelper.DegreesToRadians(0.5f))) { // Handle heading... double neededHeading = WoWMathHelper.CalculateNeededFacing(Me.Location, CurrentTask.PositionToLand); neededHeading = WoWMathHelper.NormalizeRadian((float)neededHeading); QBCLog.Info("Adjusting firing heading"); Me.SetFacing((float)neededHeading); await Coroutine.Sleep(200); return(true); } // Adjust azimuth... double currentAzimuth = WoWMathHelper.NormalizeRadian(Lua.GetReturnVal <float>("return VehicleAimGetAngle();", 0)); double neededAzimuth = NormalizeAngleToPi(CurrentTask.NeededAzimuth); double azimuthChangeRequired = neededAzimuth - currentAzimuth; if (Math.Abs(azimuthChangeRequired) >= 0.01) { QBCLog.Info("Adjusting firing azimuth"); // NB: VehicleAimIncrement() handles negative values of 'increment' correctly... Lua.DoString("VehicleAimIncrement({0})", azimuthChangeRequired); await Coroutine.Sleep(200); return(true); } // Fire.. QBCLog.Info("Firing Catapult"); Lua.DoString(Lua_LaunchCommand); await Coroutine.Wait(3000, () => !Query.IsInVehicle()); return(true); }
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"); })) )); }
private async Task <bool> HandleQuestCompletion() { if (!Me.IsQuestComplete(QuestId)) { return(false); } // Exit vehicle after quest is completed QBCLog.Info("Finished!"); Lua.DoString("VehicleExit()"); await CommonCoroutines.SleepForRandomUiInteractionTime(); _isBehaviorDone = true; return(true); }
private void InstallHook() { s_prevNavigator = Navigator.NavigationProvider; var avoidNavigator = new AvoidanceNavigationProvider();; Navigator.NavigationProvider = avoidNavigator; avoidNavigator.UpdateMaps(); s_hook = new ActionRunCoroutine(ctx => HookHelpers.ExecuteHook(this, HookHandler)); TreeHooks.Instance.InsertHook("Combat_Main", 0, s_hook); BotEvents.OnPulse += BotEvents_OnPulse; BotEvents.OnBotStopped += BotEvents_OnBotStopped; BotEvents.Profile.OnNewOuterProfileLoaded += Profile_OnNewOuterProfileLoaded; LootTargeting.Instance.RemoveTargetsFilter += Instance_RemoveTargetsFilter; QBCLog.Info("Installed avoidance system"); }
private bool RemoveHook() { if (_myHook == null) { return(false); } QBCLog.Info("Removing hook"); TreeHooks.Instance.RemoveHook("Questbot_Profile", _myHook); BotEvents.OnBotStopped -= BotEvents_OnBotStopped; BotEvents.Profile.OnNewProfileLoaded -= Profile_OnNewProfileLoaded; _myHook = null; return(true); }
private async Task <bool> MainCoroutine() { if (!string.IsNullOrEmpty(CurrentProfileName)) { QBCLog.Info("Skipping Current HBRelogTask... Bye Bye Now"); HBRelogRemoteApi.SkipCurrentTask(CurrentProfileName); BehaviorDone(); return(true); } else { QBCLog.Error("Could not connect to HBRelog Server or Invalid Profile. Could not Skip Task"); BehaviorDone(); return(true); } }
/// <summary> /// This behavior quits attacking the mob, once the mob is targeting us. /// </summary> private Composite UtilityBehavior_GetMobsAttention(WoWUnitDelegate selectedTargetDelegate) { return(new PrioritySelector(targetContext => selectedTargetDelegate(targetContext), new Decorator(targetContext => IsViable((WoWUnit)targetContext), new PrioritySelector( new Decorator(targetContext => !((((WoWUnit)targetContext).CurrentTarget == Me) || (Me.GotAlivePet && ((WoWUnit)targetContext).CurrentTarget == Me.Pet)), new PrioritySelector( new Action(targetContext => { QBCLog.Info("Getting attention of {0}", ((WoWUnit)targetContext).SafeName); return RunStatus.Failure; }), UtilityBehavior_SpankMob(selectedTargetDelegate))) )))); }
private void UsePetAbility(string action) { var spell = StyxWoW.Me.PetSpells.FirstOrDefault(p => p.ToString() == action); if (spell == null) { return; } QBCLog.Info("[Pet] Casting {0}", action); Lua.DoString("CastPetAction({0})", spell.ActionBarIndex + 1); if (action == "Move") { SpellManager.ClickRemoteLocation(Enemies[0].Location); } }
private bool CheckPartyRange() { foreach (var p in StyxWoW.Me.GroupInfo.RaidMembers.Select(a => a.ToPlayer())) { if (p == null) { QBCLog.Info("Can't scan party member, assuming member is too far away"); return(false); } if (p.Guid != Me.Guid && WoWMovement.CalculatePointFrom(p.Location, 0).DistanceSqr(Me.Location) > p.InteractRange) { return(false); } } return(true); }
private async Task <bool> MainCoroutine() { if (IsDone) { return(false); } if (Me.IsQuestComplete(GetQuestId()) || !Query.IsInVehicle()) { QBCLog.Info("Finished!"); CharacterSettings.Instance.UseGroundMount = true; BehaviorDone(); return(true); } // We're always returning 'true' return(await PhaseOneLogic() || await PhaseTwoLogic()); }
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); }
public override void OnStart() { // This reports problems, and stops BT processing if there was a problem with attributes... // We had to defer this action, as the 'profile line number' is not available during the element's // constructor call. OnStart_HandleAttributeProblem(); // 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 (!IsDone) { PlayerQuest quest = StyxWoW.Me.QuestLog.GetQuestById((uint)QuestId); if (quest == null) { QBCLog.Warning("Cannot find quest with QuestId({0}).", QuestId); _isBehaviorDone = true; } else if (quest.IsCompleted && (Type != AbandonType.All)) { QBCLog.Warning("Quest({0}, \"{1}\") is Complete--skipping abandon.", QuestId, quest.Name); _isBehaviorDone = true; } else if (!quest.IsFailed && (Type == AbandonType.Failed)) { QBCLog.Warning("Quest({0}, \"{1}\") has not Failed--skipping abandon.", QuestId, quest.Name); _isBehaviorDone = true; } else { TreeRoot.GoalText = string.Format("Abandoning QuestId({0}): \"{1}\"", QuestId, quest.Name); StyxWoW.Me.QuestLog.AbandonQuestById((uint)QuestId); QBCLog.Info("Quest({0}, \"{1}\") successfully abandoned", QuestId, quest.Name); _waitTimerAfterAbandon.WaitTime = TimeSpan.FromMilliseconds(WaitTime); _waitTimerAfterAbandon.Reset(); } } }
private void ActionShowActivities() { var builder = new StringBuilder(); if (s_persistedActivities.Count <= 0) { builder.AppendFormat("No DoWhenActivities in use."); } else { builder.AppendFormat("DoWhenActivities in use (count:{0}):", s_persistedActivities.Count); foreach (var activity in s_persistedActivities.OrderBy(e => e.ActivityIdentifier)) { builder.Append(activity.BuildDebugInfo(" ")); } } QBCLog.Info(builder.ToString()); }
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() { OnStart_HandleAttributeProblem(); if (_state == true) { if (s_myHook == null) { QBCLog.Info("Inserting hook"); s_myHook = CreateHook(); TreeHooks.Instance.InsertHook("Questbot_Main", 0, s_myHook); } else { QBCLog.Info("Insert was requested, but was already present"); } _inserted = true; } else { if (s_myHook != null) { QBCLog.Info("Removing hook"); TreeHooks.Instance.RemoveHook("Questbot_Main", s_myHook); s_myHook = null; } else { QBCLog.Info("Remove was requested, but hook was not present"); } _inserted = false; } }
protected override Composite CreateBehavior() { return(_root ?? (_root = new PrioritySelector( // check if we have finished 10 questions (marked complete) new Decorator(ret => Me.IsQuestComplete(QuestId), new PrioritySelector( new Decorator(ret => Me.HasAura("Mental Training"), new Sequence( new Action(ret => QBCLog.Info("Mental Training complete - exiting Orb")), new Action(ret => Lua.DoString("RunMacroText(\"/click OverrideActionBarButton4\")")), CreateWaitForLagDuration() ) ), new Action(ret => _isBehaviorDone = true) ) ), // if we don't have vehicle buff, use Orb of Ascension new Decorator(ret => !Me.HasAura("Mental Training"), new Sequence( new Action(delegate { QBCLog.Info("Using Orb of Ascension"); WoWItem orb = ObjectManager.GetObjectsOfType <WoWItem>().Where(u => u.Entry == 52828).FirstOrDefault(); if (orb == null) { QBCLog.Fatal("Quest item \"Orb of Ascension\" not in inventory."); } orb.Use(true); return RunStatus.Success; }), new WaitContinue(1, ret => Me.HasAura("Mental Training"), new ActionAlwaysSucceed()) ) ), // if we have YES aura 74008, then click yes new Decorator(ret => HasAura(Me, 74008), new Sequence( new Action(ret => QBCLog.Info("Answering YES")), new WaitContinue(TimeSpan.FromMilliseconds(500), ret => false, new ActionAlwaysSucceed()), new Action(ret => Lua.DoString("RunMacroText(\"/click OverrideActionBarButton1\")")), new WaitContinue(1, ret => !HasAura(Me, 74008), new ActionAlwaysSucceed()) ) ), // if we have NO aura 74009, then click no new Decorator(ret => HasAura(Me, 74009), new Sequence( new Action(ret => QBCLog.Info("Answering NO")), new WaitContinue(TimeSpan.FromMilliseconds(500), ret => false, new ActionAlwaysSucceed()), new Action(ret => Lua.DoString("RunMacroText(\"/click OverrideActionBarButton2\")")), new WaitContinue(1, ret => !HasAura(Me, 74009), new ActionAlwaysSucceed()) ) ), new Action(delegate { return RunStatus.Success; }) ) )); }
protected override Composite CreateBehavior() { return(_Root ?? (_Root = new PrioritySelector(context => !s_isBehaviorDone, #region MyHotSpot // Store our current location. new Decorator(context => MyHotSpot == WoWPoint.Empty, new Sequence( new DecoratorContinue(context => Me.IsMoving, new WaitContinue(TimeSpan.FromMilliseconds(2000), context => false, new ActionAlwaysSucceed()) ), new DecoratorContinue(context => !Me.IsMoving, new Action(context => MyHotSpot = Me.Location) ) ) ), #endregion #region MinLevel // Should we check for partymember minumum level ? new Decorator(context => (MinLevel > 0), new Sequence( // Someone is below MinLevel. new DecoratorContinue(context => !CheckLevel(), new Sequence( new Action(context => QBCLog.Info("Someone in your party is below level {0}.", MinLevel)), new Action(context => s_isBehaviorDone = true) ) ), // Everyone is equal or above MinLevel. new DecoratorContinue(context => CheckLevel(), new Action(context => MinLevel = 0) ) ) ), #endregion #region CheckRange // Should we wait for party members to be in range ? new Decorator(context => (CheckRange != 0), new Sequence( // Everyone isn't within interact range, lets wait abit before checking again. new DecoratorContinue(context => !CheckPartyRange(), new Sequence( new DecoratorContinue(context => !Navigator.AtLocation(MyHotSpot), new Sequence( new DecoratorContinue(context => Navigator.CanNavigateFully(Me.Location, MyHotSpot), new Action(context => Navigator.MoveTo(MyHotSpot)) ), new DecoratorContinue(context => !Navigator.CanNavigateFully(Me.Location, MyHotSpot), new Action(context => Flightor.MoveTo(MyHotSpot)) ) ) ), new WaitContinue(TimeSpan.FromMilliseconds(300), context => false, new ActionAlwaysSucceed()) ) ), // Everyone is within interact range. new DecoratorContinue(context => CheckPartyRange(), new Sequence( new Action(context => QBCLog.Info("Everyone is within range.")), new Action(context => CheckRange = 0) ) ) ) ), #endregion #region ChkExp // Disabled until I can find out a safer way to to it. /* * new Decorator(context => (ChkExp != 0), * new Sequence( * new DecoratorContinue(context => !AreWeDone(), * new Action(context => CheckExpansions()) * ), * new DecoratorContinue(context => AreWeDone(), * new Sequence( * new DecoratorContinue(context => !DoAllHaveExp(), * new Sequence( * new Action(context => QBCLog.Info("Everyone in your group doesn't have ExpansionLevel '{0}'", ChkExp)), * new Action(context => _isBehaviorDone = true) * ) * ), * new DecoratorContinue(context => DoAllHaveExp(), * new Sequence( * new Action(context => QBCLog.Info("Everyone has atleast ExpansionLevel '{0}'", ChkExp)), * new Action(context => ChkExp = 0) * ) * ) * ) * ) * ) * ), */ #endregion #region RemotePath // Load the remote profile... new Decorator(context => RemotePath != "", new Sequence( // You have included a RemotePath but not a ProfileName. new DecoratorContinue(context => ProfileName == "", new Sequence( new Action(context => QBCLog.Error("You need to include a ProfileName.")), new Action(context => s_isBehaviorDone = true) ) ), // Remote Profile doesn't exist. new DecoratorContinue(context => (ProfileName != "" && !UrlExists(NewRemoteProfilePath)), new Sequence( new Action(context => QBCLog.Error("Profile '{0}' does not exist.", ProfileName)), new Action(context => s_isBehaviorDone = true) ) ), // Everything is ok, Load the remote Profile new DecoratorContinue(context => (ProfileName != "" && UrlExists(NewRemoteProfilePath)), new Sequence( new Action(context => TreeRoot.StatusText = "Loading profile '" + ProfileName + "'"), new Action(context => QBCLog.Info("Loading profile '{0}'", ProfileName)), new Action(context => ProfileManager.LoadNew(new MemoryStream(new WebClient().DownloadData(NewRemoteProfilePath)))), new WaitContinue(TimeSpan.FromMilliseconds(300), context => false, new ActionAlwaysSucceed()), new Action(context => s_isBehaviorDone = true) ) ) ) ), #endregion #region ProfileName // Load the local profile... new Decorator(context => (ProfileName != "" && RemotePath == ""), new PrioritySelector( // Local Profile doesn't exist. new Decorator(context => !IsStoreProfile && !File.Exists(NewLocalProfilePath), new Sequence( new Action(context => QBCLog.Error("Profile '{0}' does not exist.", ProfileName)), new Action(context => s_isBehaviorDone = true) ) ), // Everything is ok, Load the local Profile. new Sequence( new Action(context => TreeRoot.StatusText = "Loading profile '" + ProfileName + "'"), new Action(context => QBCLog.Error("Loading profile '{0}'", ProfileName)), new Action(context => ProfileManager.LoadNew(NewLocalProfilePath, false)), new WaitContinue(TimeSpan.FromMilliseconds(300), context => false, new ActionAlwaysSucceed()), new Action(context => s_isBehaviorDone = true) ) ) ), #endregion #region Behavior Done // Everyone is within interact range and we shouldn't load a profile, then end the Quest Behavior. new Decorator(context => !s_isBehaviorDone, new Action(context => s_isBehaviorDone = true) ) #endregion ) )); }
private async Task TargetLogic(WoWUnit target) { if (!Query.IsViable(target)) { return; } var targetDistSqr = target.Location.DistanceSquared(Vehicle.Location); if (PickUpPassengerButton == 0) { TreeRoot.StatusText = string.Format("Blowing stuff up. {0} mins before resummon is required", _flightTimer.TimeLeft.TotalMinutes); if (HealButton > 0 && targetDistSqr < 60 * 60 && (Vehicle.HealthPercent <= HealPercent || Vehicle.ManaPercent <= HealPercent) && UseVehicleButton(HealButton)) { QBCLog.Info("Used heal button {0} on NPC:{1}", HealButton, target.SafeName); return; } // return when a button is used. foreach (var button in Buttons) { if (UseVehicleButton(button)) { return; } } return; } TreeRoot.StatusText = string.Format("Rescuing {0}", target.SafeName); var pickTimer = new WaitTimer(TimeSpan.FromSeconds(20)); pickTimer.Reset(); while (target.IsValid && target.IsAlive && !UnitIsRidingMyVehicle(target) && Query.IsInVehicle() && !pickTimer.IsFinished) { Vector3 clickLocation = target.Location.RayCast(target.Rotation, 6); clickLocation.Z += 3; if (Vehicle.Location.DistanceSquared(clickLocation) > 3 * 3) { Stopwatch timer = Stopwatch.StartNew(); do { Flightor.MoveTo(clickLocation); await Coroutine.Yield(); } while (timer.ElapsedMilliseconds < 1000 && Vehicle.Location.DistanceSquared(clickLocation) > 3 * 3); } else { if (Vehicle.IsMoving) { await CommonCoroutines.StopMoving(string.Format("Picking up {0}", target.SafeName)); } UseVehicleButton(PickUpPassengerButton); if (await Coroutine.Wait(4000, () => UnitIsRidingMyVehicle(target))) { QBCLog.Info("Successfully picked up passenger {0}", target.SafeName); return; } QBCLog.Info("Failed to picked up passenger {0}", target.SafeName); await Coroutine.Yield(); } } }
private async Task <bool> MoveToEnd(bool exitVehicle, WoWUnit passenger = null) { if (!Query.IsInVehicle()) { return(false); } if (Vehicle.Location.DistanceSquared(EndLocation) >= PrecisionSqr) { await UseSpeedBuff(); Flightor.MoveTo(EndLocation); return(true); } if (exitVehicle) { Lua.DoString("VehicleExit()"); await Coroutine.Sleep(2000); await Coroutine.Wait(20000, () => !Me.IsFalling); if (Me.Combat) { QBCLog.Info("Getting in vehicle to drop combat"); return(await GetInVehicleLogic()); } return(true); } if (!Query.IsViable(passenger)) { return(false); } if (Vehicle.IsMoving) { await CommonCoroutines.StopMoving("Dropping off passenger."); await CommonCoroutines.SleepForLagDuration(); } await Coroutine.Sleep(StyxWoW.Random.Next(5000, 6000)); UseVehicleButton(DropPassengerButton); await CommonCoroutines.SleepForLagDuration(); if (!await Coroutine.Wait(10000, () => !Query.IsViable(passenger) || !UnitIsRidingMyVehicle(passenger))) { QBCLog.Warning("Failed to drop passenger off"); return(false); } if (Query.IsViable(passenger)) { Blacklist.Add(passenger, BlacklistFlags.Interact, TimeSpan.FromMinutes(10), "Rescued"); } // pause a sec to see if quest completes. if (await Coroutine.Wait(2000, () => Quest.IsCompleted)) { return(true); } CycleToNearestPointInPath(); return(true); }
private async Task <bool> Coroutine_CombatMain() { if (IsDone) { return(false); } if (!Query.IsInVehicle()) { // only move to vehicle if doing nothing else if (!Targeting.Instance.IsEmpty() || BotPoi.Current.Type != PoiType.None) { return(false); } WoWUnit amber = Amber; // Wait for Amber to load in the ObjectMananger. if (amber == null || !amber.WithinInteractRange) { var moveTo = amber != null ? amber.Location : _vehicleLoc; await UtilityCoroutine.MoveTo(moveTo, "Moving to Start Amber(Human) Story", MovementBy); return(true); } if (await CommonCoroutines.StopMoving()) { return(true); } if (!GossipFrame.Instance.IsVisible) { amber.Interact(); await CommonCoroutines.SleepForRandomUiInteractionTime(); return(true); } if (GossipFrame.Instance.GossipOptionEntries != null) { GossipFrame.Instance.SelectGossipOption(0); await CommonCoroutines.SleepForRandomUiInteractionTime(); return(true); } return(true); } if (await InteractWithUnit(HozenEnemy)) { return(true); } if (await InteractWithUnit(OrcEnemy)) { return(true); } if (!Me.HasAura("See Quest Invis 5")) { var turret = Turret; if (TurretLocation.DistanceSqr(Me.Location) > 3 * 3) { await UtilityCoroutine.MoveTo(TurretLocation, "Turret Location", MovementBy); return(true); } if (turret == null) { TreeRoot.StatusText = "Waiting for turret to spawn"; return(true); } if (!turret.WithinInteractRange) { await UtilityCoroutine.MoveTo(TurretLocation, "interact range of turret", MovementBy); return(true); } if (await CommonCoroutines.StopMoving()) { return(true); } QBCLog.Info("Using turret"); Turret.Interact(); return(true); } return(false); }
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 ))); }
public void Loopstuff() { while (true) { ObjectManager.Update(); if (Me.IsQuestComplete(QuestId)) { _isBehaviorDone = true; break; } try { if (!Query.IsInVehicle()) { var turret = GetTurret(); if (turret != null) { if (turret.DistanceSqr > 5 * 5) { //Navigator.MoveTo(turret.Location); } else { turret.Interact(); } } else { QBCLog.Info("Unable to find turret"); } } else { if (Me.CurrentTarget != null && (Me.CurrentTarget.Distance < 60 || Me.CurrentTarget.InLineOfSight)) { WoWMovement.ClickToMove(Me.CurrentTarget.Location); //WoWMovement.ClickToMove(Me.CurrentTarget.Location.RayCast(Me.CurrentTarget.Rotation, 20)); var x = ObjectManager.GetObjectsOfType <WoWUnit>().FirstOrDefault(z => z.CharmedByUnit == Me); Vector3 v = Vector3.Normalize(Me.CurrentTarget.Location - Me.Location); Lua.DoString( string.Format( "VehicleAimIncrement(({0} - VehicleAimGetAngle())); CastPetAction(1);CastPetAction(2);", Math.Asin(v.Z).ToString())); } else { if (!Me.IsQuestObjectiveComplete(QuestId, 1)) { if (Marksmen != null) { Marksmen.Target(); } } else if (!Me.IsQuestObjectiveComplete(QuestId, 2)) { if (Cannoner != null) { Cannoner.Target(); } } else if (!Me.IsQuestObjectiveComplete(QuestId, 3)) { if (Cannon != null) { Cannon.Target(); } } } } } catch (Exception except) { QBCLog.Exception(except); } } }
private Composite CreateCombatBehavior() { // NB: We'll be running right over some hostiles while in the barrel. // Even with a PullDistance set to one, HBcore and the CombatRoutine are going to try to pull these mobs. // Thus, this behavior runs at "higher than combat" priority, and prevents the CombatRoutine from executing // while this behavior is in progress. // // 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 Decorator(context => !_isBehaviorDone, new PrioritySelector(context => _combatContext.Update(), // If quest is done, behavior is done... new Decorator(context => !UtilIsProgressRequirementsMet(QuestId, QuestRequirementInLog, QuestRequirementComplete), new Action(context => { _isBehaviorDone = true; QBCLog.Info("Finished"); })), // If not in Keg Bomb Vehicle, move to it and get inside... new Decorator(context => !Query.IsInVehicle() && (_combatContext.KegBomb != null), new PrioritySelector( new Decorator(context => _combatContext.KegBomb.Distance > _combatContext.KegBomb.InteractRange, new Action(context => { Navigator.MoveTo(_combatContext.KegBomb.Location); })), new Decorator(context => Me.IsMoving, new Action(context => { WoWMovement.MoveStop(); })), new Decorator(context => !Me.IsSafelyFacing(_combatContext.KegBomb), new Action(context => { _combatContext.KegBomb.Face(); })), new Sequence( // N.B. we need to wait a bit before jumping in vehicle after a round - // due to a bug that prevents bot from leaving vehicle until a relog new WaitContinue(2, context => false, new ActionAlwaysSucceed()), new Action(context => { _combatContext.ReInitialize(); _combatContext.KegBomb.Interact(); QBCLog.Info("Started barrel roll #{0}", ++_barrelRollCount); return RunStatus.Failure; })), new Wait(TimeSpan.FromMilliseconds(1000), context => false, new ActionAlwaysSucceed()) )), // If we are in the vehicle... new Decorator(context => Query.IsInVehicle() && (_combatContext.KegBombVehicle != null), new PrioritySelector( // If we've been in the barrel too long, just blow it up... // Blacklist whatever target we were after, and try again new Decorator(context => (_combatContext.BarrelRollingTimer.ElapsedMilliseconds > BarrelRollingTimeBeforeRetrying) && !_combatContext.IsKegIgnited, new Action(context => { QBCLog.Warning("We've been in the barrel too long--we're blowing it up to try again"); IgniteKeg(_combatContext); if (_combatContext.SelectedTarget != null) { Blacklist.Add(_combatContext.SelectedTarget, BlacklistFlags.Combat, TimeSpan.FromMinutes(3)); } })), // Select target, if not present... new Decorator(context => _combatContext.SelectedTarget == null, new Action(context => ChooseTarget(_combatContext))), // If we have a target, guide barrel to target... new Decorator(context => _combatContext.SelectedTarget != null, new Action(context => { float neededFacing = WoWMathHelper.CalculateNeededFacing(_combatContext.KegBombVehicle.Location, _combatContext.SelectedTarget.Location); neededFacing = WoWMathHelper.NormalizeRadian(neededFacing); float neededRotation = Math.Abs(neededFacing - _combatContext.KegBombVehicle.RenderFacing); neededRotation = WoWMathHelper.NormalizeRadian(neededRotation); // If we need to rotate heading 'too hard' to hit the target, then we missed the target... // Blow up the current barrel, blacklist the target, and try again if (((neededRotation > (Math.PI / 2)) && (neededRotation < ((Math.PI * 2) - (Math.PI / 2)))) && !_combatContext.IsKegIgnited) { QBCLog.Warning("We passed the selected target--igniting barrel to try again."); IgniteKeg(_combatContext); Blacklist.Add(_combatContext.SelectedTarget, BlacklistFlags.Combat, TimeSpan.FromMinutes(3)); } // Ignite the keg at the appropriate time... if (_combatContext.SelectedTarget.Distance <= IgniteDistance) { IgniteKeg(_combatContext); } // Guide the keg to target... Me.SetFacing(neededFacing); return RunStatus.Success; })) )) ))); }
protected override Composite CreateBehavior() { return(_root ?? (_root = new PrioritySelector( new Decorator(ret => Me.OnTaxi || _tryNumber >= 5 || (_doingQuestTimer.ElapsedMilliseconds >= 180000 && !WaitForNpcs), new Action(ret => _isBehaviorDone = true)), new Decorator(ret => CurrentNpc == null, new PrioritySelector( new Decorator(ret => NpcLocation.DistanceSquared(Me.Location) > 10 * 10, new Sequence( new Action(ret => QBCLog.Info("Cant find flightmaster, Moving to place provided by profile")), new Action(ret => Flightor.MoveTo(NpcLocation)))), new Action(ret => QBCLog.Info("Waiting for flightmaster to spawn")) ) ), new Decorator(ctx => Me.Mounted, new ActionRunCoroutine(ctx => CommonCoroutines.LandAndDismount("Interact Flightmaster"))), new Decorator(ret => !CurrentNpc.WithinInteractRange, new Action(ret => Navigator.MoveTo(CurrentNpc.Location)) ), // Getting ready to interact new Decorator(ctx => !TaxiFrame.Instance.IsVisible, new Sequence( new DecoratorContinue(ret => WoWMovement.ActiveMover.IsMoving, new Sequence( new Action(ret => WoWMovement.MoveStop()), new SleepForLagDuration())), new Action(ret => CurrentNpc.Interact()), new Sleep(1000), new SleepForLagDuration() )), new Decorator(ret => TaxiNumber == "0" && DestName == "ViewNodesOnly", new Sequence( new Action(ret => QBCLog.Info("Targeting Flightmaster: " + CurrentNpc.SafeName + " Distance: " + CurrentNpc.Location.Distance(Me.Location) + " to listing known TaxiNodes")), new Action(ret => Lua.DoString(string.Format("RunMacroText(\"{0}\")", "/run for i=1,NumTaxiNodes() do a=TaxiNodeName(i); print(i,a);end;"))), new Sleep(WaitTime), new Action(ret => _isBehaviorDone = true))), new Decorator(ret => TaxiNumber != "0", new Sequence( new Action(ret => QBCLog.Info("Targeting Flightmaster: " + CurrentNpc.SafeName + " Distance: " + CurrentNpc.Location.Distance(Me.Location))), new Action(ret => Lua.DoString(string.Format("RunMacroText(\"{0}\")", "/click TaxiButton" + TaxiNumber))), new Action(ret => _tryNumber++), new Sleep(WaitTime))), new Decorator(ret => DestName != "ViewNodesOnly", new Sequence( new Action(ret => QBCLog.Info("Taking a ride to: " + DestName)), new Action(ret => Lua.DoString(string.Format("RunMacroText(\"{0}\")", "/run for i=1,NumTaxiNodes() do a=TaxiNodeName(i); if strmatch(a,'" + DestName + "')then b=i; TakeTaxiNode(b); end end"))), new Action(ret => _tryNumber++), new Sleep(WaitTime))) ))); }
private async Task <bool> ScareSpiders() { // if not in a turret than move to one and interact with it if (!Query.IsInVehicle()) { var mustang = GetMustang(); if (mustang == null) { QBCLog.Warning("No mustang was found nearby"); return(false); } TreeRoot.StatusText = "Moving To Mustang"; if (mustang.DistanceSqr > 5 * 5) { return((await CommonCoroutines.MoveTo(mustang.Location)).IsSuccessful()); } await CommonCoroutines.LandAndDismount(); QBCLog.Info("Interacting with Mustang"); mustang.Interact(); return(true); } // Find the nearest spider and if none exist then move to the spawn location if (!Query.IsViable(_currentTarget) || !_currentTarget.IsAlive) { _currentTarget = ObjectManager.GetObjectsOfType <WoWUnit>() .Where(u => u.IsAlive && u.Entry == 44284 && !Blacklist.Contains(u, BlacklistFlags.Interact)) .OrderBy(u => u.DistanceSqr).FirstOrDefault(); if (_currentTarget == null) { if (!Navigator.AtLocation(_spiderSpawnLocation)) { return((await CommonCoroutines.MoveTo(_spiderSpawnLocation)).IsSuccessful()); } TreeRoot.StatusText = "Waiting for spiders to spawn"; return(true); } _noMoveBlacklistTimer.Reset(); _blacklistTimer.Reset(); QBCLog.Info("Locked on a new target. Distance {0}", _currentTarget.Distance); } TreeRoot.StatusText = "Scaring spider towards lumber mill"; var moveToPoint = WoWMathHelper.CalculatePointFrom(_lumberMillLocation, _currentTarget.Location, -6); if (moveToPoint.DistanceSqr((WoWMovement.ActiveMover ?? StyxWoW.Me).Location) > 4 * 4) { return((await CommonCoroutines.MoveTo(moveToPoint)).IsSuccessful()); } // spider not moving? blacklist and find a new target. if (_noMoveBlacklistTimer.ElapsedMilliseconds > 20000 && _currentTarget.Location.DistanceSqr(_spiderScareLoc) < 10 * 10) { Blacklist.Add(_currentTarget, BlacklistFlags.Interact, TimeSpan.FromMinutes(3), "Spider is not moving"); _currentTarget = null; } else if (_blacklistTimer.IsFinished) { Blacklist.Add(_currentTarget, BlacklistFlags.Interact, TimeSpan.FromMinutes(3), "Took too long"); _currentTarget = null; } else if (!_currentTarget.HasAura("Fear")) { await CommonCoroutines.StopMoving(); Me.SetFacing(_lumberMillLocation); await CommonCoroutines.SleepForLagDuration(); await Coroutine.Sleep(200); if (!_noMoveBlacklistTimer.IsRunning || _currentTarget.Location.DistanceSqr(_spiderScareLoc) >= 10 * 10) { _noMoveBlacklistTimer.Restart(); _spiderScareLoc = _currentTarget.Location; } Lua.DoString("CastSpellByID(83605)"); await Coroutine.Wait(3000, () => Query.IsViable(_currentTarget) && _currentTarget.HasAura("Fear")); } return(true); }
protected override Composite CreateMainBehavior() { return(_root ?? (_root = new PrioritySelector( // don't drop down while wait timer is running new Decorator(ctx => !_waitTimer.IsFinished, new ActionAlwaysSucceed()), new Decorator(ret => Counter > NumOfTimes, new Action(ret => BehaviorDone(string.Format("Used the item {0} times", NumOfTimes)))), // If item is not in our backpack, behavior is done... new Decorator(context => Item == null, new Action(context => { QBCLog.Error("ItemId({0}) is not in our backpack", ItemId); TreeRoot.Stop(); BehaviorDone("Item is not in our backpack"); })), // Wait for item to come off of cooldown... new Decorator(context => Item.CooldownTimeLeft > TimeSpan.Zero, new Action(context => QBCLog.Info("Waiting for {0} to leave cooldown (time remaining: {1})", Item.SafeName, Item.CooldownTimeLeft))), new Decorator( ret => UseType == QBType.PointToPoint, new PrioritySelector( new Decorator( ret => Me.Location.Distance(MoveToLocation) > 3, new ActionRunCoroutine(context => UtilityCoroutine.MoveTo(MoveToLocation, "Destination", MovementBy))), new Sequence( new Action(ret => TreeRoot.StatusText = string.Format("Using Quest Item: {0} Out of {1} Times", Counter, NumOfTimes)), new Action(ret => Navigator.PlayerMover.MoveStop()), new Action(ret => Me.SetFacing(ClickToLocation)), new SleepForLagDuration(), new Action(ret => Item.UseContainerItem()), new SleepForLagDuration(), new Action(ret => Counter++), new Action(ret => SpellManager.ClickRemoteLocation(ClickToLocation)), new Action(ctx => _waitTimer.Reset()) ))), new Decorator( ret => UseType == QBType.PointToObject, new PrioritySelector( new Decorator( ret => UseObject == null && Me.Location.DistanceSqr(MoveToLocation) >= 2 * 2, new Sequence( new Action(ret => TreeRoot.StatusText = "Moving to location"), new ActionRunCoroutine(context => UtilityCoroutine.MoveTo(MoveToLocation, "Destination", MovementBy)))), new Decorator( ret => UseObject != null, new PrioritySelector( new Decorator( ret => UseObject.DistanceSqr >= Range * Range, new Sequence( new Action(ret => TreeRoot.StatusText = "Moving closer to the object"), new ActionRunCoroutine(context => UtilityCoroutine.MoveTo(UseObject.Location, "UseObject location", MovementBy)))), new Decorator( ret => UseObject.DistanceSqr < MinRange * MinRange, new Sequence( new Action(ret => TreeRoot.StatusText = "Too Close, Backing Up"), new ActionRunCoroutine(context => UtilityCoroutine.MoveTo( WoWMathHelper.CalculatePointFrom(Me.Location, UseObject.Location, (float)MinRange + 2f), "Backing up", MovementBy)) )), new Sequence( new Action(ret => TreeRoot.StatusText = string.Format("Using Item: {0} {1} Out of {2} Times", UseObject.SafeName, Counter, NumOfTimes)), new Action(ret => Navigator.PlayerMover.MoveStop()), new Action(ret => Me.SetFacing(UseObject.Location)), new SleepForLagDuration(), new Action(ret => Item.UseContainerItem()), new Action(ret => Counter++), new SleepForLagDuration(), new Action(ret => SpellManager.ClickRemoteLocation(UseObject.Location)), new Action(ret => _npcBlacklist.Add(UseObject.Guid)), new Action(ctx => _waitTimer.Reset())))), new Action(ret => TreeRoot.StatusText = "No objects around. Waiting") )), new Decorator( ret => UseType == QBType.ToObject, new PrioritySelector( new Decorator( ret => UseObject != null, new PrioritySelector( new Decorator( ret => UseObject.DistanceSqr >= Range * Range, new Sequence( new Action(ret => TreeRoot.StatusText = "Moving to object's range"), new ActionRunCoroutine(context => UtilityCoroutine.MoveTo(UseObject.Location, "UseObject location", MovementBy)))), new Decorator( ret => UseObject.DistanceSqr < MinRange * MinRange, new Sequence( new Action(ret => TreeRoot.StatusText = "Too Close, Backing Up"), new ActionRunCoroutine( context => UtilityCoroutine.MoveTo( WoWMathHelper.CalculatePointFrom(Me.Location, UseObject.Location, (float)MinRange + 2f), "Backing up", MovementBy)) )), new Sequence( new Action(ret => TreeRoot.StatusText = string.Format("Using Item: {0} {1} Out of {2} Times", UseObject.SafeName, Counter, NumOfTimes)), new Action(ret => Navigator.PlayerMover.MoveStop()), new Action(ret => Me.SetFacing(UseObject.Location)), new SleepForLagDuration(), new Action(ret => Item.UseContainerItem()), new Action(ret => Counter++), new SleepForLagDuration(), new Action(ret => SpellManager.ClickRemoteLocation(UseObject.Location)), new Action(ret => _npcBlacklist.Add(UseObject.Guid)), new Action(ctx => _waitTimer.Reset())))), new Decorator( ret => Me.Location.DistanceSqr(MoveToLocation) > 2 * 2, new Sequence( new Action(ret => TreeRoot.StatusText = "Moving to location"), new ActionRunCoroutine(context => UtilityCoroutine.MoveTo(MoveToLocation, "Destination", MovementBy)))) )) ))); }