public bool Buff(AIOPartyMember unit, AIOSpell spell, uint reagent = 0) { return(Buff(new List <AIOPartyMember>() { unit }, spell, reagent)); }
// Pull public static bool Pull(Cast cast, bool alwaysPull, List <AIOSpell> spells) { AIOSpell pullSpell = spells.Find(s => s != null && s.IsSpellUsable && s.KnownSpell); if (pullSpell == null) { RangeManager.SetRangeToMelee(); return(false); } WoWUnit closestHostileFromTarget = GetClosestHostileFrom(ObjectManager.Target, 20); if (closestHostileFromTarget == null && !alwaysPull) { RangeManager.SetRangeToMelee(); return(false); } float pullRange = pullSpell.MaxRange; if (ObjectManager.Target.GetDistance > pullRange - 2 || ObjectManager.Target.GetDistance < 6 || TraceLine.TraceLineGo(ObjectManager.Target.Position)) { RangeManager.SetRangeToMelee(); return(false); } if (closestHostileFromTarget != null && RangeManager.GetRange() < pullRange) { Logger.Log($"Pulling from distance (hostile unit {closestHostileFromTarget.Name} is too close)"); } if (ObjectManager.Me.IsMounted) { MountTask.DismountMount(); } RangeManager.SetRange(pullRange - 1); Thread.Sleep(300); if (cast.OnTarget(pullSpell)) { Thread.Sleep(500); if (pullSpell.GetCurrentCooldown > 0) { Usefuls.WaitIsCasting(); if (pullSpell.Name == "Shoot" || pullSpell.Name == "Throw" || pullSpell.Name == "Avenger's Shield") { Thread.Sleep(1500); } return(true); } } return(false); }
// Reactivates auto attack if it's off. Must pass the Attack spell as argument public static void CheckAutoAttack(AIOSpell attack) { bool _autoAttacking = Lua.LuaDoString <bool>("isAutoRepeat = false; if IsCurrentSpell('Attack') then isAutoRepeat = true end", "isAutoRepeat"); if (!_autoAttacking && ObjectManager.Target.IsAlive) { Logger.LogDebug("Re-activating attack"); attack.Launch(); } }
public Cast(AIOSpell defaultBaseSpell, AIOSpell wandSpell, BaseSettings settings) { AutoDetectImmunities = settings.AutoDetectImmunities; DefaultBaseSpell = defaultBaseSpell; CombatDebugON = settings.ActivateCombatDebug; WandSpell = wandSpell; IsApproachingTarget = false; CombatLogON = settings.ActivateCombatLog; EventsLuaWithArgs.OnEventsLuaStringWithArgs += EventsLuaStringWithArgsHandler; FightEvents.OnFightLoop += FightLoopHandler; }
// Stops using wand and waits for its CD to be over private void StopWandWaitGCD(AIOSpell wandSpell) { CombatDebug("Stopping Wand and waiting for GCD"); wandSpell.Launch(); Timer limit = new Timer(1500); while (!CurrentSpell.IsSpellUsable && !limit.IsReady) { Thread.Sleep(50); } CombatDebug($"Waited for GCD after wand stop : {1500 - limit.TimeLeft()}"); }
public bool Buff(List <AIOPartyMember> units, AIOSpell spell, uint reagent = 0) { if (reagent != 0 && !ItemsManager.HasItemById(reagent)) { return(false); } List <AIOPartyMember> unitsNeedsBuff = units .FindAll(m => !m.HaveBuff(spell.Name)) .OrderBy(m => rng.Next()) .ToList(); if (unitsNeedsBuff.Count <= 0) { return(false); } return(OnFocusUnit(spell, unitsNeedsBuff[0])); }
public static void SwitchTarget(Cast cast, AIOSpell spell) { if ((ObjectManager.Target.Target == ObjectManager.Me.Guid || !ObjectManager.Target.IsAlive || !ObjectManager.Target.HasTarget || !ObjectManager.Me.HasTarget) && !ToolBox.HasDebuff("Taunt", "target") && !ToolBox.HasDebuff("Growl", "target")) { lock (_groupLock) { foreach (WoWUnit enemy in EnemiesFighting) { WoWPlayer partyMemberToSave = _groupAndRaid .Find(m => enemy.Target == m.Guid && (m.Guid != ObjectManager.Me.Guid || !ObjectManager.Me.HasTarget)); if (partyMemberToSave != null) { Logger.Log($"Regaining aggro [{enemy.Name} attacking {partyMemberToSave.Name}]"); ObjectManager.Me.Target = enemy.Guid; if (spell != null) { if (spell.Name == "Righteous Defense") { cast.OnFocusUnit(spell, partyMemberToSave); } if (spell.Name == "Intervene" && enemy.Position.DistanceTo(partyMemberToSave.Position) < 10) { cast.OnTarget(spell); } } return; } } } } }
public bool AdvancedCast(AIOSpell spell, bool stopWandAndCast = true, bool onSelf = false, WoWUnit onUnitFocus = null, Vector3 location = null) { WoWUnit Me = ObjectManager.Me; float buffer = 600; if (IsApproachingTarget) { return(true); } CurrentSpell = spell; CurrentSpellLocation = location; CombatDebug("*----------- INTO PRE CAST FOR " + CurrentSpell.Name); if (!CurrentSpell.KnownSpell || IsBackingUp || Me.CastingTimeLeft > buffer || !CurrentSpell.IsForcedCooldownReady || Me.IsStunned) { return(false); } // Define target if (onUnitFocus != null) { CurrentSpellTarget = onUnitFocus; } else if (CurrentSpellLocation != null) { CurrentSpellTarget = null; } else if (onSelf) { CurrentSpellTarget = ObjectManager.Me; } else { if (CurrentSpell.MaxRange <= 0 && ObjectManager.Target.GetDistance > RangeManager.GetMeleeRangeWithTarget()) { return(false); } CurrentSpellTarget = ObjectManager.Target; } // Now that we know the target if (CurrentSpellLocation == null) { if (CurrentSpellTarget == null || CurrentSpellTarget.GetDistance > 100 || (CurrentSpellTarget.IsDead && !CurrentSpell.OnDeadTarget) || (CurrentSpell.MinRange > 0 && CurrentSpellTarget.GetDistance <= CurrentSpell.MinRange) || UnitImmunities.Contains(CurrentSpellTarget, CurrentSpell.Name) || (!CurrentSpellTarget.IsValid && !CurrentSpell.OnDeadTarget)) // double check this { return(false); } } CombatDebug("*----------- INTO CAST FOR " + CurrentSpell.Name); // CHECK COST if (CurrentSpell.PowerType == -2 && Me.Health < CurrentSpell.Cost) { CombatDebug($"{CurrentSpell.Name}: Not enough health {CurrentSpell.Cost}/{Me.Health}, SKIPPING"); return(false); } else if (CurrentSpell.PowerType == 0 && Me.Mana < CurrentSpell.Cost) { CombatDebug($"{CurrentSpell.Name}: Not enough mana {CurrentSpell.Cost}/{Me.Mana}, SKIPPING"); return(false); } else if (CurrentSpell.PowerType == 1 && Me.Rage < CurrentSpell.Cost) { CombatDebug($"{CurrentSpell.Name}: Not enough rage {CurrentSpell.Cost}/{Me.Rage}, SKIPPING"); return(false); } else if (CurrentSpell.PowerType == 2 && ObjectManager.Pet.Focus < CurrentSpell.Cost) { CombatDebug($"{CurrentSpell.Name}: Not enough pet focus {CurrentSpell.Cost}/{ObjectManager.Pet.Focus}, SKIPPING"); return(false); } else if (CurrentSpell.PowerType == 3 && Me.Energy < CurrentSpell.Cost) { CombatDebug($"{CurrentSpell.Name}: Not enough energy {CurrentSpell.Cost}/{Me.Energy}, SKIPPING"); return(false); } // DON'T CAST BECAUSE WANDING if (WandSpell != null && ToolBox.UsingWand() && !stopWandAndCast) { CombatDebug("Didn't cast because we were wanding"); return(false); } // COOLDOWN CHECKS float _spellCD = CurrentSpell.GetCurrentCooldown; CombatDebug($"Cooldown is {_spellCD}"); if (_spellCD >= 500) { CombatDebug("Didn't cast because cd is too long"); return(false); } // STOP WAND FOR CAST if (WandSpell != null && ToolBox.UsingWand() && stopWandAndCast) { StopWandWaitGCD(WandSpell); } // Wait for remaining Cooldown if (_spellCD > 0f && _spellCD < buffer) { CombatDebug($"{CurrentSpell.Name} is almost ready, waiting"); while (CurrentSpell.GetCurrentCooldown > 0 && CurrentSpell.GetCurrentCooldown < 500) { Thread.Sleep(50); } Thread.Sleep(50); // safety } if (!CurrentSpell.IsSpellUsable) { CombatDebug("Didn't cast because spell somehow not usable"); return(false); } bool stopMove = CurrentSpell.CastTime > 0 || CurrentSpell.IsChannel; if (CurrentSpellLocation != null || CurrentSpellTarget.Guid != Me.Guid) { Vector3 spellPosition = CurrentSpellLocation != null ? CurrentSpellLocation : CurrentSpellTarget.Position; if (CurrentSpell.MaxRange > 0 && spellPosition.DistanceTo(Me.Position) > CurrentSpell.MaxRange || TraceLine.TraceLineGo(spellPosition)) { if (Me.HaveBuff("Spirit of Redemption")) { return(false); } Logger.LogFight($"Target not in range/sight, recycling {CurrentSpell.Name}"); if (Fight.InFight) { IsApproachingTarget = true; } else { ApproachSpellTarget(); } return(true); } } if (onUnitFocus != null) { ObjectManager.Me.FocusGuid = CurrentSpellTarget.Guid; } string unit = onUnitFocus != null ? "focus" : "target"; unit = onSelf || CurrentSpellLocation != null ? "player" : unit; // Wait for remaining cast in case of buffer while (Me.CastingTimeLeft > 0) { Thread.Sleep(25); } if (stopMove) { MovementManager.StopMoveNewThread(); } if (CombatLogON) { string rankString = CurrentSpell.Rank > 0 ? $"(Rank {CurrentSpell.Rank})" : ""; string target = CurrentSpellLocation != null?CurrentSpellLocation.ToString() : CurrentSpellTarget.Name; Logger.Log($"[Spell] Casting {CurrentSpell.Name.Replace("()", "")} {rankString} on {target}"); } CurrentSpell.Launch(stopMove, false, true, unit); if (CurrentSpell.IsClickOnTerrain) { ClickOnTerrain.Pulse(CurrentSpellLocation); } Thread.Sleep(50); ToolBox.ClearCursor(); // Wait for channel to end if (CurrentSpell.IsChannel) { CombatDebug($"{CurrentSpell.Name} is channel, wait cast"); while (ToolBox.GetChannelTimeLeft("player") < 0) { Thread.Sleep(50); } CurrentSpell.StartForcedCooldown(); return(true); } // Wait for instant cast GCD if (CurrentSpell.CastTime <= 0) { CurrentSpell.StartForcedCooldown(); Timer gcdLimit = new Timer(1500); CombatDebug($"{CurrentSpell.Name} is instant, wait GCD"); while (DefaultBaseSpell.GetCurrentCooldown > buffer && !gcdLimit.IsReady) { Thread.Sleep(50); } if (gcdLimit.IsReady) { Logger.LogError("We had to resort to timer wait (GCD)"); } return(true); } if (CurrentSpell.CastTime > 0) { // Wait for cast to end buffer = CurrentSpell.PreventDoubleCast ? 0 : buffer; CombatDebug($"{CurrentSpell.Name} is normal, wait until {buffer} left"); while (Me.CastingTimeLeft > buffer) { if (CurrentSpell.IsResurrectionSpell && CurrentSpellTarget.IsAlive) { Lua.RunMacroText("/stopcasting"); } Thread.Sleep(50); } CurrentSpell.StartForcedCooldown(); } return(true); }
public bool OnFocusUnit(AIOSpell s, WoWUnit onUnitFocus, bool stopWandAndCast = true) { return(AdvancedCast(s, stopWandAndCast, onUnitFocus: onUnitFocus)); }
public bool OnLocation(AIOSpell s, Vector3 location, bool stopWandAndCast = true) { return(AdvancedCast(s, stopWandAndCast, location: location)); }
public bool OnSelf(AIOSpell s, bool stopWandAndCast = true) { return(AdvancedCast(s, stopWandAndCast, true)); }
public bool OnTarget(AIOSpell s, bool stopWandAndCast = true) { return(AdvancedCast(s, stopWandAndCast)); }