private static async Task <bool> HandleDismount() { Navigator.Clear(); Flightor.Clear(); while (Me.Mounted) { if (Me.Location.Distance(s_targetLocation) > 5) { await Coroutine.Wait(20000, () => Flightor.MoveTo(s_targetLocation) == MoveResult.ReachedDestination); } else { await CommonCoroutines.LandAndDismount(null, true, s_targetLocation); await CommonCoroutines.StopMoving(); var _target = Me.CurrentTarget; if (_target != null) { Lua.DoString("StartAttack()"); } } //await Coroutine.Yield(); } return(true); }
private async Task <bool> MainLogic() { if (GetOffLocation != Vector3.Zero && Me.Location.DistanceSquared(GetOffLocation) < 2 * 2) { BehaviorDone("Successfully used the transport."); return(true); } if (Me.IsOnTransport || _usedTransport) { if (TransportLocation != Vector3.Zero && TransportLocation.DistanceSquared(EndLocation) < 1.5 * 1.5) { TreeRoot.StatusText = "Moving out of transport"; Navigator.PlayerMover.MoveTowards(GetOffLocation); return(true); } _usedTransport = true; TreeRoot.StatusText = "Waiting for the end location"; return(true); } if (Me.IsMoving) { return(false); } if (TransportLocation != Vector3.Zero && TransportLocation.DistanceSquared(StartLocation) < 1.5 * 1.5 && WaitAtLocation.DistanceSquared(Me.Location) < 2 * 2) { // don't do anything that can cause toon to move off course LevelBot.BehaviorFlags &= ~(BehaviorFlags.Vendor | BehaviorFlags.FlightPath | BehaviorFlags.Combat | BehaviorFlags.Loot); TreeRoot.StatusText = "Moving inside transport"; Navigator.PlayerMover.MoveTowards(StandLocation); return(true); } if (WaitAtLocation.DistanceSquared(Me.Location) > 2 * 2) { await UtilityCoroutine.MoveTo(WaitAtLocation, DestName, MovementBy); return(true); } await CommonCoroutines.LandAndDismount(); TreeRoot.StatusText = "Waiting for transport"; return(true); }
protected override async Task Run() { if (StyxWoW.Me.Location.Distance(_loc) > 6) { Flightor.MoveTo(_loc); TreeRoot.StatusText = string.Format("Flying to location {0}", _loc); } else { if (Dismount) { await CommonCoroutines.LandAndDismount(landPoint : _loc); } //Lua.DoString("Dismount() CancelShapeshiftForm()"); IsDone = true; TreeRoot.StatusText = string.Format("Arrived at location {0}", _loc); } }
private static async Task <bool> TryNavigator(Vector3 destination, float?distanceTolerance, string destinationName = null) { MoveToParameters moveToParams = new MoveToParameters(destination); if (distanceTolerance.HasValue) { moveToParams.DistanceTolerance = distanceTolerance.Value; } // If we can navigate to destination, use navigator... var moveResult = Navigator.MoveTo(moveToParams); if (moveResult.IsSuccessful()) { return(true); } // Make sure we are on ground if navigation failed. if (StyxWoW.Me.IsFlying) { if (await CommonCoroutines.LandAndDismount("For ground navigation")) { return(true); } } if (destinationName == null) { destinationName = destination.ToString(); } QBCLog.DeveloperInfo( "Navigator unable to move from {0} to destination({1}, {2}) on ground --try MovementBy=\"FlightorPreferred\".", WoWMovement.ActiveMover.Location, destinationName, destination.ToString()); return(false); }
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(new PrioritySelector( // PvP server considerations... // Combat is disabled while on the Taxi. If on the ground, we want it enabled // in case we get attacked on a PvP server. new Decorator(context => !LevelBot.BehaviorFlags.HasFlag(BehaviorFlags.Combat), new Action(context => { LevelBot.BehaviorFlags |= BehaviorFlags.Combat; })), // Move to flight master, and interact to take taxi ride... new Decorator(context => !Me.OnTaxi, new PrioritySelector(context => { FlightMaster = Query.FindMobsAndFactions(Utility.ToEnumerable <int>(MobId_FlightMaster)) .FirstOrDefault() as WoWUnit; return context; }, // If flight master not in view, move to where he should be... new Decorator(context => FlightMaster == null, new ActionRunCoroutine( context => UtilityCoroutine.MoveTo( WaitLocation, "FlightMaster location", MovementBy))), // Make certain the bombs are in our backpack... new ActionRunCoroutine( ctx => _waitForInventoryItem ?? (_waitForInventoryItem = new UtilityCoroutine.WaitForInventoryItem( () => ItemId_Bomb, () => { QBCLog.ProfileError( "Cannot continue without required item: {0}", Utility.GetItemNameFromId(ItemId_Bomb)); BehaviorDone(); }))), // Move to flightmaster, and gossip to hitch a ride... new Decorator(context => FlightMaster != null, new PrioritySelector( new Decorator(context => !FlightMaster.WithinInteractRange, new ActionRunCoroutine( context => UtilityCoroutine.MoveTo( FlightMaster.Location, FlightMaster.SafeName, MovementBy))), new ActionRunCoroutine(context => CommonCoroutines.StopMoving()), new Decorator(ctx => Me.Mounted, new ActionRunCoroutine(ctx => CommonCoroutines.LandAndDismount())), new Decorator(context => !GossipFrame.Instance.IsVisible, new Action(context => { FlightMaster.Interact(); })), new Action(context => { GossipFrame.Instance.SelectGossipOption(GossipOption); }) )) )) )); }
/// <summary> /// Mounts or Dismounts according to the provided MOUNTSTRATEGYDELEGATE. /// <para> /// Notes: /// <list type="bullet"> /// <item> /// <description> /// <para> /// * A "Dismount" will unmount, or cancel a 'mounted' shapeshift form. /// Examples of the latter include: Druid Flight Form, Druid Travel Form, Shaman Ghost Wolf, Worgen /// Running Wild. /// </para> /// </description> /// </item> /// <item> /// <description> /// <para> * Requests to "Mount" will only be honored if the area allows it.</para> /// </description> /// </item> /// </list> /// </para> /// </summary> /// <returns></returns> /// <remarks>17Apr2013-03:11UTC chinajade</remarks> public static async Task <bool> ExecuteMountStrategy(MountStrategyType mountStrategy, NavType navType = NavType.Fly) { if (mountStrategy == MountStrategyType.None) { return(false); } #pragma warning disable 618 // Dismount needed? if (mountStrategy == MountStrategyType.Dismount || mountStrategy == MountStrategyType.CancelShapeshift || mountStrategy == MountStrategyType.DismountOrCancelShapeshift || mountStrategy == MountStrategyType.Land) { if (!Me.Mounted) { return(false); } if (mountStrategy != MountStrategyType.Land) { return(await CommonCoroutines.LandAndDismount("Requested by QB")); } if (!Me.IsFlying) { return(false); } return(await CommonCoroutines.LandAndDismount("Land requested by QB", false)); } #pragma warning restore 618 if (mountStrategy == MountStrategyType.Mount && Mount.UseMount && Mount.CanMount()) { if (Me.Mounted) { // Check if we should switch mounts if (navType == NavType.Fly) { if (Mount.Current.IsFlyingMount || !Flightor.IsFlyableArea()) { return(false); } await CommonCoroutines.LandAndDismount("Switching to flying mount"); } else { // If ground nav then any mount is fine. return(false); } } if (navType == NavType.Fly) { if (!Flightor.CanFly) { return(false); } return(await CommonCoroutines.SummonFlyingMount()); } return(await CommonCoroutines.SummonGroundMount()); } return(false); }
/// <summary> Finds a proper location to land and dismounts. </summary> /// <remarks> raphus, 12/10/2013. </remarks> public static async Task <bool> LandAndDismount(string reason = "[QB] LandAndDismount") { return(await CommonCoroutines.LandAndDismount(reason)); }
private Composite StateBehaviorPS_MovingToSafeSpot() { return(new PrioritySelector( // If a "Move Near" mob was specified, move to it... new Decorator(context => MobIdToMoveNear > 0, new PrioritySelector( new Decorator(context => Query.IsViable(Mob_ToMoveNear), new PrioritySelector( // Target the MoveToNpc, as feedback to the user... new ActionFail(context => { Utility.Target(Mob_ToMoveNear); }), // Move to mob... new Decorator(ctx => !Navigator.AtLocation(Mob_ToMoveNear.Location), new ActionRunCoroutine( context => UtilityCoroutine.MoveTo( Mob_ToMoveNear.Location, Mob_ToMoveNear.SafeName, MovementBy))) )), // Need to wait for Mob to respawn... new Decorator(context => !Query.IsViable(Mob_ToMoveNear), new Action(context => { TreeRoot.StatusText = string.Format("Waiting for {0} to respawn", Utility.GetObjectNameFromId(MobIdToMoveNear)); })) )), // No "Move Near" mob, so use the provided Safe spot coordinates... new Decorator(context => MobIdToMoveNear <= 0 && !Navigator.AtLocation(SafespotLocation), new ActionRunCoroutine( context => UtilityCoroutine.MoveTo( SafespotLocation, "safe spot", MovementBy))), // Dismount once we've arrived at mob or destination... new Decorator(ctx => Me.Mounted, new ActionRunCoroutine(ctx => CommonCoroutines.LandAndDismount())), new Decorator(ctx => StyxWoW.Me.IsMoving, new Action(ctx => WoWMovement.MoveStop())), // Target and Face the AvoidNpc, as feedback to the user... new ActionFail( context => { Utility.Target(Mob_ToAvoid, true); }), // If AvoidNpc is not around, // or if AvoidNpc is prescribed distance away, and facing away from us, // we're done... new Decorator(context => IsSafeToMoveToDestination(Mob_ToAvoid), new Action(context => { FollowPath.DismissPetIfNeeded(); Path_Ingress = null; Path_Egress = null; State_MainBehavior = StateType_MainBehavior.PathIngressing; })), // Tell user what we're up to... new CompositeThrottle(Throttle.UserUpdate, new Action(context => { TreeRoot.StatusText = string.Format("Waiting for '{0}' to move {1:F1}/{2:F1} yards away, and pathing away from us.", Mob_ToAvoid.SafeName, Mob_ToAvoid.Distance, AvoidDistance); })) )); }
// Originally contributed by Chinajade. // // LICENSE: // This work is licensed under the // Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. // //Modified to work in conjunction with my behavior objects. /// <summary> /// Uses the transport. /// </summary> /// <param name="transportId">The transport identifier.</param> /// <param name="startLocation">The start location.</param> /// <param name="endLocation">The end location.</param> /// <param name="waitAtLocation">The wait at location.</param> /// <param name="standAtLocation">The stand at location.</param> /// <param name="getOffLocation">The get off location.</param> /// <param name="movement">The movement.</param> /// <param name="destination">The destination.</param> /// <param name="navigationFailedAction"> /// The action to take if <paramref name="waitAtLocation" /> cant be navigated to /// </param> /// <returns>returns <c>true</c> until done</returns> /// <exception cref="Exception">A delegate callback throws an exception. </exception> public static async Task <bool> UseTransport( int transportId, WoWPoint startLocation, WoWPoint endLocation, WoWPoint waitAtLocation, WoWPoint standAtLocation, WoWPoint getOffLocation, MovementTypes movementType, string destination = null) { if (getOffLocation != WoWPoint.Empty && StyxWoW.Me.Location.DistanceSqr(getOffLocation) < 2 * 2) { return(false); } var transportLocation = GetTransportLocation(transportId); if (transportLocation != WoWPoint.Empty && transportLocation.DistanceSqr(startLocation) < 1.5 * 1.5 && waitAtLocation.DistanceSqr(Player.Location) < 2 * 2) { TreeRoot.StatusText = "Moving inside transport"; Navigator.PlayerMover.MoveTowards(standAtLocation); await CommonCoroutines.SleepForLagDuration(); // wait for bot to get on boat. await Coroutine.Wait(12000, () => !StyxWoW.Me.IsMoving || Navigator.AtLocation(standAtLocation)); } // loop while on transport to prevent bot from doing anything else while (StyxWoW.Me.Transport != null && StyxWoW.Me.Transport.Entry == transportId) { if (transportLocation != WoWPoint.Empty && transportLocation.DistanceSqr(endLocation) < 1.5 * 1.5) { TreeRoot.StatusText = "Moving out of transport"; Navigator.PlayerMover.MoveTowards(getOffLocation); await CommonCoroutines.SleepForLagDuration(); // Sleep until we stop moving. await Coroutine.Wait(12000, () => !StyxWoW.Me.IsMoving || Navigator.AtLocation(getOffLocation)); return(true); } // Exit loop if in combat or dead. if (StyxWoW.Me.Combat || !StyxWoW.Me.IsAlive) { return(false); } TreeRoot.StatusText = "Waiting for the end location"; await Coroutine.Yield(); // update transport location. transportLocation = GetTransportLocation(transportId); } if (waitAtLocation.DistanceSqr(Player.Location) > 2 * 2) { var _movement = new Movement(waitAtLocation, 2f, name: "TransportWaitAtLocation", checkStuck: false); if (movementType == MovementTypes.ClickToMove) { await _movement.ClickToMove(); } else { await _movement.MoveTo(); } return(true); } await CommonCoroutines.LandAndDismount(); TreeRoot.StatusText = "Waiting for transport"; return(true); }
/// <summary> /// Uses the transport. /// </summary> /// <param name="transportId">The transport identifier.</param> /// <param name="transportStartLoc">The start location.</param> /// <param name="transportEndLoc">The end location.</param> /// <param name="waitAtLoc">The wait at location.</param> /// <param name="boardAtLoc">The stand at location.</param> /// <param name="getOffLoc">The get off location.</param> /// <param name="movement">The movement.</param> /// <param name="destination">The destination.</param> /// <param name="navigationFailedAction"> /// The action to take if <paramref name="waitAtLoc" /> cant be navigated to /// </param> /// <returns>returns <c>true</c> until done</returns> /// <exception cref="Exception">A delegate callback throws an exception. </exception> public static async Task <bool> UseTransport( int transportId, Vector3 transportStartLoc, Vector3 transportEndLoc, Vector3 waitAtLoc, Vector3 boardAtLoc, Vector3 getOffLoc, MovementByType movement = MovementByType.FlightorPreferred, string destination = null, Action navigationFailedAction = null) { if (getOffLoc != Vector3.Zero && Me.Location.DistanceSquared(getOffLoc) < 2 * 2) { return(false); } var transportLocation = GetTransportLocation(transportId); if (transportLocation != Vector3.Zero && transportLocation.DistanceSquared(transportStartLoc) < 1.5 * 1.5 && waitAtLoc.DistanceSquared(Me.Location) < 2 * 2) { TreeRoot.StatusText = "Moving inside transport"; Navigator.PlayerMover.MoveTowards(boardAtLoc); await CommonCoroutines.SleepForLagDuration(); // wait for bot to get on boat. await Coroutine.Wait(12000, () => !Me.IsMoving || Navigator.AtLocation(boardAtLoc)); } // loop while on transport to prevent bot from doing anything else while (Me.Transport != null && Me.Transport.Entry == transportId) { if (transportLocation != Vector3.Zero && transportLocation.DistanceSquared(transportEndLoc) < 1.5 * 1.5) { TreeRoot.StatusText = "Moving out of transport"; Navigator.PlayerMover.MoveTowards(getOffLoc); await CommonCoroutines.SleepForLagDuration(); // Sleep until we stop moving. await Coroutine.Wait(12000, () => !Me.IsMoving || Navigator.AtLocation(getOffLoc)); return(true); } // Exit loop if in combat or dead. if (Me.Combat || !Me.IsAlive) { return(false); } TreeRoot.StatusText = "Waiting for the end location"; await Coroutine.Yield(); // update transport location. transportLocation = GetTransportLocation(transportId); } if (waitAtLoc.DistanceSquared(Me.Location) > 2 * 2) { if (!await MoveTo(waitAtLoc, destination ?? waitAtLoc.ToString(), movement)) { navigationFailedAction?.Invoke(); } return(true); } await CommonCoroutines.LandAndDismount(); TreeRoot.StatusText = "Waiting for transport"; return(true); }
private async Task <bool> KoMloop() { if (StyxWoW.IsInWorld) { Mon(); if ((IsPlayerInRange && St >= 20) || Stc >= 3) { Hearth = true; } if (Hearth) { Logging.WriteDiagnostic("ST: {0} - IsPlayerInRange: {1} - STC: {2} - STF: {3}", St, IsPlayerInRange, Stc, Stf); // ReSharper disable once RedundantArgumentDefaultValue await CommonCoroutines.LandAndDismount(null, true); await CommonCoroutines.StopMoving(); if (GHs != null && StyxWoW.Me.CurrentMap.ExpansionId == 5) { if (GHs.CooldownTimeLeft > TimeSpan.Zero) { await Coroutine.Wait(1200000, () => GHs.CooldownTimeLeft == TimeSpan.Zero); } } else if (Hs != null) { if (Hs.CooldownTimeLeft > TimeSpan.Zero) { await Coroutine.Wait(1800000, () => Hs.CooldownTimeLeft == TimeSpan.Zero); } } else { CLog("... Couldn't do my job as no Hearthstone is available"); TreeRoot.Shutdown(); } var currentMapId = StyxWoW.Me.MapId; while ((Hs != null || GHs != null) && currentMapId == StyxWoW.Me.MapId && !StyxWoW.Me.IsActuallyInCombat && StyxWoW.Me.IsAlive && !StyxWoW.Me.HasAura(15007)) { if (GHs != null && StyxWoW.Me.CurrentMap.ExpansionId == 5) { GHs.Interact(); } else if (Hs != null) { Hs.Interact(); } await Coroutine.Sleep(1000); await Coroutine.Wait(30000, () => (StyxWoW.Me.MapId != currentMapId || !StyxWoW.Me.IsCasting) && StyxWoW.Me.IsValid); await Coroutine.Sleep(2500); } if (ProfileManager.XmlLocation.ToLower().Contains("questing profile pack")) { _kickz = false; for (var i = 0; i <= _qdirs.Length - 1; i++) { if (ProfileManager.XmlLocation.ToLower().Contains(_qdirs[i])) { ProfileManager.LoadNew(Path.Combine(Path.GetDirectoryName(ProfileManager.XmlLocation), "..\\Auto Loader - v2.xml")); _kickz = true; } } if (!_kickz) { ProfileManager.LoadNew(ProfileManager.XmlLocation); } } else { ProfileManager.LoadNew(ProfileManager.XmlLocation); } await Coroutine.Sleep(2500); Def(1); return(true); } if (Moving && St >= BeginUnstuck && !Stuck && Ts > 2) { Motionless = false; Reset = false; Plog = true; Slog = true; Stuck = true; Stc = DateTime.Now.Subtract(Ustime).TotalSeconds <= 30 && Fs ? Stc + 1 : Stc; if (Stf >= 3) { Hearth = true; } Sp = StyxWoW.Me.Location; Mpos = Lua.GetReturnVal <string>( "x,y=GetPlayerMapPosition('player');return format('%.1f - %.1f',100*x, 100*y)", 0); } if (Sp.Distance(StyxWoW.Me.Location) > Df * 7 && Stuck) { if (Lsp.Distance(StyxWoW.Me.Location) > Stf * Df * 12 || !Fs) { Fs = !Fs ? true : Fs; Stf = Lsp.Distance(Sp) <= Stf * Df * 10 && Fs ? Stf + 0.5 : 1; Ustime = DateTime.Now; Def(0); await CommonCoroutines.StopMoving(); } } if (!Moving && !Motionless && Ts > 210) { Motionless = true; } if (Reset && Rt < 30) { return(false); } if (Stuck) { Unstuck(); return(true); } if (Motionless) { Bbm(); return(true); } return(false); } return(false); }
/// <summary> /// <para>Uses the hearthstone.</para> /// <para>Dismounts if mounted and stops moving before attempting to cast hearthstone. </para> /// <para>Does not yield until hearthstone is casted unless it can't be casted, already in hearthstone area or cast failed. </para> /// </summary> /// <param name="useGarrisonHearthstone">Use garrison hearthstone if set to <c>true</c>.</param> /// <param name="inHearthAreaAction">The action to take if already in hearthstone area.</param> /// <param name="noHearthStoneInBagsAction">The action to take if no hearthstone is in bags.</param> /// <param name="hearthNotSetAction">The action to take if hearth is not set.</param> /// <param name="hearthOnCooldownAction">The action to take if hearth is on cooldown.</param> /// <param name="hearthCastedAction">The action to take if hearth is successfully casted.</param> /// <param name="hearthCastFailedAction">The action to take if hearth failed to cast. The reason string is passed in argument.</param> /// <returns>Returns <c>true</c> if hearth was casted</returns> /// <exception cref="Exception">A delegate callback throws an exception.</exception> public static async Task <bool> UseHearthStone( bool useGarrisonHearthstone = false, Action inHearthAreaAction = null, Action noHearthStoneInBagsAction = null, Action hearthNotSetAction = null, Action hearthOnCooldownAction = null, Action hearthCastedAction = null, Action <string> hearthCastFailedAction = null) { if (IsInHearthStoneArea(useGarrisonHearthstone)) { if (inHearthAreaAction != null) { inHearthAreaAction(); } else { QBCLog.DeveloperInfo("Already at hearthstone area"); } return(false); } var hearthStones = useGarrisonHearthstone ? GetHearthStonesByIds(ItemId_GarrisonHearthStoneId) : GetHearthStonesByIds(ItemId_HearthStoneId, ItemId_TheInnkeepersDaughter); if (!hearthStones.Any()) { if (noHearthStoneInBagsAction != null) { noHearthStoneInBagsAction(); } else { QBCLog.DeveloperInfo("No hearthstone found in bag"); } return(false); } if (!useGarrisonHearthstone && Me.HearthstoneAreaId == 0) { // I can only see this occurring if using the Innkeeper's Daughter hearthtone since the normal hearthstone // only shows up in bags if hearth has been set. if (hearthNotSetAction != null) { hearthNotSetAction(); } else { QBCLog.DeveloperInfo("Hearth has not been set"); } return(false); } var usableHearthstone = hearthStones.FirstOrDefault(i => !i.Effects.First().Spell.Cooldown); if (usableHearthstone == null) { if (hearthOnCooldownAction != null) { hearthOnCooldownAction(); } else { QBCLog.DeveloperInfo("Hearth is on cooldown"); } return(false); } // the following coroutines execute sequentially, they do not return until dismounted or movement has stopped. await CommonCoroutines.LandAndDismount(); await CommonCoroutines.StopMoving(); // Close any frame that can prevent hearthstone use... // For example WoW will try to sell to hearthstone if merchant frame is open when hearthstone is used await CloseFrames(); var hearthstoneSpell = usableHearthstone.Effects.First().Spell; using (var castMonitor = SpellCastMonitor.Start(hearthstoneSpell.Id)) { QBCLog.DeveloperInfo("Using hearthstone: {0}", hearthstoneSpell.Name); usableHearthstone.Use(); var castResult = await castMonitor.GetResult(12000); if (castResult == SpellCastResult.Succeeded) { await Coroutine.Wait(2000, () => IsInHearthStoneArea(useGarrisonHearthstone)); if (hearthCastedAction != null) { hearthCastedAction(); } else { QBCLog.DeveloperInfo("Successfully used hearthstone"); } return(true); } string reason = castResult == SpellCastResult.UnknownFail ? castMonitor.FailReason : castResult.ToString(); if (hearthCastFailedAction != null) { hearthCastFailedAction(reason); } else { QBCLog.Warning("Cast of {0} failed. Reason: {1}", hearthstoneSpell.Name, reason); } return(false); } }