private async Task UseItem(int x) { var g = Geomancer(_spots[x]); if (!Query.IsViable(g)) { return; } if (g.DistanceSqr > 5 * 5) { await CommonCoroutines.MoveTo(g.Location); return; } if (Me.CurrentTarget != g) { g.Target(); return; } await CommonCoroutines.Dismount(); Rock.Use(); }
public static async Task <bool> Rotation() { if (Me.Mounted) { if (await CommonCoroutines.Dismount()) { return(true); } } return(false); }
public static async Task <bool> Rotation() { if (!Me.Mounted && !Me.IsInTravelForm()) { return(await Combat.Rotation()); } if (await CommonCoroutines.Dismount()) { return(true); } return(await Combat.Rotation()); }
/// <summary> /// Mounts a vehicle /// </summary> /// <param name="searchLocation">The search location.</param> /// <param name="movementBy">The movement type.</param> /// <param name="extraVehicleQualifiers">The extra vehicle qualifiers.</param> /// <param name="vehicleIds">The vehicle ids.</param> /// <returns> /// <c>true</c> if any action was taken; <c>false</c> otherwise /// </returns> public static async Task <bool> MountVehicle( Vector3 searchLocation, MovementByType movementBy = MovementByType.FlightorPreferred, Func <WoWUnit, bool> extraVehicleQualifiers = null, params int[] vehicleIds) { if (Query.IsInVehicle()) { return(false); } var vehicle = Query.FindUnoccupiedVehicles(vehicleIds, extraVehicleQualifiers).FirstOrDefault(); if (vehicle == null) { if (!Navigator.AtLocation(searchLocation)) { return(await MoveTo(searchLocation, "Vehicle search area", movementBy)); } await (s_mountVehicleUserUpdateThrottle ?? (s_mountVehicleUserUpdateThrottle = new ThrottleCoroutineTask( TimeSpan.FromSeconds(10), async() => QBCLog.Info("Waiting for a vehicle to become available")))); return(true); } if (!vehicle.WithinInteractRange) { return(await MoveTo(vehicle.Location, vehicle.SafeName, movementBy, vehicle.InteractRange)); } if (await CommonCoroutines.Dismount("Getting inside vehicle")) { await Coroutine.Sleep(Delay.BeforeButtonClick); } vehicle.Interact(); await Coroutine.Sleep(Delay.AfterInteraction); return(true); }
/// <summary>Gossips with the specified wow object. Hearthstone bind popups are automatically accepted</summary> /// <param name="wowObject">The wow object. Navigates to <paramref name="searchLocation" /> null </param> /// <param name="searchLocation">The search location of <paramref name="wowObject" />.</param> /// <param name="movementBy">The movement type to use.</param> /// <param name="navigationFailedAction"> /// The action to take if <paramref name="wowObject" /> or <paramref name="searchLocation"/> cant be navigated to /// </param> /// <param name="notFoundAction"> /// The action to take if <paramref name="wowObject" /> is not found at /// <paramref name="searchLocation" />. /// </param> /// <param name="noGossipFrameAction"> /// The action to take if interaction with <paramref name="wowObject" /> didn't open a /// gossip frame. /// </param> /// <param name="noMatchingGossipOptionAction"> /// <para>The action to take if the passed in gossip type and/or gossip indices </para> /// <para>doesn't match what was offered by <paramref name="wowObject" />.</para> /// </param> /// <param name="gossipEntryType"> /// <para>Type gossip entry type to select. Ignored if set to Unknown.</para> /// <para>If none of this type are found on current page then</para> /// <para> normal gossip types are clicked through in hopes of ending on a page with this gossip type</para> /// </param> /// <param name="gossipIndexes"> /// The gossip indexes to follow through. Has precedence over /// <paramref name="gossipEntryType" />. /// </param> /// <exception cref="Exception">A delegate callback throws an exception.</exception> public static async Task <bool> Gossip( WoWObject wowObject, WoWPoint searchLocation, MovementByType movementBy = MovementByType.FlightorPreferred, Action navigationFailedAction = null, Action notFoundAction = null, Action noGossipFrameAction = null, Action noMatchingGossipOptionAction = null, GossipEntry.GossipEntryType gossipEntryType = GossipEntry.GossipEntryType.Unknown, params int[] gossipIndexes) { if (wowObject == null) { if (!Navigator.AtLocation(searchLocation)) { if (await MoveTo(searchLocation, "Gossip object search area", movementBy)) { return(true); } navigationFailedAction?.Invoke(); return(false); } if (notFoundAction != null) { notFoundAction(); } else { TreeRoot.StatusText = "Waiting for the WoW object selected for gossip to spawn"; } return(true); } if (!wowObject.WithinInteractRange) { if (await MoveTo(wowObject.Location, wowObject.SafeName, movementBy)) { return(true); } navigationFailedAction?.Invoke(); return(false); } if (await CommonCoroutines.Dismount("Gossiping with " + wowObject.SafeName)) { await Coroutine.Sleep(Delay.BeforeButtonClick); } // If gossip frame is open then we must assume that it doesn't belong to the selected gossip object at this point if (GossipFrame.Instance.IsVisible) { GossipFrame.Instance.Close(); return(true); } Func <bool> isFrameReadyForInput = () => GossipFrame.Instance.IsVisible && (GossipFrame.Instance.GossipOptionEntries != null || (!gossipIndexes.Any() && gossipEntryType == GossipEntry.GossipEntryType.Unknown)); wowObject.Interact(); var openedGossipFrame = await Coroutine.Wait(3000, isFrameReadyForInput); if (!openedGossipFrame) { QBCLog.Warning("No gossip frame was opened after interacting with {0}", wowObject.SafeName); noGossipFrameAction?.Invoke(); return(false); } int gossipPage = 1; // Click through all the gossip indices for (var i = 0; i < gossipIndexes.Length; i++) { var index = gossipIndexes[i] - 1; var gossipEntry = GossipFrame.Instance.GossipOptionEntries.Where(g => g.Index == index) .Select(g => (GossipEntry?)g) .FirstOrDefault(); if (!gossipEntry.HasValue || gossipEntry.Value.Type == GossipEntry.GossipEntryType.Unknown) { QBCLog.Warning("{0} does not provide a gossip at index {1} on page {2}", wowObject.SafeName, index + 1, gossipPage); noMatchingGossipOptionAction?.Invoke(); return(false); } await ClickGossipOption(gossipEntry.Value, gossipPage); // make sure frame didn't close before we're done. if (!isFrameReadyForInput() && (i < gossipIndexes.Length - 1 || gossipEntryType != GossipEntry.GossipEntryType.Unknown)) { // This can happen if some external event causes object to stop offering gossip frame, such as NPC getting into combat. // Usually this can be fixed by interacting with object again at a later time. We let the caller handle this. QBCLog.Warning("Gossip frame for {0} closed unexpectedly.", wowObject.SafeName); return(true); } gossipPage++; } if (gossipEntryType != GossipEntry.GossipEntryType.Unknown) { if (!gossipIndexes.Any()) { while (true) { var gossipEntry = GossipFrame.Instance.GossipOptionEntries.FirstOrDefault(g => g.Type == gossipEntryType); // If no gossip indices were specified then we just click through more gossip, // hopefully it leads to the final gossip type if (gossipEntry.Type != gossipEntryType) { gossipEntry = GossipFrame.Instance.GossipOptionEntries.FirstOrDefault(g => g.Type == GossipEntry.GossipEntryType.Gossip); } if (gossipEntry.Type == GossipEntry.GossipEntryType.Unknown) { QBCLog.Warning("{0} does not provide a {0} gossip type", wowObject.SafeName, gossipEntryType); noMatchingGossipOptionAction?.Invoke(); return(false); } await ClickGossipOption(gossipEntry, gossipPage); if (!isFrameReadyForInput() && gossipEntry.Type != gossipEntryType) { // This can happen if some external event causes object to stop offering gossip frame, such as NPC getting into combat. // Usually this can be fixed by interacting with object again at a later time. We let the caller handle this. QBCLog.Warning("Gossip frame for {0} closed unexpectedly.", wowObject.SafeName); return(true); } if (gossipEntry.Type == gossipEntryType) { break; } gossipPage++; } } } // Set hearthstone automatically const string setHsPopupName = "CONFIRM_BINDER"; if (Lua.GetReturnVal <bool>($"return StaticPopup_Visible('{setHsPopupName}')", 0)) { uint hsId = StyxWoW.Me.HearthstoneAreaId; Lua.DoString( $"local _,frame = StaticPopup_Visible('{setHsPopupName}') if frame then StaticPopup_OnClick(frame, 1) end"); if (await Coroutine.Wait(5000, () => StyxWoW.Me.HearthstoneAreaId != hsId)) { await CommonCoroutines.SleepForRandomReactionTime(); var boundLocation = Lua.GetReturnVal <string>("return GetBindLocation()", 0); QBCLog.Info( "You are now bound at {0} Inn in {1}({2})", (Query.IsViable(wowObject) ? wowObject.SafeName : "the"), boundLocation, Me.HearthstoneAreaId); } } return(true); }
public static async Task <bool> DoFishing() { if (AutoAnglerBot.Instance.Profile.FishAtHotspot && !Navigator.AtLocation(AutoAnglerBot.Instance.Profile.CurrentPoint)) { return(false); } if (AutoAnglerSettings.Instance.Poolfishing && BotPoi.Current.Type != PoiType.Harvest) { return(false); } if (await CheckLootFrame()) { return(true); } // refresh water walking if needed if (!Me.Mounted && WaterWalking.CanCast && !WaterWalking.IsActive && await WaterWalking.Cast()) { return(true); } if (AutoAnglerSettings.Instance.Poolfishing) { var pool = BotPoi.Current.AsObject as WoWGameObject; if (pool == null || !pool.IsValid) { BotPoi.Clear(); return(false); } if (await MoveToPool(pool)) { return(true); } } if (await EquipPole()) { return(true); } if (await EquipHat()) { return(true); } if (await Applylure()) { return(true); } if (await Applybait()) { return(true); } if (!AutoAnglerSettings.Instance.Poolfishing && AutoAnglerBot.Instance.ShouldFaceWaterNow) { AutoAnglerBot.Instance.ShouldFaceWaterNow = false; if (await FaceWater()) { return(true); } } if (Me.Mounted && await CommonCoroutines.Dismount("Fishing")) { return(true); } if (!await Coroutine.Wait(10000, () => !Me.IsFalling)) { AutoAnglerBot.Log("Falling for 10 seconds; I don't think this will end good."); return(false); } if (Me.IsSwimming) { await JumpOnWaterSurface(); } if (Me.IsMoving) { WoWMovement.MoveStop(); if (!await Coroutine.Wait(4000, () => !Me.IsMoving)) { return(false); } } // Checks if we got a bite and recasts if needed. if (await CheckFishLine()) { return(true); } return(false); }
private Composite CreateBehavior_GetInVehicle() { const uint oldBlastyId = 43562; WoWUnit vehicle = null; return(new Decorator(ctx => !Query.IsInVehicle(), new PrioritySelector( ctx => vehicle = ObjectManager.GetObjectsOfTypeFast <WoWUnit>().FirstOrDefault(u => u.Entry == oldBlastyId), new Decorator(ctx => vehicle != null && !vehicle.WithinInteractRange, new Action(ctx => Navigator.MoveTo(vehicle.Location))), new Decorator( ctx => vehicle != null && vehicle.WithinInteractRange, new PrioritySelector( new Decorator(ctx => Me.Mounted, new ActionRunCoroutine(context => CommonCoroutines.Dismount("Getting in vehicle"))), new Action(ctx => vehicle.Interact())))))); }
protected async override Task Run() { if (Me.IsFlying && await CommonCoroutines.Dismount("Crafting an item")) { return; } if (!IsRecipe) { CheckTradeskillList(); } if (Casted >= CalculatedRepeat) { Finished(); return; } // can't make recipe so stop trying. if (IsRecipe && Recipe.CanRepeatNum2 <= 0) { Finished("Not enough material."); return; } if (Me.IsCasting && Me.CastingSpellId != Entry) { SpellManager.StopCasting(); } // we should confirm the last recipe in list so we don't make an axtra if (Casted + 1 < CalculatedRepeat || (Casted + 1 == CalculatedRepeat && (Confimed || !_spamControl.IsRunning || (_spamControl.ElapsedMilliseconds >= (_recastTime + (_recastTime / 2)) + _waitTime && !StyxWoW.Me.IsCasting)))) { if (!_spamControl.IsRunning || Me.IsCasting && Me.CurrentCastTimeLeft <= TimeSpan.FromMilliseconds(250) || (!StyxWoW.Me.IsCasting && _spamControl.ElapsedMilliseconds >= _waitTime)) { if (StyxWoW.Me.IsMoving) { WoWMovement.MoveStop(); } if (!QueueIsRunning) { Lua.Events.AttachEvent("UNIT_SPELLCAST_SUCCEEDED", OnUnitSpellCastSucceeded); QueueIsRunning = true; TreeRoot.StatusText = string.Format("Casting: {0}", IsRecipe ? Recipe.Name : Entry.ToString()); } WoWSpell spell = WoWSpell.FromId((int)Entry.Value); if (spell == null) { PBLog.Warn("{0}: {1}", Strings["Error_UnableToFindSpellWithEntry"], Entry.Value.ToString(CultureInfo.InvariantCulture)); return; } _recastTime = spell.CastTime; ProfessionbuddyBot.Debug("Casting {0}, recast :{1}", spell.Name, _recastTime); if (CastOnItem) { WoWItem item = TargetedItem; if (item != null) { spell.CastOnItem(item); } else { PBLog.Warn( "{0}: {1}", Strings["Error_UnableToFindItemToCastOn"], IsRecipe ? Recipe.Name : Entry.Value.ToString(CultureInfo.InvariantCulture)); IsDone = true; } } else { spell.Cast(); } _waitTime = Util.WowWorldLatency * 3 + 50; Confimed = false; _spamControl.Reset(); _spamControl.Start(); } } }
private Composite CreateBehavior_Antistuck() { return(new PrioritySelector( new Decorator(context => _stuckTimer.IsFinished, new Sequence(context => _antiStuckMyLoc = WoWMovement.ActiveMover.Location, // Check if stuck... new DecoratorContinue(context => _antiStuckMyLoc.DistanceSqr(_antiStuckPrevPosition) < (3 * 3), new Sequence(context => _antiStuckPerformSimpleSequence = _antiStuckStuckSucceedTimer.IsFinished, new DecoratorContinue(context => Me.IsMounted() && !Me.IsFlying, new ActionRunCoroutine(context => CommonCoroutines.Dismount("Stuck"))), // Perform simple unstuck proceedure... new DecoratorContinue(context => _antiStuckPerformSimpleSequence, new Sequence( new Action(context => QBCLog.Debug("Stuck. Trying to jump")), new Action(context => { // ensure bot is moving forward when jumping (Wow will sometimes automatically // stop moving if running against a wall) if (ShouldPerformCTM) { WoWMovement.ClickToMove(Destination); } WoWMovement.Move(WoWMovement.MovementDirection.JumpAscend); }), new Sleep(1000), new Action(context => WoWMovement.MoveStop(WoWMovement.MovementDirection.JumpAscend)) )), // perform less simple unstuck proceedure new DecoratorContinue(context => !_antiStuckPerformSimpleSequence, new Sequence(context => _antiStuckMoveDirection = GetRandomMovementDirection(), new Action(context => QBCLog.Debug("Stuck. Movement Directions: {0}", _antiStuckMoveDirection)), new Action(context => WoWMovement.Move(_antiStuckMoveDirection)), new Sleep(2000), new Action(context => WoWMovement.MoveStop(_antiStuckMoveDirection)))), new Action(context => _antiStuckStuckSucceedTimer.Reset()))), new Action(context => _antiStuckPrevPosition = _antiStuckMyLoc), new Action(context => _stuckTimer.Reset()) )))); }
private Composite CreateBehavior_GetInVehicle() { const uint flamebringerId = 27292; WoWUnit flamebringer = null; return (new PrioritySelector( ctx => flamebringer = ObjectManager.GetObjectsOfTypeFast <WoWUnit>().FirstOrDefault(u => u.Entry == flamebringerId), // move out to framebringers location new Decorator(ctx => flamebringer == null, CreateBehavior_MoveTo(ctx => _flamebringerLocation)), new Decorator(ctx => flamebringer.Distance > 5, CreateBehavior_MoveTo(ctx => flamebringer.Location)), // dismount and cancel shapeshift new Decorator(ctx => Me.IsMounted(), new ActionRunCoroutine(context => CommonCoroutines.Dismount("Getting on Flamebringger"))), new Decorator(ctx => Me.IsShapeshifted(), new Action(ctx => Lua.DoString("CancelShapeshiftForm()"))), new Decorator(ctx => Me.IsMoving, new Action(ctx => WoWMovement.MoveStop())), // interact with and talk to flamebringer new Decorator(ctx => !GossipFrame.Instance.IsVisible, new Action(ctx => flamebringer.Interact())), new Decorator( ctx => GossipFrame.Instance.IsVisible, new Action(ctx => GossipFrame.Instance.SelectGossipOption(0))))); }
public async static Task <bool> MoveToPool(WoWGameObject pool) { if (!AutoAnglerSettings.Instance.Poolfishing || AutoAnglerBot.Instance.Profile.FishAtHotspot) { return(false); } if (pool == null || !pool.IsValid) { return(false); } if (_lastPoolGuid != pool.Guid) { MoveToPoolTimer.Reset(); _lastPoolGuid = pool.Guid; if (!FindPoolPoint(pool, out _poolPoints) || !_poolPoints.Any()) { Utility.BlacklistPool(pool, TimeSpan.FromDays(1), "Found no landing spots"); return(false); } } // should never be true.. but being safe.. if (!_poolPoints.Any()) { Utility.BlacklistPool(pool, TimeSpan.FromDays(1), "Pool landing points mysteriously disapear..."); return(false); } var myLoc = Me.Location; var moveto = _poolPoints[0]; TreeRoot.StatusText = "Moving to " + pool.Name; if (myLoc.DistanceSqr(moveto) > 4 * 4) { MoveResult moveResult; if (AutoAnglerSettings.Instance.Fly) { // don't bother mounting up if we can use navigator to walk over if it's less than 25 units away if (myLoc.DistanceSqr(moveto) < 25 * 25 && !Me.Mounted) { moveResult = Navigator.MoveTo(moveto); if (moveResult != MoveResult.Failed && moveResult != MoveResult.PathGenerationFailed) { return(true); } } //if (!Me.Mounted && !SpellManager.GlobalCooldown) //{ // Flightor.MountHelper.MountUp(); // return true; //} Flightor.MoveTo(WoWMathHelper.CalculatePointFrom(myLoc, moveto, -1f)); return(true); } moveResult = Navigator.MoveTo(moveto); if (moveResult == MoveResult.UnstuckAttempt || moveResult == MoveResult.PathGenerationFailed || moveResult == MoveResult.Failed) { if (!RemovePointAtTop(pool)) { return(true); } AutoAnglerBot.Debug("Unable to path to pool point, switching to a new point"); _poolPoints.Sort((a, b) => a.DistanceSqr(myLoc).CompareTo(b.DistanceSqr(myLoc))); } // if it takes more than 25 seconds to get to a point remove that point and try another. if (MoveToPoolTimer.IsFinished) { if (!RemovePointAtTop(pool)) { return(false); } } return(true); } // wait for bot to reach destination before dismounting await Coroutine.Wait(2000, () => !Me.IsMoving); if (Me.Mounted) { await CommonCoroutines.Dismount("Fishing"); } // can't fish while swimming.. if (Me.IsSwimming && !WaterWalking.IsActive && !WaterWalking.CanCast) { AutoAnglerBot.Debug("Moving to new PoolPoint since I'm swimming at current PoolPoint"); if (!RemovePointAtTop(pool)) { return(false); } return(true); } return(false); }