internal static void Pulse() { if (!StyxWoW.Me.GotAlivePet) { PetSpells.Clear(); return; } if (StyxWoW.Me.Mounted) { _wasMounted = true; } if (_wasMounted && !StyxWoW.Me.Mounted) { _wasMounted = false; PetTimer.Reset(); } if (StyxWoW.Me.Pet != null && _petGuid != StyxWoW.Me.Pet.Guid) { _petGuid = StyxWoW.Me.Pet.Guid; PetSpells.Clear(); // Cache the list. yea yea, we should just copy it, but I'd rather have shallow copies of each object, rather than a copy of the list. PetSpells.AddRange(StyxWoW.Me.PetSpells); PetTimer.Reset(); } }
internal static Composite CreateKitingBehavior() { return (new Decorator( ctx => BelphegorSettings.Instance.Kiting.IsKitingActive, new Sequence( new Action(ctx => RegenerateCache(MinimumDistance, (CombatContext)ctx)), new PrioritySelector( new Decorator( ctx => CheckTimer.IsFinished && _currentTargetPoint == Vector3.Zero && NeedsToGetGround, new Action( ctx => { Log.Info("Kiting behavior started."); _currentTargetPoint = ((CombatContext)ctx).PlayerPosition. GeneratePossibleTargetPointsInHalfCircleFacingAwayFromTarget( (CombatContext)ctx, ((CombatContext)ctx).TargetPosition, MaximumDistance - MinimumDistance). FirstOrDefault( p => ((CombatContext)ctx).UnitPositions.CachedPositions.Any( cp => cp.Position.DistanceSqr(p) < BelphegorSettings.Instance.Kiting.AggroRange * BelphegorSettings.Instance.Kiting.AggroRange)); if (_currentTargetPoint == Vector3.Zero) { Log.Info("Kiting failed to find target spot."); CheckTimer.Reset(); return RunStatus.Success; } Log.Info("Kiting target position found."); return RunStatus.Failure; } ) ), new Decorator( ctx => (_currentTargetPoint != Vector3.Zero && (_currentTargetPoint.DistanceSqr(((CombatContext)ctx).PlayerPosition) < 4f * 4f || _currentTargetPoint.DistanceSqr(((CombatContext)ctx).PlayerPosition) > (MaximumDistance - MinimumDistance) * (MaximumDistance - MinimumDistance))) || ZetaDia.Me.Movement.StuckFlags.HasFlag(StuckFlags.WasStuck), new Action(ret => { _currentTargetPoint = Vector3.Zero; CheckTimer.Reset(); Log.Info("Kiting behavior finished."); }) ), new Decorator( ctx => _currentTargetPoint != Vector3.Zero, CommonBehaviors.MoveAndStop(ret => _currentTargetPoint, 4f, true, "Kiting Position") ) ) ) )); }
public async Task <bool> Run() { if (_moveTimer.IsFinished && Poi.Current != null && Poi.Current.Type != PoiType.None) { List <Vector3> path = StraightPathHelper.RealStraightPath(); Logger.Info("Dump path:"); foreach (Vector3 x in path) { Logger.Info(x.ToString()); } Logger.Warn( "No activity was detected for {0} seconds. Adding target {1} to the blacklist and trying again", _moveTimer.WaitTime.TotalSeconds, Poi.Current); if (Poi.Current.Unit != null) { DDTargetingProvider.Instance.AddToBlackList(Poi.Current.Unit, TimeSpan.FromSeconds(30), "Navigation Error"); } if (Poi.Current.Type != PoiType.None) { Poi.Clear("No activity detected (not none): PoiType: " + Poi.Current.Type); } if (Poi.Current.Type != PoiType.Wait) { Poi.Clear("No activity detected (not wait): PoiType: " + Poi.Current.Type); } if (Poi.Current.Type == PoiType.Quest) { Poi.Clear("No activity detected (not wait): PoiType: " + Poi.Current.Type); } GameObjectManager.Update(); Navigator.Clear(); _moveTimer.Reset(); return(true); } if (_moveTimer.IsFinished) { Logger.Warn("No activity was detected for {0} seconds. Clearing Navigator?", _moveTimer.WaitTime.TotalSeconds); await CommonTasks.StopMoving(); Navigator.Clear(); _moveTimer.Reset(); return(true); } return(false); }
public static async Task OffMeshMove(Vector3 _target) { waitTimer_0.Reset(); Navigator.PlayerMover.MoveTowards(_target); while (_target.Distance2D(Core.Me.Location) >= 4 && !waitTimer_0.IsFinished) { Navigator.PlayerMover.MoveTowards(_target); await Coroutine.Sleep(100); } Navigator.PlayerMover.MoveStop(); }
static PetManager() { // NOTE: This is a bit hackish. This fires VERY OFTEN in major cities. But should prevent us from summoning right after dismounting. // Lua.Events.AttachEvent("COMPANION_UPDATE", (s, e) => CallPetTimer.Reset()); // Note: To be changed to OnDismount with new release Mount.OnDismount += (s, e) => { if (StyxWoW.Me.Class == WoWClass.Hunter || StyxWoW.Me.Class == WoWClass.Warlock || StyxWoW.Me.PetNumber > 0) { PetSummonAfterDismountTimer.Reset(); } }; }
public override void OnEnable() { Lua.Events.AttachEvent("DELETE_ITEM_CONFIRM", DeleteItemConfirmPopup); Lua.Events.AttachEvent("MERCHANT_SHOW", SellVenderItems); Lua.Events.AttachEvent("LOOT_CLOSED", LootEnded); Lua.DoString("SetCVar('AutoLootDefault','1')"); InitialMirLoad(); MrItemRemover2Settings.Instance.Load(); PrintSettings(); _checkTimer.Reset(); //should start the timer IsInitialized = true; }
private async Task <bool> NotStarted() { var zDiff = Math.Abs((float)(Destination.Z - AdvDia.MyPosition.Z)); var distanceToDestination = AdvDia.MyPosition.Distance(Destination); //if (PluginEvents.CurrentProfileType == ProfileType.Rift && // distanceToDestination < 50f && zDiff < 3 && // Core.Grids.CanRayWalk(AdvDia.MyPosition, Destination)) //{ // _mover = Mover.StraightLine; // _lastRaywalkCheck = PluginTime.CurrentMillisecond; // Navigator.PlayerMover.MoveTowards(Destination); //} //else //{ // _mover = Mover.Navigator; //} //// Intercept destinations that require a gate to be used to reach them, and redirect to gate position. //if (DeathGates.IsInDeathGateWorld) //{ // var gatePosition = DeathGates.GetBestGatePosition(_destination); // if (DeathGates.IsInOutsideRegion && !IsDeathGateIgnored(gatePosition, _deathGateIgnoreList)) // { // Core.Logger.Debug($"Moving to use Death Gate (Currently in Outside Region) {gatePosition} Dist: {gatePosition.Distance(AdvDia.MyPosition)}"); // _deathGatePosition = gatePosition; // State = States.MovingToDeathGate; // _pathGenetionTimer.Reset(); // return false; // } // var destinationIsGate = _destination.Distance(gatePosition) < 5f; // if (destinationIsGate) // { // Core.Logger.Debug($"Current Destination is Death Gate. {gatePosition} Dist: {gatePosition.Distance(AdvDia.MyPosition)}"); // _deathGatePosition = gatePosition; // State = States.MovingToDeathGate; // _pathGenetionTimer.Reset(); // return false; // } //} Core.Logger.Debug("{0} {1} (Distance: {2})", (_mover == Mover.StraightLine ? "Moving towards" : "Moving to"), Destination, distanceToDestination); State = States.Moving; _pathGenetionTimer.Reset(); return(false); }
// does nothing if no baits are in bag public async static Task <bool> Applybait() { if (StyxWoW.Me.IsCasting || IsBait) { return(false); } if (!BaitRecastTimer.IsFinished) { return(false); } BaitRecastTimer.Reset(); var mainHand = StyxWoW.Me.Inventory.Equipped.MainHand; if (mainHand == null || mainHand.ItemInfo.WeaponClass != WoWItemWeaponClass.FishingPole) { return(false); } foreach (var baitInBag in GetBaits()) { if (baitInBag != null && baitInBag.Use()) { AutoAnglerBot.Log("Applying bait: {0}", baitInBag.GetItemName()); await CommonCoroutines.SleepForLagDuration(); return(true); } } return(false); }
public async Task <bool> GetCoroutine() { CoroutineCoodinator.Current = this; SafeZerg.Instance.DisableZerg(); if (_waitTimer == null) { _waitTimer = new WaitTimer(_waitTime); _waitTimer.Reset(); string status = $"[Wait] Waiting for {_waitTime.TotalSeconds} seconds"; StatusText = status; Core.Logger.Debug(status); } if (ZetaDia.Globals.WorldSnoId != _worldId) { StatusText = "[Wait] Stopped waiting because world id is not correct"; Core.Logger.Debug(StatusText); _isDone = true; return(true); } if (!_waitTimer.IsFinished) { return(false); } _isDone = true; return(true); }
public override void Initialize() { if (!Styx.StyxWoW.IsInGame) { return; } if (Me.Class != WoWClass.Rogue) { return; } // Temp Looting Fix BotEvents.Player.OnMobKilled += e => { WoWMovement.MoveStop(); StyxWoW.SleepForLagDuration(); }; // Temp Skinning Fix BotEvents.Player.OnMobLooted += e => { WoWMovement.MoveStop(); StyxWoW.SleepForLagDuration(); }; slog("Indexing Talent Trees"); Talents = new TalentManager(); slog("Calculating Talent Trees"); TalentSpec = Talents.GetSpec(); slog("Determined " + TalentSpec + " as your spec."); _specRefresh.Reset(); slog("v" + wRogueVersion + " By wired420 Loaded"); slog("Checking for Updates"); Update(); }
public static Composite DemonHunterBuffs() { return (new PrioritySelector(CtxChanger, Common.CreateWaitForAttack(), Common.CreateWaitForCast(), Common.CreateGetPowerGlobe(), Common.CreateUsePoolOfReflection(), new SelfCast(SNOPower.X1_DemonHunter_Companion, ctx => CompanionTimer.IsFinished && !Minion.HasPet(((CombatContext)ctx), Pet.DH_Companion), s => CompanionTimer.Reset()), new SelfCast(SNOPower.DemonHunter_Chakram, extra => BelphegorSettings.Instance.DemonHunter.ShurikenCloud && ShurikenCloudTimer.IsFinished, s => ShurikenCloudTimer.Reset()), new SelfCast(SNOPower.DemonHunter_SmokeScreen, extra => SmokeScreenTimer.IsFinished && ZetaDia.Me.HitpointsCurrentPct <= BelphegorSettings.Instance.DemonHunter .SmokeScreenHP || BelphegorSettings.Instance.DemonHunter.SpamSmokeScreen, s => SmokeScreenTimer.Reset()), Avoidance.CreateMoveForAvoidance( BelphegorSettings.Instance.DemonHunter.MaximumRange) )); }
// Pulse event method public void OnPulse() { // Wait some more if our timers are still going if (!LevelUpTimer.IsFinished || !SetSkillTimer.IsFinished) { return; } // Don't do anything if we're dead or switching worlds if (!ZetaDia.IsInGame || !Zeta.Game.ZetaDia.Me.IsValid || !ZetaDia.CPlayer.IsValid || Zeta.Game.ZetaDia.Me.IsDead || ZetaDia.IsLoadingWorld) { return; } // Don't do anything if we're in combat if (Zeta.Game.ZetaDia.Me.IsInCombat) { return; } if (SkillEquipQueue.Count > 0) { Skill skillToEquip = SkillEquipQueue[0]; if (skillToEquip.activate()) { Log(skillToEquip.getSnoPower().ToString() + "(" + skillToEquip.getRuneId() + ") has been set"); // Remove it from list SkillEquipQueue.Remove(skillToEquip); } SetSkillTimer.Reset(); } }
private async Task <bool> NotStarted() { _timeout.Reset(); SafeZerg.Instance.DisableZerg(); State = States.Searching; return(false); }
/// <summary> /// Creates a behavior for using potions. /// </summary> /// <returns></returns> /// <remarks>Created 2012-07-11</remarks> public static Composite CreateUsePotion() { return (new Decorator( ret => PotionCooldownTimer.IsFinished && ((CombatContext)ret).CurrentHealthPercentage <= BelphegorSettings.Instance.HealthPotionPct, new PrioritySelector(ctx => BestPotion, new Decorator(ctx => ctx != null, new Sequence( new Action( ctx => ZetaDia.Me.Inventory.UseItem(((ACDItem)ctx).DynamicId)), new Action(ctx => PotionCooldownTimer.Reset()), new Action( ctx => Logger.Write( "Potion set to use below {0}%, my health is currently {1}%, using {2}", 100 * BelphegorSettings.Instance.HealthPotionPct, Math.Round(100 * ZetaDia.Me.HitpointsCurrentPct), ((ACDItem)ctx).Name)) ) ) ) )); }
/// <summary> /// Creates a behavior for using potions. /// </summary> /// <returns></returns> /// <remarks>Created 2012-07-11</remarks> public static Composite CreateUsePotion() { return (new Decorator( ret => PotionCooldownTimer.IsFinished && ((CombatContext)ret).CurrentHealthPercentage <= BelphegorSettings.Instance.HealthPotionPct, new PrioritySelector(ctx => HealthPotion, new Decorator(ctx => ctx != null, new Action( ctx => { ZetaDia.Me.Inventory.UseItem(((ACDItem)ctx).DynamicId); PotionCooldownTimer.Reset(); Log.InfoFormat( "Using {0}, Health is {1}/{2}", ((ACDItem)ctx).Name, 100 * BelphegorSettings.Instance.HealthPotionPct, Math.Round(100 * ZetaDia.Me.HitpointsCurrentPct), ((ACDItem)ctx).Name); return RunStatus.Success; }) ) ) )); }
public static Composite DemonHunterMovement() { return(new PrioritySelector( Common.CreateWaitForAttack(), Common.CreateWaitForCast(), new SelfCast(SNOPower.DemonHunter_Preparation, ctx => BelphegorSettings.Instance.DemonHunter.UsePreparationForMovement), new SelfCast(SNOPower.DemonHunter_ShadowPower, ctx => BelphegorSettings.Instance.DemonHunter.UseShadowPowerForMovement && !ZetaDia.Me.HasBuff(SNOPower.DemonHunter_ShadowPower)), new CastAtLocation(SNOPower.DemonHunter_Vault, ctx => (Vector3)ctx, ctx => BelphegorSettings.Instance.DemonHunter.UseVaultForMovement && ZetaDia.Me.CurrentSecondaryResource > BelphegorSettings.Instance.DemonHunter.VaultDiscipline && VaultMovementTimer.IsFinished && ZetaDia.Me.Position.Distance((Vector3)ctx) > BelphegorSettings.Instance.DemonHunter.VaultDistance, s => VaultMovementTimer.Reset()), new Action(ret => { ZetaDia.Me.Movement.MoveActor((Vector3)ret); return RunStatus.Success; }) )); }
public async Task <bool> Run() { if (Target.Type != PoiType.Wait) { return(false); } //let the navigator handle movement if we are far away if (Target.Location.Distance2D(Core.Me.Location) > 3) { return(false); } // move closer plz if (Target.Location.Distance2D(Core.Me.Location) >= 2) { await CommonTasks.MoveAndStop(new MoveToParameters(Target.Location, "Floor Exit"), 0.5f, true); return(true); } await CommonTasks.StopMoving(); int _level = DeepDungeonManager.Level; _moveTimer.Reset(); await Coroutine.Wait(-1, () => Core.Me.InCombat || _level != DeepDungeonManager.Level || CommonBehaviors.IsLoading || QuestLogManager.InCutscene || _moveTimer.IsFinished); if (_moveTimer.IsFinished) { if (Poi.Current.Unit != null) { if (!Poi.Current.Unit.IsValid) { Logger.Debug("Waited 5 minutes at exit: Blacklisting current exit for 10min not valid"); DDTargetingProvider.Instance.AddToBlackList(Poi.Current.Unit, TimeSpan.FromMinutes(10), "Waited at exit(not valid) for 5 minutes"); } else { Logger.Debug("Waited 5 minutes at exit: Blacklisting current exit for 5 min"); DDTargetingProvider.Instance.AddToBlackList(Poi.Current.Unit, TimeSpan.FromMinutes(5), "Waited at exit for 5 minutes"); } } else { Logger.Debug("Waited 5 minutes at exit but poi is null"); } blackList.Add(location); } GameObjectManager.Update(); location = Vector3.Zero; Poi.Clear("Floor has changed or we have entered combat"); Navigator.Clear(); return(true); }
/* * private long LastTick { get; set; } */ private static Composite CreateBehaviorLogic() { return(new PrioritySelector( Move.NeedMove(), // Move.CompositeJumpMeele(), // .. logic for behavior tree goes here .. new Action(r => { if (WaitNextMessage.IsFinished) { WaitNextMessage.Reset(); var obj = ObjectManager.GetObjectsOfTypeFast <WoWGameObject>() .Where(ob => ob.IsValid) .OrderBy(od => od.Distance) .FirstOrDefault(); var unit = ObjectManager.GetObjectsOfTypeFast <WoWPlayer>() .Where(player => player.IsValid && player.IsAlliance) .OrderBy(p => p.Distance) .FirstOrDefault(); if (obj != null) { var list = obj.GetType().GetProperties().Select(w => w.Name + " - " + w.GetValue(obj)); var list3 = list.ToList(); var list2 = obj.GetType().GetFields().Select(w => w.Name + " - " + w.GetValue(obj)); list3.AddRange(list2); var file = list3.Find(p => p.Contains("Entry")) ?? list3.Find(p => p.Contains("DescriptorGuid ")); file = file.Remove(0, file.LastIndexOf(' ') + 1); if (File.Exists("BASE\\" + file + ".xml")) { return; } SaveIdList("BASE\\" + file + ".xml", list3.ToList()); Logging.Write("Добавили {0} {1}", obj.Name, obj.Entry); } if (unit != null) { AlertWisper(); var list = unit.GetType().GetProperties().Select(w => w.Name + " - " + w.GetValue(unit)); var list3 = list.ToList(); var list2 = unit.GetType().GetFields().Select(w => w.Name + " - " + w.GetValue(unit)); list3.AddRange(list2); var file = list3.Find(p => p.Contains("Name")) ?? list3.Find(p => p.Contains("SafeName")); file = file.Remove(0, file.LastIndexOf(' ') + 1); if (File.Exists("BASE\\" + file + ".xml")) { return; } SaveIdList("BASE\\" + file + ".xml", list3.ToList()); Logging.Write("Добавили {0} {1}", unit.Name, unit.SafeName); } //Logging.Write(Colors.White, "[ImpMove] activity message " + DateTime.Now); } }) )); }
public static bool CheckStuck() { if (Player.Location.Distance(_lastPlayerPos) > 2f) { _lastPlayerPos = Player.Location; _lastMoved = DateTime.Now; _stuckWaitTimer.Reset(); return(false); } if (_stuckWaitTimer.IsFinished) { return(true); } return(false); }
private Composite FlaskBot() { return(new PrioritySelector( new Decorator(ret => _flaskCd.IsFinished && Variables.Me.HealthPercent < Settings.Instance.PotHealth && Variables.LifeFlasks.Count() != 0 && !Variables.Me.HasAura("flask_effect_life"), new Action(ret => { Variables.LifeFlasks.First().Use(); _flaskCd.Reset(); })), new Decorator(ret => _flaskCd.IsFinished && Variables.Me.ManaPercent < Settings.Instance.PotMana && Variables.ManaFlasks.Count() != 0 && !Variables.Me.HasAura("flask_effect_mana"), new Action(ret => { Variables.ManaFlasks.First().Use(); _flaskCd.Reset(); })) )); }
// does nothing if no lures are in bag public async static Task <bool> Applylure() { if (StyxWoW.Me.IsCasting || IsLureOnPole) { return(false); } if (!LureRecastTimer.IsFinished) { return(false); } LureRecastTimer.Reset(); var mainHand = StyxWoW.Me.Inventory.Equipped.MainHand; if (mainHand == null || mainHand.ItemInfo.WeaponClass != WoWItemWeaponClass.FishingPole) { return(false); } // Ancient Pandaren Fishing Charm WoWItem ancientPandarenFishingCharm = StyxWoW.Me.BagItems .FirstOrDefault(r => r.Entry == AncientPandarenFishingCharmItemId); if (ancientPandarenFishingCharm != null && !StyxWoW.Me.HasAura(AncientPandarenFishingCharmAuraId)) { AutoAnglerBot.Log("Appling Ancient Pandaren Fishing Charm lure"); ancientPandarenFishingCharm.Use(); await CommonCoroutines.SleepForLagDuration(); return(true); } // Fishing Hats WoWItem head = StyxWoW.Me.Inventory.Equipped.Head; if (head != null && Utility.FishingHatIds.Any(hat => hat == head.Entry && hat != 118393)) // Checking for Draenor tentacle hat { AutoAnglerBot.Log("Appling Fishing Hat lure to fishing pole"); head.Use(); await CommonCoroutines.SleepForLagDuration(); return(true); } foreach (var kv in Lures) { WoWItem lureInBag = Utility.GetItemInBag(kv.Key); if (lureInBag != null && lureInBag.Use()) { AutoAnglerBot.Log("Appling {0} to fishing pole", kv.Value); await CommonCoroutines.SleepForLagDuration(); return(true); } } return(false); }
private void AntiAfk() { if (!_afkTimer.IsFinished) { return; } WoWMovement.Move(WoWMovement.MovementDirection.JumpAscend, TimeSpan.FromMilliseconds(100)); _afkTimer.Reset(); }
static private void AnitAfk() { // keep the bot from going afk. if (AntiAfkTimer.IsFinished) { StyxWoW.ResetAfk(); AntiAfkTimer.Reset(); } }
/// <summary> Updates this object. </summary> /// <remarks> Nesox, 2013-10-02. </remarks> public static void Update() { if (!UpdateTimer.IsFinished) { return; } using (new PerformanceLogger(BelphegorSettings.Instance.Debug.IsDebugHotbarCacheLog, "HotbarUpdate")) { if (!ZetaDia.IsInGame || ZetaDia.IsLoadingWorld || ZetaDia.Me == null || ZetaDia.Me.CommonData == null) { return; } UpdateTimer.Reset(); _powers.Clear(); var slots = new[] { HotbarSlot.HotbarMouseLeft, HotbarSlot.HotbarMouseRight, HotbarSlot.HotbarSlot1, HotbarSlot.HotbarSlot2, HotbarSlot.HotbarSlot3, HotbarSlot.HotbarSlot4 }; foreach (HotbarPower hotbarPower in slots.Select(slot => new HotbarPower(slot))) { _powers.Add(hotbarPower); if (BelphegorSettings.Instance.Debug.IsDebugHotbarCacheLog) { Log.DebugFormat("Added Power:{0} RuneIndex:{1}", hotbarPower.Power, hotbarPower.RuneIndex); } } if (HasPower(SNOPower.Wizard_Archon)) { if (BelphegorSettings.Instance.Debug.IsDebugHotbarCacheLog) { Log.Debug("Found Archon manually adding skills"); } _powers.Add(new HotbarPower(SNOPower.Wizard_Archon_ArcaneBlast, 0)); _powers.Add(new HotbarPower(SNOPower.Wizard_Archon_ArcaneStrike, 0)); _powers.Add(new HotbarPower(SNOPower.Wizard_Archon_DisintegrationWave, 0)); if (HasRune(SNOPower.Wizard_Archon, 1)) { _powers.Add(new HotbarPower(SNOPower.Wizard_Archon_SlowTime, 0)); } if (HasRune(SNOPower.Wizard_Archon, 2)) { _powers.Add(new HotbarPower(SNOPower.Wizard_Archon_Teleport, 0)); } } } }
protected Composite CreateEnsureTarget() { return (new PrioritySelector( new Decorator( ret => NeedTankTargeting && targetingTimer.IsFinished && Me.Combat && TankTargeting2.Instance.FirstUnit != null && Me.CurrentTarget != TankTargeting2.Instance.FirstUnit, new Action( ret => { Logging.WriteDebug("Targeting first unit of TankTargeting"); TankTargeting2.Instance.FirstUnit.Target(); StyxWoW.SleepForLagDuration(); targetingTimer.Reset(); })), new Decorator( ret => Me.CurrentTarget == null || Me.CurrentTarget.Dead || Me.CurrentTarget.IsFriendly, new PrioritySelector( ctx => { if (Me.IsInInstance) { return null; } if (RaFHelper.Leader != null && RaFHelper.Leader.Combat) { return RaFHelper.Leader.CurrentTarget; } if (Targeting.Instance.FirstUnit != null && Me.Combat) { return Targeting.Instance.FirstUnit; } var units = ObjectManager.GetObjectsOfType <WoWUnit>(false, false).Where( p => p.IsHostile && !p.IsOnTransport && !p.Dead && p.DistanceSqr <= 70 * 70 && p.Combat); if (Me.Combat && units.Any()) { return units.OrderBy(u => u.DistanceSqr).FirstOrDefault(); } return null; }, new Decorator( ret => ret != null, new Sequence( new Action(ret => Logging.Write("Target is invalid. Switching to " + Extensions.SafeName((WoWUnit)ret) + "!")), new Action(ret => ((WoWUnit)ret).Target()))), new Decorator( ret => Me.CurrentTarget != null, new Action( ret => { Me.ClearTarget(); return RunStatus.Failure; })))))); }
private void OnPulse(object sender, EventArgs e) { if (_pulseTimer.IsFinished) { _pulseTimer.Stop(); Scans(); _pulseTimer.Reset(); } }
protected Composite CreateBehavior_QuestbotMain() { return(_root ?? (_root = new PrioritySelector( new Decorator( ret => !_isBehaviorDone, new PrioritySelector( new Decorator(ret => Me.QuestLog.GetQuestById((uint)QuestId) != null && Me.QuestLog.GetQuestById((uint)QuestId).IsCompleted, new Sequence( new Action(ret => TreeRoot.StatusText = "Finished!"), new WaitContinue(120, new Action(delegate { _isBehaviorDone = true; return RunStatus.Success; })) )), new Decorator( ret => KillUnit == null, new Action(ret => TreeRoot.StatusText = String.Format("Waiting for {0} to Spawn", KillSheya ? "Sheya" : "Lorenth")) ), new Decorator( ret => StyxWoW.Me.HasAura("Unstable Lightning Blast") && s_timer.IsFinished, new Sequence( new Action(ret => s_timer.Reset()), new Action(ret => s_moveTimer.Reset()), new Action(ret => WoWMovement.Move(WoWMovement.MovementDirection.StrafeLeft)))), new Decorator( ret => (StyxWoW.Me.IsMoving && KillSheya) || (StyxWoW.Me.IsMoving && !KillSheya && s_moveTimer.IsFinished), new Sequence( new Action(ret => WoWMovement.MoveStop()), new ActionAlwaysSucceed())), new Decorator( ret => KillUnit != null && KillUnit.Location.Distance(KillLocation) > 5, new Sequence( new Action(ret => _isBehaviorDone = true), new ActionAlwaysSucceed())), new Decorator( ret => KillUnit != null && KillUnit.Location.Distance(KillLocation) < 5 && Item != null, new Sequence( new Action(ret => KillUnit.Target()), new SleepForLagDuration(), new Action(ret => Item.UseContainerItem()), new ActionAlwaysSucceed())), new ActionAlwaysSucceed() ))))); }
public void Profile_OnUnknownProfileElement(object sender, UnknownProfileElementEventArgs e) { // hackish way to set variables to default states before loading new profile... wtb OnNewOuterProfileLoading event if (_loadProfileTimer.IsFinished) { _poolsToFish.Clear(); _pathingType = PathingType.Circle; _loadProfileTimer.Reset(); } if (e.Element.Name == "FishingSchool") { XAttribute entryAttrib = e.Element.Attribute("Entry"); if (entryAttrib != null) { uint entry; UInt32.TryParse(entryAttrib.Value, out entry); if (!_poolsToFish.Contains(entry)) { _poolsToFish.Add(entry); XAttribute nameAttrib = e.Element.Attribute("Name"); if (nameAttrib != null) { Log("Adding Pool Entry: {0} to the list of pools to fish from", nameAttrib.Value); } else { Log("Adding Pool Entry: {0} to the list of pools to fish from", entry); } } } else { Err( "<FishingSchool> tag must have the 'Entry' Attribute, e.g <FishingSchool Entry=\"202780\"/>\nAlso supports 'Name' attribute but only used for display purposes"); } e.Handled = true; } else if (e.Element.Name == "Pathing") { XAttribute typeAttrib = e.Element.Attribute("Type"); if (typeAttrib != null) { _pathingType = (PathingType) Enum.Parse(typeof(PathingType), typeAttrib.Value, true); Log("Setting Pathing Type to {0} Mode", _pathingType); } else { Err( "<Pathing> tag must have the 'Type' Attribute, e.g <Pathing Type=\"Circle\"/>"); } e.Handled = true; } }
private static void HandlePlayerDead(object sender, LuaEventArgs args) { // Since we hooked this in ctor, make sure we are the selected CC if (RoutineManager.Current.Name != SingularRoutine.Instance.Name) return; if (StyxWoW.Me.IsAlive || StyxWoW.Me.IsGhost) return; List<string> hasSoulstone = Lua.GetReturnValues("return HasSoulstone()", "hawker.lua"); if (hasSoulstone != null && hasSoulstone.Count > 0 && !String.IsNullOrEmpty(hasSoulstone[0]) && hasSoulstone[0].ToLower() != "nil") { if (MovementManager.IsMovementDisabled ) { Logger.Write(Color.Aquamarine, "Suppressing {0} behavior since movement disabled...", hasSoulstone[0]); return; } const int RezMaxMobsNear = 0; const int RezWaitTime = 10; const int RezWaitDist = 20; WaitTimer waitClearArea = new WaitTimer(TimeSpan.FromSeconds(RezWaitTime )); waitClearArea.Reset(); Logger.Write(Color.Aquamarine, "Waiting up to {0} seconds for clear area to use {1}...", RezWaitTime , hasSoulstone[0]); int countMobs; do { countMobs = (from u in Unit.NearbyUnfriendlyUnits where u.Distance < RezWaitDist select u).Count(); } while (countMobs > RezMaxMobsNear && !waitClearArea.IsFinished && !StyxWoW.Me.IsAlive && !StyxWoW.Me.IsGhost); if (StyxWoW.Me.IsGhost) { Logger.Write(Color.Aquamarine, "Insignia taken or something else released the corpse"); return; } if (StyxWoW.Me.IsAlive) { Logger.Write(Color.Aquamarine, "Ressurected by something other than Singular..."); return; } if (countMobs > RezMaxMobsNear ) { Logger.Write(Color.Aquamarine, "Still {0} enemies within {1} yds, skipping {2}", countMobs, RezWaitDist, hasSoulstone[0]); return; } Lua.DoString("UseSoulstone()"); StyxWoW.SleepForLagDuration(); } else { } }
public void Tick() { var location = Core.Me.Location; if (location.DistanceSqr(_location) > DISTANCE) { _location = location; MoveTimer.Reset(); } }
private static void HandleWorldTransfer(object sender, EventArgs e) { WorldTransferTimeoutTimer.Reset(); //Reload the profile on map change Profile current = ProfileManager.CurrentProfile; Log.DebugFormat("Reloading the profile on map change {0}", current.Name); ProfileManager.Load(current.Path); }
public async Task<bool> GetCoroutine() { SafeZerg.Instance.DisableZerg(); if (_waitTimer == null) { _waitTimer = new WaitTimer(_waitTime); _waitTimer.Reset(); Logger.Debug("[Wait] Waiting for {0} seconds", _waitTime.TotalSeconds); } if (!_waitTimer.IsFinished) return false; _isDone = true; return true; }
// =========================================================== // Inner and Anonymous Classes // =========================================================== private static void FormatAndShowTimer(string pTimerStringName) { // Create a new timer if last one has expired or we didn't have one if(!WaitTimerCreated) { foreach(var t in UIRefresher.ThrottleTimers.Where(t => t.TimerName == pTimerStringName)) { WaitTimerCreated = true; // Set up a new timer based on the amount of milliseconds in our current timer WaitTimer = new WaitTimer(new TimeSpan(0, 0, 0, 0, t.Time)); // Build the string with the proper format WaitTimerAsString = BuildTimeAsString(WaitTimer.WaitTime); WaitTimer.Reset(); } } OutputMessage(pTimerStringName); }
private async Task<bool> ReturningToTown() { DisablePulse(); if (_returningToTownbWaitTimer == null) { _returningToTownbWaitTimer = new WaitTimer(TimeSpan.FromSeconds(5)); _returningToTownbWaitTimer.Reset(); } if (!_returningToTownbWaitTimer.IsFinished) return false; if (!await TownPortalCoroutine.UseWaypoint()) return false; _returningToTownbWaitTimer = null; State = States.InTown; return false; }
public static Composite CreateBrewmasterMonkInstanceCombat() { var powerStrikeTimer = new WaitTimer(TimeSpan.FromSeconds(20)); return new PrioritySelector( Safers.EnsureTarget(), Movement.CreateMoveToLosBehavior(), Movement.CreateFaceTargetBehavior(), Helpers.Common.CreateAutoAttack(true), Helpers.Common.CreateInterruptSpellCast(ret => StyxWoW.Me.CurrentTarget), // make sure I have aggro. Spell.Cast("Provoke", ret => TankManager.Instance.NeedToTaunt.FirstOrDefault(), ret => SingularSettings.Instance.EnableTaunting), // apply the Weakened Blows debuff. Keg Smash also generates allot of threat Spell.Cast("Keg Smash", ctx => StyxWoW.Me.MaxChi - StyxWoW.Me.CurrentChi >= 2 && Clusters.GetCluster(StyxWoW.Me, Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 8).Any(u => !u.HasAura("Weakened Blows"))), Spell.CastOnGround("Dizzying Haze", ctx => TankManager.Instance.NeedToTaunt.FirstOrDefault().Location, ctx => TankManager.Instance.NeedToTaunt.Any(), false), // AOE new Decorator(ctx => Unit.NearbyUnfriendlyUnits.Count(u => u.DistanceSqr <= 8 * 8) >= 3, new PrioritySelector( // cast breath of fire to apply the dot. Spell.Cast("Breath of Fire",ctx => Clusters.GetCluster(StyxWoW.Me, Unit.NearbyUnfriendlyUnits, ClusterType.Cone, 8).Count(u =>u.HasAura("Dizzying Haze") && !u.HasAura("Breath of Fire")) >= 3), Spell.Cast("Zen Sphere", ctx => TalentManager.IsSelected((int)Common.Talents.ZenSphere) && StyxWoW.Me.HealthPercent < 90 && StyxWoW.Me.HasAura("Zen Sphere") && StyxWoW.Me.CurrentChi >= 4), // aoe stuns Spell.Cast("Charging Ox Wave", ctx => TalentManager.IsSelected((int)Common.Talents.ChargingOxWave) && Clusters.GetClusterCount(StyxWoW.Me, Unit.NearbyUnfriendlyUnits, ClusterType.Cone, 30) >= 3), Spell.Cast("Leg Sweep", ctx => TalentManager.IsSelected((int)Common.Talents.LegSweep)) )), // ***** Spend Chi ***** Spell.Cast("Rushing Jade Wind", ctx => TalentManager.IsSelected((int)Common.Talents.RushingJadeWind) &&(!StyxWoW.Me.HasAura("Shuffle") || StyxWoW.Me.Auras["Shuffle"].TimeLeft <= TimeSpan.FromSeconds(1))), Spell.Cast("Blackout Kick", ctx => !StyxWoW.Me.HasAura("Shuffle") || StyxWoW.Me.Auras["Shuffle"].TimeLeft <= TimeSpan.FromSeconds(1)), Spell.Cast("Tiger Palm", ret => StyxWoW.Me.CurrentChi >= 2 && SpellManager.HasSpell("Guard") && (!StyxWoW.Me.HasAura("Power Guard") || StyxWoW.Me.Auras["Power Guard"].StackCount < 3)), //Spell.Cast("Tiger Palm", ret => StyxWoW.Me.CurrentChi >= 2 && SpellManager.HasSpell("Blackout Kick") && (!StyxWoW.Me.HasAura("Tiger Power") || StyxWoW.Me.Auras["Tiger Power"].StackCount < 3)), Spell.BuffSelf("Purifying Brew", ctx => StyxWoW.Me.HasAura("Stagger") && StyxWoW.Me.CurrentChi >= 3), // ***** Generate Chi ***** Spell.Cast("Keg Smash", ctx => StyxWoW.Me.MaxChi - StyxWoW.Me.CurrentChi >= 2 && Unit.NearbyUnfriendlyUnits.Any(u => u.DistanceSqr <= 8 * 8)), Spell.Cast("Spinning Crane Kick", ctx => StyxWoW.Me.MaxChi - StyxWoW.Me.CurrentChi >= 1 && Unit.NearbyUnfriendlyUnits.Count(u => u.DistanceSqr <= 8 * 8) >= 3), // jab with power strike talent is > expel Harm if off CD. new Decorator(ctx => TalentManager.IsSelected((int)Common.Talents.PowerStrikes) && StyxWoW.Me.MaxChi - StyxWoW.Me.CurrentChi >= 2 && SpellManager.CanCast("Jab") && powerStrikeTimer.IsFinished, new Sequence( new Action(ctx => powerStrikeTimer.Reset()), Spell.Cast("Jab") )), Spell.Cast("Expel Harm", ctx => StyxWoW.Me.HealthPercent < 90 && StyxWoW.Me.MaxChi - StyxWoW.Me.CurrentChi >= 1 && Unit.NearbyUnfriendlyUnits.Any(u => u.DistanceSqr <= 10 * 10)), Spell.Cast("Jab", ctx => StyxWoW.Me.MaxChi - StyxWoW.Me.CurrentChi >= 1), // filler Spell.Cast("Tiger Palm", ret => !SpellManager.HasSpell("Blackout Kick") || SpellManager.HasSpell("Brewmaster Training")), TryCastClashBehavior(), //Only roll to get to the mob quicker. Spell.Cast("Roll", ret => SingularSettings.Instance.IsCombatRoutineMovementAllowed() && StyxWoW.Me.CurrentTarget.Distance.Between(10, 40)), Movement.CreateMoveToMeleeBehavior(true)); }
public static Composite CreateBrewmasterMonkInstanceCombat() { var powerStrikeTimer = new WaitTimer(TimeSpan.FromSeconds(20)); return new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), CreateCloseDistanceBehavior(), Helpers.Common.CreateAutoAttack(true), Spell.WaitForCastOrChannel(), new Decorator( req => !Spell.IsGlobalCooldown(), new PrioritySelector( Helpers.Common.CreateInterruptBehavior(), // Execute if we can Spell.Cast("Touch of Death", ret => Me.CurrentChi >= 3 && Me.HasAura("Death Note")), // make sure I have aggro. Spell.Cast("Provoke", ret => TankManager.Instance.NeedToTaunt.FirstOrDefault(), ret => SingularSettings.Instance.EnableTaunting), // highest priority -- Keg Smash for threat and debuff Spell.Cast("Keg Smash", req => Me.MaxChi - Me.CurrentChi >= 2 && Clusters.GetCluster(Me, Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 8).Any(u => !u.HasAura("Weakened Blows"))), // taunt if needed Spell.CastOnGround("Dizzying Haze", on => TankManager.Instance.NeedToTaunt.FirstOrDefault(), req => TankManager.Instance.NeedToTaunt.Any(), false), // AOE new Decorator( req => Spell.UseAOE && Unit.NearbyUnfriendlyUnits.Count(u => u.DistanceSqr <= 8 * 8) >= 3, new PrioritySelector( // cast breath of fire to apply the dot. Spell.Cast("Breath of Fire", ctx => Clusters.GetCluster(Me, Unit.NearbyUnfriendlyUnits, ClusterType.Cone, 8).Count(u => u.HasAura("Dizzying Haze") && !u.HasAura("Breath of Fire")) >= 3), Spell.Cast("Zen Sphere", ctx => TalentManager.IsSelected((int)MonkTalents.ZenSphere) && Me.HealthPercent < 90 && Me.HasAura("Zen Sphere") && Me.CurrentChi >= 4), // aoe stuns Spell.Cast("Charging Ox Wave", ctx => TalentManager.IsSelected((int)MonkTalents.ChargingOxWave) && Clusters.GetClusterCount(Me, Unit.NearbyUnfriendlyUnits, ClusterType.Cone, 30) >= 3), Spell.Cast("Leg Sweep", ctx => TalentManager.IsSelected((int)MonkTalents.LegSweep)) ) ), // ***** Spend Chi ***** Spell.Cast("Rushing Jade Wind", ctx => TalentManager.IsSelected((int)MonkTalents.RushingJadeWind) && (!Me.HasAura("Shuffle") || Me.Auras["Shuffle"].TimeLeft <= TimeSpan.FromSeconds(1))), Spell.Cast("Blackout Kick", ctx => !SpellManager.HasSpell("Brewmaster Training") || Me.HasKnownAuraExpired("Shuffle", 1)), Spell.Cast("Tiger Palm", ret => Me.HasKnownAuraExpired("Tiger Power", 1) || (SpellManager.HasSpell("Brewmaster Training") && Me.HasKnownAuraExpired("Power Guard", 1))), Spell.BuffSelf("Purifying Brew", ctx => Me.HasAura("Stagger") && Me.CurrentChi >= 3), // ***** Generate Chi ***** new Decorator( req => Me.CurrentChi < Me.MaxChi, new PrioritySelector( Spell.Cast("Keg Smash", ctx => Me.MaxChi - Me.CurrentChi >= 2), Spell.Cast("Spinning Crane Kick", ctx => Unit.NearbyUnfriendlyUnits.Count(u => u.DistanceSqr <= 8 * 8) >= 3), // jab with power strike talent is > expel Harm if off CD. new Decorator(ctx => TalentManager.IsSelected((int)MonkTalents.PowerStrikes) && Me.MaxChi - Me.CurrentChi >= 2 && Spell.CanCastHack("Jab") && powerStrikeTimer.IsFinished, new Sequence( new Action(ctx => powerStrikeTimer.Reset()), Spell.Cast("Jab") ) ), Spell.Cast("Expel Harm", req => Me.HealthPercent < 90 && Unit.NearbyUnfriendlyUnits.Any(u => u.DistanceSqr <= 10 * 10)), Spell.Cast("Jab") ) ), // filler: // cast on cooldown when Level < 26 (Guard) or Level >= 34 (Brewmaster Training), otherwise try to save some Chi for Guard if available Spell.Cast("Tiger Palm", ret => SpellManager.HasSpell("Brewmaster Training") || Me.CurrentChi > 2 || !SpellManager.HasSpell("Guard") || Spell.GetSpellCooldown("Guard").TotalSeconds > 4) ) ) ); }
private async Task<bool> GoingToAct1Hub() { DisablePulse(); if (_goingToAct1HubWaitTimer == null) { _goingToAct1HubWaitTimer = new WaitTimer(TimeSpan.FromSeconds(5)); _goingToAct1HubWaitTimer.Reset(); } if (!_goingToAct1HubWaitTimer.IsFinished) return false; if (!await WaypointCoroutine.UseWaypoint(WaypointFactory.ActHubs[Act.A1])) return false; _goingToAct1HubWaitTimer = null; State = States.InTown; return false; }
private async Task<bool> NotStarted() { if (_returningToTownWaitTimer == null) { _returningToTownWaitTimer = new WaitTimer(TimeSpan.FromSeconds(5)); _returningToTownWaitTimer.Reset(); } if (!_returningToTownWaitTimer.IsFinished) return false; _returningToTownWaitTimer = null; //if (!IsAvailable) //{ // _isDone = true; // return true; //} Stats = BountyStatistic.GetInstance(QuestId); if (Stats.StartTime == default(DateTime)) Stats.StartTime = DateTime.UtcNow; if (Stats.EndTime == default(DateTime)) Stats.EndTime = DateTime.UtcNow; Logger.Log(LogLevel.Overlay, "[Bounty] Starting {0} ({1})", QuestData.Name, QuestId); if (IsInZone) { State = States.InZone; } else { Logger.Debug("[Bounty] Using waypoint to reach one of the bounty LevelAreaIds: {0}", string.Join(", ", BountyData.LevelAreaIds)); State = States.TakingWaypoint; } return false; }
public override bool IsFulfilled() { if (!GaBSettings.Get().StartMissions) { GarrisonButler.Diagnostic("[Missions] Deactivated in user settings."); return true; } var numberMissionAvailable = MissionLua.GetNumberAvailableMissions(); // Is there mission available to start if (numberMissionAvailable == 0) { GarrisonButler.Diagnostic("[Missions] No missions available to start."); return true; } var garrisonRessources = BuildingsLua.GetGarrisonRessources(); IEnumerable<Mission> missions = _missions.Where(m => m.Cost < garrisonRessources).ToList(); if (!missions.Any()) { GarrisonButler.Diagnostic("[Missions] Not enough ressources to start a mission."); return true; } if (_timeOut == null || _timeOut.IsFinished) { _timeOut = new WaitTimer(TimeSpan.FromSeconds(30)); _timeOut.Reset(); GarrisonButler.Diagnostic("Checking for missions."); _followers = FollowersLua.GetAllFollowers(); _missions = MissionLua.GetAllAvailableMissions(); // Enhanced Mission Logic if (GarrisonButler.IsIceVersion()) { toStart = NewMissionStubCode(_followers.ToList()); } else { toStart = new List<Tuple<Mission, Follower[]>>(); var followersTemp = _followers.ToList(); foreach (var mission in missions) { // Make sure that status is Idle or In Party var match = mission.FindMatch(followersTemp.Where(f => f.IsCollected && f.Status.ToInt32() <= 1).ToList()); if (match == null) continue; toStart.Add(new Tuple<Mission, Follower[]>(mission, match)); followersTemp.RemoveAll(match.Contains); } } var mess = "Found available missions to complete. " + "Can successfully complete: " + toStart.Count + " missions."; if (toStart.Count > 0) GarrisonButler.Log(mess); else { GarrisonButler.Diagnostic(mess); } return !toStart.Any(); } return !toStart.Any(); }
public override async Task Action() { if (IsCreateAllOrders()) { if (!await CapacitiveDisplayFrame.StartAllOrder(_building)) { Status = new Result(ActionResult.Failed); return; } GarrisonButler.Log("Successfully started all work orders at {0}.", _building.Name); Status = new Result(ActionResult.Done); return; } // Otherwise we create them one by one var maxSettings = GaBSettings.Get().GetBuildingSettings(_building.Id).MaxCanStartOrder; var maxInProgress = maxSettings == 0 ? _building.ShipmentCapacity : Math.Min(_building.ShipmentCapacity, maxSettings); var maxToStart = maxInProgress - _building.ShipmentsTotal; var maxCanComplete = _building.maxCanComplete(); maxToStart = Math.Min(maxCanComplete, maxToStart); for (var i = 0; i < maxToStart; i++) { if (!await CapacitiveDisplayFrame.ClickStartOrderButton(_building)) { GarrisonButler.Diagnostic( "[ShipmentStart,{0}] Max number of tries ({1}) reached to start shipment at {2}", _building.Id, Building.StartWorkOrderMaxTries, _building.Name); Status = new Result(ActionResult.Failed); return; } await Coroutine.Yield(); } //} var timeout = new WaitTimer(TimeSpan.FromMilliseconds(10000)); timeout.Reset(); while (!timeout.IsFinished) { _building.Refresh(); maxSettings = GaBSettings.Get().GetBuildingSettings(_building.Id).MaxCanStartOrder; maxInProgress = maxSettings == 0 ? _building.ShipmentCapacity : Math.Min(_building.ShipmentCapacity, maxSettings); maxToStart = maxInProgress - _building.ShipmentsTotal; maxCanComplete = _building.maxCanComplete(); var max = Math.Min(maxCanComplete, maxToStart); if (max == 0) { GarrisonButler.Log("[ShipmentStart{1}] Finished starting work orders at {0}.", _building.Name, _building.Id); Status = new Result(ActionResult.Done); return; } GarrisonButler.Diagnostic("[ShipmentStart,{0}] Waiting for shipment to update.", _building.Id); await CommonCoroutines.SleepForRandomReactionTime(); await Coroutine.Yield(); } }
public override async Task Action() { using (var myLock = StyxWoW.Memory.AcquireFrame()) { // Record number of items in bags if first execution if (_oldEntriesCount == null) { _oldEntriesCount = new List<int>(); foreach (var entry in _entries) { _oldEntriesCount.Add((int) HbApi.GetNumberItemInBags(entry)); } } // take a stack of size 5 or more and mill var stackToMill = StyxWoW.Me.BagItems.GetEmptyIfNull() .FirstOrDefault(i => _entries.Contains(i.Entry) && i.StackCount >= 5); if (stackToMill == default(WoWItem)) { Status = new Result(ActionResult.Failed, "Couldn't find a proper stack to mill in bags."); return; } var itemId = stackToMill.Entry; var itemName = stackToMill.Name; var bagIndex = stackToMill.BagIndex; var bagSlot = stackToMill.BagSlot; var stackSize = stackToMill.StackCount; WoWMovement.MoveStop(); await CommonCoroutines.SleepForLagDuration(); if (_craftMortar != null) { var millingItem = HbApi.GetItemInBags(114942).FirstOrDefault(); if (millingItem == default(WoWItem)) { Status = new Result(ActionResult.Failed, "[Mill] no draenic mortar item in bags found. operation failed."); return; } millingItem.Use(); await CommonCoroutines.SleepForLagDuration(); } else { // Search for milling spell var millingSpell = WoWSpell.FromId(51005); await HbApi.CastSpell(millingSpell); } stackToMill.UseContainerItem(); await CommonCoroutines.SleepForLagDuration(); // Verification process // Refresh of the current state var bagWithMilledItem = default(WoWContainer); var itemMilled = default(WoWItem); var waitTimer = new WaitTimer(TimeSpan.FromMilliseconds(1500)); // cast time supposed to be 1000s waitTimer.Reset(); while (!waitTimer.IsFinished) { await Coroutine.Yield(); //If casting if (StyxWoW.Me.IsCasting) continue; ObjectManager.Update(); try { bagWithMilledItem = StyxWoW.Me.GetBagAtIndex((uint) bagIndex); if (bagWithMilledItem != null) { itemMilled = bagWithMilledItem.GetItemBySlot((uint) bagSlot); if (itemMilled != null) GarrisonButler.Diagnostic( "[Milling] In bags after milling at (bagIndex={0},bagSlot={1}): stackSize={2}, itemName={3}", bagIndex, bagSlot, itemMilled.StackCount, itemMilled.Name); if (itemMilled == null || itemMilled.Entry != itemId || itemMilled.StackCount < stackSize) { GarrisonButler.Diagnostic("[Milling] Confirmed milled, break."); break; } } } catch (Exception) { break; } } await CommonCoroutines.SleepForLagDuration(); if (bagWithMilledItem == null) { Status = new Result(ActionResult.Failed, string.Format("[Milling] wrong bag index. index={0}, slot={1}, itemId={2}", bagIndex, bagSlot, itemId)); return; } if (itemMilled != null && itemMilled.Entry == itemId && itemMilled.StackCount >= stackSize) { Status = new Result(ActionResult.Failed, string.Format( "[Milling] itemMilled not null, and stackCount didn't change. index={0}, slot={1}, itemId={2}, oldSize={3}, newSize={4}", bagIndex, bagSlot, itemId, stackSize, itemMilled.StackCount)); return; } GarrisonButler.Log("[Milling] Succesfully milled {0}.", itemName); } }
/// <summary> /// Find and mill one of a stack of ItemId in bags. Uses milling spell or draenic mortar. /// </summary> /// <param name="itemId"></param> /// <returns></returns> internal static async Task<ActionResult> MillHerbFromBags(uint itemId) { // Conditions to check using (var myLock = Styx.StyxWoW.Memory.AcquireFrame()) { // Search for a stack in bags var stackToMill = Me.BagItems.GetEmptyIfNull().FirstOrDefault(i => i.Entry == itemId); if (stackToMill == default(WoWItem)) { GarrisonButler.Diagnostic("[Milling] No item found in bags, id={0}", itemId); return ActionResult.Failed; } // Must have inscription or item var inscription = Me.GetSkill(SkillLine.Inscription); if (inscription == null) { GarrisonButler.Diagnostic("[Milling] Inscription == null. operation failed."); return ActionResult.Failed; } if (!inscription.IsValid) { GarrisonButler.Diagnostic("[Milling] Inscription is not valid. operation failed."); return ActionResult.Failed; } WoWSpell millingSpell = default(WoWSpell); var millingItem = default(WoWItem); if (inscription.CurrentValue <= 0) { millingItem = GetItemInBags(114942).FirstOrDefault(); if (millingItem == default(WoWItem) || millingItem.StackCount <= 0) { GarrisonButler.Diagnostic( "[Milling] Inscription value <= 0 and no milling item in bags found. operation failed."); return ActionResult.Failed; } if (!millingItem.Usable) { GarrisonButler.Diagnostic( "[Milling] Milling item unusable. operation failed."); return ActionResult.Failed; } } else { // We use spell to mill // Search for milling spell millingSpell = WoWSpell.FromId(51005); if (millingSpell == null) { GarrisonButler.Diagnostic("[Milling] Milling spell not found(==null)."); return ActionResult.Failed; } if (!millingSpell.IsValid) { GarrisonButler.Diagnostic("[Milling] Milling spell not valid."); return ActionResult.Failed; } if (!millingSpell.CanCast) { GarrisonButler.Diagnostic("[Milling] Can't cast milling spell."); return ActionResult.Failed; } } var bagIndex = stackToMill.BagIndex; var bagSlot = stackToMill.BagSlot; var stackSize = stackToMill.StackCount; var itemName = stackToMill.SafeName; GarrisonButler.Diagnostic( "[Milling] In bags before milling at (bagIndex={0},bagSlot={1}): stackSize={2}, itemName={3}", bagIndex, bagSlot, stackSize, itemName); // Mill once using spell if (millingSpell != default(WoWSpell)) await CastSpell(millingSpell); else { millingItem.Use(); await CommonCoroutines.SleepForLagDuration(); } stackToMill.UseContainerItem(); await CommonCoroutines.SleepForLagDuration(); //// Wait for Cast //await Buddy.Coroutines.Coroutine.Wait(10000, () => !Me.IsCasting); // Verification process // Refresh of the current state var bagWithMilledItem = default(WoWContainer); var itemMilled = default(WoWItem); var waitTimer = new WaitTimer(TimeSpan.FromMilliseconds(1500)); // cast time supposed to be 1000s waitTimer.Reset(); while (!waitTimer.IsFinished) { await Buddy.Coroutines.Coroutine.Yield(); //If casting if (Me.IsCasting) continue; ObjectManager.Update(); try { bagWithMilledItem = Me.GetBagAtIndex((uint) bagIndex); if (bagWithMilledItem != null) { itemMilled = bagWithMilledItem.GetItemBySlot((uint) bagSlot); if (itemMilled != null) GarrisonButler.Diagnostic( "[Milling] In bags after milling at (bagIndex={0},bagSlot={1}): stackSize={2}, itemName={3}", bagIndex, bagSlot, itemMilled.StackCount, itemMilled.Name); if (itemMilled == null || itemMilled.Entry != itemId || itemMilled.StackCount < stackSize) { GarrisonButler.Diagnostic("[Milling] Confirmed milled, break."); break; } } } catch (Exception) { break; } } await CommonCoroutines.SleepForLagDuration(); if (bagWithMilledItem == null) { GarrisonButler.Diagnostic("[Milling] wrong bag index. index={0}, slot={1}, itemId={2}", bagIndex, bagSlot, itemId); return ActionResult.Failed; } if (itemMilled != null && itemMilled.Entry == itemId && itemMilled.StackCount >= stackSize) { GarrisonButler.Diagnostic( "[Milling] itemMilled not null, and stackCount didn't change. index={0}, slot={1}, itemId={2}, oldSize={3}, newSize={4}", bagIndex, bagSlot, itemId, stackSize, itemMilled.StackCount); return ActionResult.Failed; } GarrisonButler.Log("[Milling] Succesfully milled {0}.", itemName); } return ActionResult.Done; }