public override void Pulse() { if (_lastTargetGuid != StyxWoW.Me.CurrentTargetGuid) { _lastTargetGuid = StyxWoW.Me.CurrentTargetGuid; // Don't print this shit if we don't need to. Kthx. if (_lastTargetGuid != 0) { // Add other target switch info stuff here. Logger.WriteDebug("Switched targets!"); Logger.WriteDebug("Melee Distance: " + Spell.MeleeRange); Logger.WriteDebug("Health: " + StyxWoW.Me.CurrentTarget.MaxHealth); Logger.WriteDebug("Level: " + StyxWoW.Me.CurrentTarget.Level); } } // Double cast shit Spell.DoubleCastPreventionDict.RemoveAll(t => DateTime.UtcNow.Subtract(t).TotalMilliseconds >= 2500); PetManager.Pulse(); if (HealerManager.NeedHealTargeting) { HealerManager.Instance.Pulse(); } if (Group.MeIsTank && CurrentWoWContext != WoWContext.Battlegrounds && (Me.IsInParty || Me.IsInRaid)) { TankManager.Instance.Pulse(); } }
public Composite CreateHunterBuffs() { WantedPet = "1"; return(new PrioritySelector( new Decorator( ctx => Me.CastingSpell != null && Me.CastingSpell.Name == "Revive " + WantedPet && Me.GotAlivePet, new Action(ctx => SpellManager.StopCasting())), CreateWaitForCast(), CreateSpellBuffOnSelf("Aspect of the Hawk"), CreateSpellBuffOnSelf("Track Hidden"), //new ActionLogMessage(false, "Checking for pet"), new Decorator( ret => !Me.GotAlivePet, new Sequence( new Action(ret => PetManager.CallPet(WantedPet)), new Action(ret => Thread.Sleep(1000)), new DecoratorContinue( ret => !Me.GotAlivePet && SpellManager.CanCast("Revive Pet"), new Sequence( new Action(ret => SpellManager.Cast("Revive Pet")), new Action(ret => StyxWoW.SleepForLagDuration()), new WaitContinue( 11, ret => !Me.IsCasting, new ActionAlwaysSucceed()))))), CreateSpellCast( "Mend Pet", ret => (Me.Pet.HealthPercent < 70 || (Me.Pet.HappinessPercent < 90 && TalentManager.HasGlyph("Mend Pet"))) && !Me.Pet.HasAura("Mend Pet")) )); }
protected Composite CreateCastPetActionOnLocation(string action, LocationRetrievalDelegate location, SimpleBoolReturnDelegate extra) { return(new Decorator( ret => extra(ret) && PetManager.CanCastPetAction(action), new Sequence( new Action(ret => PetManager.CastPetAction(action)), new Action(ret => LegacySpellManager.ClickRemoteLocation(location(ret)))))); }
public override void Pulse() { PetManager.Pulse(); if (NeedHealTargeting) { HealTargeting.Instance.Pulse(); } if (NeedTankTargeting && CurrentWoWContext != WoWContext.Battlegrounds && (Me.IsInParty || Me.IsInRaid)) { TankTargeting.Instance.Pulse(); } }
public Composite CreateBeastMasterCombat() { WantedPet = "1"; return(new PrioritySelector( new Decorator( ret => !Me.GotAlivePet, new Action(ret => PetManager.CallPet(WantedPet))), CreateEnsureTarget(), CreateHunterBackPedal(), // Make sure we're in range, and facing the damned target. (LOS check as well) CreateMoveToAndFace(35f, ret => Me.CurrentTarget), //Intimidation CreateSpellCast( "Intimidation", ret => Me.CurrentTarget.IsAlive && Me.GotAlivePet && (Me.CurrentTarget.CurrentTarget == null || Me.CurrentTarget.CurrentTarget == Me)), // Always keep it up on our target! CreateSpellBuff("Hunter's Mark"), CreateHunterTrapOnAddBehavior(), new Decorator( ret => Me.CurrentTarget.DistanceSqr < 5 * 5, new PrioritySelector( CreateSpellBuffOnSelf("Disengage"), CreateSpellCast("Raptor Strike") )), // Heal pet when below 70 CreateSpellCast( "Mend Pet", ret => (Me.Pet.HealthPercent < 70 || (Me.Pet.HappinessPercent < 90 && TalentManager.HasGlyph("Mend Pet"))) && !Me.Pet.HasAura("Mend Pet")), CreateSpellCast( "Concussive Shot", ret => Me.CurrentTarget.CurrentTarget == null || Me.CurrentTarget.CurrentTarget == Me), //Rapid fire on elite CreateSpellBuffOnSelf("Rapid Fire", ret => CurrentTargetIsElite), CreateSpellBuff("Serpent Sting"), // Ignore these two when our pet is raging CreateSpellCast("Focus Fire", ret => !Me.Pet.HasAura("Bestial Wrath")), CreateSpellCast("Kill Shot", ret => !Me.Pet.HasAura("Bestial Wrath")), // Basically, cast it whenever its up. CreateSpellCast("Kill Command"), // Only really cast this when we need a sting refresh. CreateSpellCast( "Cobra Shot", ret => Me.CurrentTarget.HasAura("Serpent Sting") && Me.CurrentTarget.Auras["Serpent Sting"].TimeLeft.TotalSeconds < 3), // Focus dump on arcane shot, unless our pet has bestial wrath, then we use it for better DPS CreateSpellCast("Arcane Shot"), // For when we have no Focus CreateSpellCast("Steady Shot"), CreateAutoAttack(true) )); }
public Composite CreateWarlockPreCombatBuffs() { return(new PrioritySelector( CreateWaitForCast(), CreateSpellBuffOnSelf("Create Healthstone", ret => NeedToCreateHealthStone), CreateSpellBuffOnSelf("Demon Armor", ret => !Me.HasAura("Demon Armor") && !SpellManager.HasSpell("Fel Armor")), CreateSpellBuffOnSelf("Fel Armor", ret => !Me.HasAura("Fel Armor")), CreateSpellBuffOnSelf("Soul Link", ret => !Me.HasAura("Soul Link") && Me.GotAlivePet), new Decorator( ret => !Me.GotAlivePet, new Action(ret => PetManager.CallPet(WantedPet))), CreateSpellBuffOnSelf("Health Funnel", ret => Me.GotAlivePet && Me.Pet.HealthPercent < 60 && Me.HealthPercent > 40) )); }
protected Composite CreateAutoAttack(bool includePet) { const int SPELL_ID_AUTO_SHOT = 75; return(new PrioritySelector( new Decorator( ret => !Me.IsAutoAttacking && Me.AutoRepeatingSpellId != SPELL_ID_AUTO_SHOT, new Action(ret => Me.ToggleAttack())), new Decorator( ret => includePet && Me.GotAlivePet && (Me.Pet.CurrentTarget == null || Me.Pet.CurrentTarget != Me.CurrentTarget), new Action( delegate { PetManager.CastPetAction("Attack"); return RunStatus.Failure; })) )); }
public Composite CreateSurvivalCombat() { WantedPet = "1"; return(new PrioritySelector( new Decorator( ret => !Me.GotAlivePet, new Action(ret => PetManager.CallPet(WantedPet))), CreateEnsureTarget(), CreateHunterBackPedal(), // Make sure we're in range, and facing the damned target. (LOS check as well) CreateMoveToAndFace(35f, ret => Me.CurrentTarget), // Always keep it up on our target! CreateSpellBuff("Hunter's Mark"), // Heal pet when below 70 CreateSpellCast("Mend Pet", ret => Me.Pet.HealthPercent < 70 && !Me.Pet.HasAura("Mend Pet")), CreateSpellCast( "Concussive Shot", ret => Me.CurrentTarget.CurrentTarget == null || Me.CurrentTarget.CurrentTarget == Me), //Rapid fire on elite CreateSpellBuff("Rapid Fire", ret => CurrentTargetIsElite), //Cast when mob Hp below 20 CreateSpellCast("Kill Shot", ret => Me.CurrentTarget.HealthPercent < 19), new Decorator( ret => !Me.HasAura("Lock and Load"), new PrioritySelector( // The extra here 'flips' the explosive usage. CreateSpellCast("Kill Command", ret => Me.FocusPercent == 100), CreateSpellCast("Explosive Shot", ret => LastSpellCast != "Explosive Shot"), CreateSpellCast("Steady Shot", ret => LastSpellCast != "Steady Shot"))), // Refresh when it wears off. CreateSpellBuff("Serpent Sting", ret => !Me.CurrentTarget.HasAura("Serpent Sting")), // Whenever it's not on CD CreateSpellCast("Explosive Shot"), // Whenever its not on CD CreateSpellCast("Black Arrow"), // Main DPS filler CreateSpellCast("Steady Shot"), CreateSpellCast("Arcane Shot"), CreateAutoAttack(true) )); }
public override void Pulse() { // No pulsing if we're loading or out of the game. if (!StyxWoW.IsInGame || !StyxWoW.IsInWorld) { return; } // Update the current context, check if we need to rebuild any behaviors. UpdateContext(); // Double cast shit Spell.DoubleCastPreventionDict.RemoveAll(t => DateTime.UtcNow.Subtract(t).TotalMilliseconds >= 2500); Spell.PulseDoubleCastEntries(); //Only pulse for classes with pets switch (StyxWoW.Me.Class) { case WoWClass.Hunter: case WoWClass.DeathKnight: case WoWClass.Warlock: case WoWClass.Mage: PetManager.Pulse(); break; } if (HealerManager.NeedHealTargeting) { HealerManager.Instance.Pulse(); } if (Group.MeIsTank && CurrentWoWContext != WoWContext.Battlegrounds && (Me.GroupInfo.IsInParty || Me.GroupInfo.IsInRaid)) { TankManager.Instance.Pulse(); } }
protected Composite CreateCastPetActionOn(string action, UnitSelectionDelegate onUnit, SimpleBoolReturnDelegate extra) { return(new Decorator( ret => extra(ret) && PetManager.CanCastPetAction(action), new Action(ret => PetManager.CastPetAction(action, onUnit(ret))))); }
public Composite CreateFrostMageCombat() { WantedPet = "Water Elemental"; return(new PrioritySelector( CreateEnsureTarget(), //Move away from frozen targets new Decorator( ret => (Me.CurrentTarget.HasAura("Frost Nova") || Me.CurrentTarget.HasAura("Freeze")) && Me.CurrentTarget.DistanceSqr < 5 * 5, new Action( ret => { Logger.Write("Getting away from frozen target"); WoWPoint moveTo = WoWMathHelper.CalculatePointFrom(Me.Location, Me.CurrentTarget.Location, 10f); if (Navigator.CanNavigateFully(Me.Location, moveTo)) { Navigator.MoveTo(moveTo); } })), CreateMoveToAndFace(34f, ret => Me.CurrentTarget), CreateWaitForCast(true), CreateCastPetActionOnLocation("Freeze", ret => !Me.CurrentTarget.HasAura("Frost Nova")), CreateSpellBuff("Frost Nova", ret => NearbyUnfriendlyUnits.Any(u => u.DistanceSqr <= 8 * 8)), CreateMagePolymorphOnAddBehavior(), new Decorator( ret => !Me.GotAlivePet, new Action(ret => PetManager.CallPet(WantedPet))), CreateSpellCast("Evocation", ret => Me.ManaPercent < 20), CreateSpellCast("Counterspell", ret => Me.CurrentTarget.IsCasting), CreateSpellCast("Mirror Image"), CreateSpellCast("Time Warp"), new Decorator( ret => Me.CurrentTarget.HealthPercent > 50, new Sequence( new Action(ctx => Me.CurrentTarget.Face()), new Action(ctx => StyxWoW.SleepForLagDuration()), new PrioritySelector(CreateSpellCast("Flame Orb")) )), CreateSpellBuffOnSelf("Ice Barrier", ret => !Me.Auras.ContainsKey("Mana Shield")), CreateSpellBuffOnSelf("Mana Shield", ret => !Me.Auras.ContainsKey("Ice Barrier") && Me.HealthPercent <= 50), CreateSpellCast( "Deep Freeze", ret => (Me.ActiveAuras.ContainsKey("Fingers of Frost") || Me.CurrentTarget.HasAura("Frost Nova") || Me.CurrentTarget.HasAura("Freeze"))), CreateSpellCast( "Ice Lance", ret => (Me.ActiveAuras.ContainsKey("Fingers of Frost") || Me.CurrentTarget.ActiveAuras.ContainsKey("Frost Nova") || Me.CurrentTarget.ActiveAuras.ContainsKey("Freeze"))), //CreateSpellCast("Fireball", Me.ActiveAuras.ContainsKey("Brain Freeze")), CreateSpellCast("Arcane Missiles", ret => Me.ActiveAuras.ContainsKey("Arcane Missiles!")), new Decorator( ret => Me.ActiveAuras.ContainsKey("Brain Freeze"), new PrioritySelector( CreateSpellCast("Frostfire Bolt"), CreateSpellCast("Fireball") )), CreateSpellBuff("Fire Blast", ret => Me.CurrentTarget.HealthPercent < 10), CreateSpellCast("Frostbolt") )); }
private void CheckCurrentPet() { if (!SingularSettings.Debug) { return; } if (Me.Pet == null) { if (_lastPetGuid.IsValid) { _lastPetGuid = WoWGuid.Empty; if (SingularSettings.Debug) { Logger.WriteDebug("YourCurrentPet: (none)"); } } } else { // check for change in current pet if (Me.Pet.Guid != _lastPetGuid || Me.Pet.IsAlive != _lastPetAlive) { _lastPetGuid = Me.Pet.Guid; _lastPetAlive = Me.Pet.IsAlive; Logger.WriteDebug("YourCurrentPet: #{0}, Name={1}, Level={2}, Type={3}, Talents={4}", Me.PetNumber, Me.Pet.SafeName(), Me.Pet.Level, Me.Pet.CreatureType, PetManager.GetPetTalentTree()); } // now check pets target CheckTarget(Me.Pet.CurrentTarget, ref _lastCheckPetsTargetGuid, "PetsCurrentTarget", (x) => { }); } }
public override void Pulse() { #region Pulse - check for conditions that we should not Pulse during /* * if (!StyxWoW.IsInGame) * { * if (DateTime.UtcNow > _nextNotInGameMsgAllowed) * { * Logger.WriteDebug(Color.HotPink, "info: not in game"); * _nextNotInGameMsgAllowed = DateTime.UtcNow.AddSeconds(30); * } * return; * } * _nextNotInGameMsgAllowed = DateTime.MinValue; * * if (!StyxWoW.IsInWorld) * { * if (DateTime.UtcNow > _nextNotInWorldMsgAllowed) * { * Logger.WriteDebug(Color.HotPink, "info: not in world"); * _nextNotInWorldMsgAllowed = DateTime.UtcNow.AddSeconds(30); * } * return; * } * _nextNotInWorldMsgAllowed = DateTime.MinValue; */ #endregion _pulsePhase++; if (_pulsePhase == 1) { if (WaitForLatencyCheck.IsFinished) { Latency = StyxWoW.WoWClient.Latency; WaitForLatencyCheck.Reset(); } // output messages about pulldistance and behaviorflag changes here MonitorPullDistance(); MonitorBehaviorFlags(); /* * // now if combat disabled, bail out * bool combatDisabled = Bots.Grind.BehaviorFlags.Combat != (Bots.Grind.LevelBot.BehaviorFlags & Bots.Grind.BehaviorFlags.Combat); * if (combatDisabled != _lastCombatDisabledState) * { * _lastCombatDisabledState = combatDisabled; * Logger.Write(Color.HotPink, * combatDisabled * ? "info: botbase disabled BehaviorFlags.Combat" * : "info: botbase enabled BehaviorFlags.Combat" * ); * } */ // check time since last call and be sure user knows if Singular isn't being called if (SingularSettings.Debug) { TimeSpan since = CallWatch.TimeSpanSinceLastCall; if (since.TotalSeconds > (4 * CallWatch.SecondsBetweenWarnings)) { if (!Me.IsGhost && !Me.Mounted && !Me.IsFlying && DateTime.UtcNow > _nextNoCallMsgAllowed) { Logger.WriteDebug(Color.HotPink, "info: {0:F0} seconds since {1} BotBase last called Singular", since.TotalSeconds, GetBotName()); _nextNoCallMsgAllowed = DateTime.UtcNow.AddSeconds(4 * CallWatch.SecondsBetweenWarnings); } } } UpdateDiagnosticFPS(); } else if (_pulsePhase == 2) { // talentmanager.Pulse() intense if does work, so return if true if (TalentManager.Pulse()) { return; } // check and output casting state information UpdateDiagnosticCastingState(); UpdatePullMoreConditionals(); // Update the current context, check if we need to rebuild any behaviors. UpdateContext(); } else if (_pulsePhase == 3) { _pulsePhase = 0; // Pulse our StopAt manager StopMoving.Pulse(); PetManager.Pulse(); // Double cast maintenance Spell.MaintainDoubleCast(); HotkeyDirector.Pulse(); WatchAurasForProcs(); } if (Me.Class == WoWClass.Warlock) { ClassSpecific.Warlock.Common.CancelBurningRushIfNeeded(fromPulse: true); } // Output if Target changed CheckCurrentTarget(); // Output if Pet or Pet Target changed CheckCurrentPet(); // check Targeting pulses if (HealerManager.NeedHealTargeting) { BotBase bot = GetCurrentBotBase(); if (bot != null && (bot.PulseFlags & PulseFlags.Targeting) != PulseFlags.Targeting) { HealerManager.Instance.Pulse(); } } else if (TankManager.NeedTankTargeting && Group.MeIsTank) { BotBase bot = GetCurrentBotBase(); if (bot != null && (bot.PulseFlags & PulseFlags.Targeting) != PulseFlags.Targeting) { TankManager.Instance.Pulse(); } } }