private static Composite MindSpikeRotation() { return(new Sequence( //this is the stationary composite, so it shouldn't be an issue to face the target. new TreeSharp.Action(delegate { if (!Me.IsMoving) { TargetManager.ActiveTarget.Face(); } }), //Need to add code here to respect the SWD logic specified by settings.. new PrioritySelector( AltarboyComposites.CastSpell("Archangel", ret => ( AuraManager.HasMyAura("Dark Evangelism", Me, 5)), Me), //Shadow Word Death On Exectue AltarboyComposites.CastSpell("Shadow Word: Death", ret => ( TargetManager.SafeToShadowWordDeath(TargetManager.ActiveTarget) && AltarboySettings.Instance.ShadowWordDeathForExecute && TargetManager.ActiveTarget.HealthPercent <= 25 ), TargetManager.ActiveTarget), AltarboyComposites.CastSpell("Mind Blast", ret => AuraManager.HasMyAura("Mind Spike", TargetManager.ActiveTarget, 3), TargetManager.ActiveTarget), AltarboyComposites.CastSpell("Shadow Word: Death", ret => (TargetManager.SafeToShadowWordDeath(TargetManager.ActiveTarget) && AltarboySettings.Instance.ShadowWordDeathForManaOnly && Me.ManaPercent <= AltarboySettings.Instance.ShadowWordDeathManaPercent), TargetManager.ActiveTarget), AltarboyComposites.CastSpell("Mind Spike", ret => true, TargetManager.ActiveTarget), AltarboyComposites.CastSpell("Mind Flay", ret => ( Me.IsSafelyFacing(TargetManager.ActiveTarget) && (AuraManager.GetAuraTimeLeft("Mind Flay", TargetManager.ActiveTarget, true).TotalSeconds <= AltarboySettings.Instance.ClippingDuration) ), TargetManager.ActiveTarget) ))); }
private static Composite MovementDps() { return(new PrioritySelector( //Use dispersion when low on mana. AltarboyComposites.CastSpell("Dispersion", ret => (Me.ManaPercent <= AltarboySettings.Instance.DispersionManaPercent), Me), // I think it always makes sense to use pain first... this cans generate orbs, and apparitions. AltarboyComposites.CastSpell("Shadow Word: Pain", ret => ( AuraManager.GetAuraTimeLeft("Shadow Word: Pain", TargetManager.ActiveTarget, true).TotalSeconds <= .4) , TargetManager.ActiveTarget), //Shadow Word Death While Moving AltarboyComposites.CastSpell("Shadow Word: Death", ret => ( TargetManager.SafeToShadowWordDeath(TargetManager.ActiveTarget) && AltarboySettings.Instance.ShadowWordDeathWhileMoving ), TargetManager.ActiveTarget), //Shadowfiend on CD or as mana regen. AltarboyComposites.CastSpell("Shadowfiend", ret => ( (AltarboySettings.Instance.UseShadowFiendOnCD || (AltarboySettings.Instance.UseShadowFiendForManaRegen && Me.ManaPercent <= AltarboySettings.Instance.UseShadowFiendManaPercent))) , TargetManager.ActiveTarget ), //This will spam cause its good dps... AltarboyComposites.CastSpell("Devouring Plague", ret => true, TargetManager.ActiveTarget) )); }
public static Boolean ShouldApplyDevouringPlague() { if (TargetManager.ActiveTarget.IsMechanical && TargetManager.ActiveTarget.Level <= Me.Level) { return(false); } return(!TargetManager.DetectHostileTargets(200).Any(target => AuraManager.GetAuraTimeLeft("Devouring Plague", target, true).TotalSeconds >= 1.2)); }
private static Composite MindSearDps(SimpleBoolReturnDelegate extra) { //FOR NOW WE WILL ASSUME THAT WE ONLY MIND SEAR ON FRIENDLY TARGETS // EVENTUALLY THIS WONT BE THE CASE. return(new Sequence( //this is the stationary composite, so it shouldn't be an issue to face the target. new TreeSharp.Action(delegate { if (!Me.IsMoving) { TargetManager.ActiveTarget.Face(); } }), new Decorator( ret => extra(ret), new PrioritySelector( // lets trigger ES first if possible // AltarboyComposites.CastSpell("Mind Blast", ret => // Me.CurrentTarget.CurrentTarget != null && // Me.IsSafelyFacing(Me.CurrentTarget.CurrentTarget ) && // !Me.IsMoving && // AuraManager.HasMyAura("Shadow Orb", Me, 1) // , Me.CurrentTarget.CurrentTarget), // // Mind sear is expensive... lets get some mana back. //AltarboyComposites.CastSpell("Shadowfiend", ret => ( // Me.CurrentTarget.CurrentTarget != null && // (AltarboySettings.Instance.UseShadowFiendOnCD || (AltarboySettings.Instance.UseShadowFiendForManaRegen && Me.ManaPercent <= AltarboySettings.Instance.UseShadowFiendManaPercent)) && // AuraManager.GetAuraTimeLeft("Mind Sear", Me.CurrentTarget, true).TotalSeconds <= 0.5), // Me.CurrentTarget.CurrentTarget //), ////Lets Execute with SWD if we can. //AltarboyComposites.CastSpell("Shadow Word: Death", ret => ( // SafeToShadowWordDeath() && // AltarboySettings.Instance.ShadowWordDeathForExecute && // TargetManager.DetectHostileTargets(40).Any(target => (target.HealthPercent <= 25 && target.Distance <= 35)) // ), TargetManager.DetectHostileTargets(40).First(target => (target.HealthPercent <= 25 && target.Distance <= 35))), //// lets use some SWD if possible... good time to get some mana back //AltarboyComposites.CastSpell("Shadow Word: Death", ret => ( // SafeToShadowWordDeath() && // Me.ManaPercent <= AltarboySettings.Instance.ShadowWordDeathManaPercent && // AltarboySettings.Instance.ShadowWordDeathForManaOnly //), false, Me.CurrentTarget.CurrentTarget), AltarboyComposites.CastMindSear(ret => (AuraManager.GetAuraTimeLeft("Mind Sear", TargetManager.ActiveTarget, true).TotalSeconds <= 0.4)) ) // new TreeSharp.Action(delegate { CastManager.CastSpell("Mind Sear"); }) ))); }
public static Boolean TargetNeedsMultiDot(WoWUnit unit) { if (unit == null) { return(false); } if (unit.Distance2D > 40 || !unit.InLineOfSight) { return(false); } return(AuraManager.GetAuraTimeLeft("Vampiric Touch", unit, true).TotalSeconds < 3 || AuraManager.GetAuraTimeLeft("Shadow Word: Pain", unit, true).TotalSeconds < 1.5); }
public static bool IsShackleTarget(WoWUnit unit) { //Can only shackle undead. if (unit == null || !unit.IsUndead) { return(false); } // if its already shackled - just ignore it if (AuraManager.GetAuraTimeLeft("Shackle Undead", unit, true).TotalSeconds >= 3) { return(false); } return(unit.IsValid && AltarboySpecialTargets.Any(u => u.TargetId == unit.Entry && u.Shackle)); }
public static Composite SelectFriendlyMindSearTarget() { //We should AOE (Mind Sear) - And use the RafLeader as the target. return(new Decorator(ret => AltarboySettings.Instance.UseMindSear && AltarboySettings.Instance.EnableMindSearTargeting && (AuraManager.GetAuraTimeLeft("Mind Sear", TargetManager.ActiveTarget, true).TotalSeconds <= 1) && !Me.IsMoving && BestFriendlyMindSearTarget() != null && NumOfHostileWithinRange(BestFriendlyMindSearTarget(), 10) >= AltarboySettings.Instance.MindSearHostileCount && BestFriendlyMindSearTarget().Distance2D <= 40, new TreeSharp.Action(delegate { SetTarget(BestFriendlyMindSearTarget(), TargetMode.MindSear); }) )); }
public static Composite HealSelf() { return(new PrioritySelector( new Decorator(ret => Me.HealthPercent <= 20, CastSpell("Flash Heal", ret => (true), Me)), new Decorator(ret => Me.HealthPercent <= 30, CastSpell("Penance", ret => (true), Me)), new Decorator( ret => AuraManager.GetAuraTimeLeft("Renew", Me, true).TotalSeconds <= 1 && Me.HealthPercent <= 80, CastSpell("Renew", ret => (true), Me) ), new Decorator( ret => CanPowerWordShield(Me) && Me.HealthPercent <= 90, CastSpell("Power Word: Shield", ret => (true), Me) ) )); }
// Logic to prevent ripping all DoTs off of target when casting Mind Spike. public static Boolean ShouldMindSpikeOverDoTs(WoWUnit unit) { if (AuraManager.GetAuraTimeLeft("Devouring Plague", unit, true).TotalSeconds >= 1.5) { return(false); } if (!AuraManager.HasMyAura("Vampiric Touch", unit)) { return(true); } if (!AuraManager.HasMyAura("Shadow Word: Pain", unit)) { return(true); } // The clauses below estimates a 1.2 second cast of Mind Spike return(AuraManager.GetAuraTimeLeft("Shadow Word: Pain", unit, true).TotalSeconds <= 1.1); }
public static Composite Combat() { return(new Sequence( //Select a target Target(), //Then kill it. new Decorator( ret => TargetManager.ActiveTarget != null && !CastManager.IsHymning() && !Me.IsFalling && !TargetManager.IsIgnoreTarget(TargetManager.ActiveTarget), //Added falling clause cause was killing me on Ragnaros. new PrioritySelector( MindSearDps(ret => TargetManager.ShouldMindSear(TargetManager.ActiveTarget) && AuraManager.GetAuraTimeLeft("Mind Sear", TargetManager.ActiveTarget, true).TotalSeconds <= AltarboySettings.Instance.ClippingDuration), SingleTargetDps() ) ) )); }
private static Composite NormalDpsRotation(SimpleBoolReturnDelegate extra) { // Altarboy.Logger.Slog(Color.Lime, "--- Single Target Max Dps Rotation --- "); return(new Sequence( //this is the stationary composite, so it shouldn't be an issue to face the target. new TreeSharp.Action(delegate { if (!Me.IsMoving && !Me.IsSafelyFacing(TargetManager.ActiveTarget)) { TargetManager.ActiveTarget.Face(); } }), new Decorator( ret => extra(ret), new PrioritySelector( // This doesnt belong here but Im using it for raiding at the moment... will move later. AltarboyComposites.CastSpell("Dispersion", ret => (AuraManager.HasAuraStacks("Tormented", 14, Me)), Me), //Shadow Word Death On Exectue AltarboyComposites.CastSpell("Shadow Word: Death", ret => ( TargetManager.SafeToShadowWordDeath(TargetManager.ActiveTarget) && AltarboySettings.Instance.ShadowWordDeathForExecute && TargetManager.ActiveTarget.HealthPercent <= 25 ), TargetManager.ActiveTarget), //Shadowfiend on Bloodlust. AltarboyComposites.CastSpell("Shadowfiend", ret => ( AltarboySettings.Instance.ForceFiendOnBloodlust && AuraManager.IsLusting(Me)), TargetManager.ActiveTarget ), //Shadowfiend on Bloodlust. AltarboyComposites.CastSpell("Shadowfiend", ret => ( AltarboySettings.Instance.ForceShadowFiendOnArchangel && AuraManager.HasMyAura("Dark Archangel", Me)), TargetManager.ActiveTarget ), // I think it always makes sense to use pain first... this can generate orbs, and apparitions. AltarboyComposites.CastSpell("Shadow Word: Pain", ret => ( AuraManager.GetAuraTimeLeft("Shadow Word: Pain", TargetManager.ActiveTarget, true).TotalSeconds <= .4), TargetManager.ActiveTarget ), AltarboyComposites.CastSpell("Mind Flay", ret => ( !Altarboy.AuraManager.HasAuraStacks("Dark Evangelism", 5, Me) && Me.IsSafelyFacing(TargetManager.ActiveTarget) && (AuraManager.GetAuraTimeLeft("Mind Flay", TargetManager.ActiveTarget, true).TotalSeconds <= AltarboySettings.Instance.ClippingDuration) ), TargetManager.ActiveTarget), // If there is an orb to use, and ES is close to running out... Refresh it before applying dots. AltarboyComposites.CastSpell("Mind Blast", ret => Me.IsSafelyFacing(TargetManager.ActiveTarget) && AuraManager.HasMyAura("Shadow Orb", Me, 1) && AuraManager.GetAuraTimeLeft("Empowered Shadow", Me, true).TotalSeconds < 4, TargetManager.ActiveTarget ), AltarboyComposites.CastSpell("Vampiric Touch", ret => ( CastManager.LastSpellCast != "Vampiric Touch" && Me.IsSafelyFacing(TargetManager.ActiveTarget) && (AuraManager.GetAuraTimeLeft("Vampiric Touch", TargetManager.ActiveTarget, true).TotalSeconds <= 2.6) ), TargetManager.ActiveTarget), // DP goes second cause you can cast while moving and it does instant damage. AltarboyComposites.CastSpell("Devouring Plague", ret => ( TargetManager.ShouldApplyDevouringPlague() ), TargetManager.ActiveTarget), // --- Trying to delay mana regen stuff untill dots are up if possible. ---// //Use dispersion when low on mana. AltarboyComposites.CastSpell("Dispersion", ret => (Me.ManaPercent <= AltarboySettings.Instance.DispersionManaPercent), Me), //Shadowfiend on CD or as mana regen. AltarboyComposites.CastSpell("Shadowfiend", ret => ( (AltarboySettings.Instance.UseShadowFiendOnCD || (AltarboySettings.Instance.UseShadowFiendForManaRegen && Me.ManaPercent <= AltarboySettings.Instance.UseShadowFiendManaPercent)) && AuraManager.GetAuraTimeLeft("Mind Flay", TargetManager.ActiveTarget, true).TotalSeconds <= 0.5) , TargetManager.ActiveTarget ), //Only use Archangel when there are 5 stacks up. //TODO - Want to add logic to make sure this isn't cast when dots are close to needing a refresh // - the goal is to make sure that right after this we can maximize mindblasts and mindflays. AltarboyComposites.CastSpell("Archangel", ret => ( AuraManager.HasMyAura("Dark Evangelism", Me, 5) && AuraManager.GetAuraTimeLeft("Vampiric Touch", TargetManager.ActiveTarget, true).TotalSeconds > 8 && AuraManager.GetAuraTimeLeft("Mind Flay", TargetManager.ActiveTarget, true).TotalSeconds <= 0.5) , Me ), //Shadow Word Death For Mana AltarboyComposites.CastSpell("Shadow Word: Death", ret => ( TargetManager.SafeToShadowWordDeath(TargetManager.ActiveTarget) && AltarboySettings.Instance.ShadowWordDeathForManaOnly && Me.ManaPercent <= AltarboySettings.Instance.ShadowWordDeathManaPercent ), TargetManager.ActiveTarget), //Shadow Word on CD (Not sure who would want this) AltarboyComposites.CastSpell("Shadow Word: Death", ret => ( TargetManager.SafeToShadowWordDeath(TargetManager.ActiveTarget) && AltarboySettings.Instance.ShadowWordDeathOnCD ), TargetManager.ActiveTarget), //Mind blast freely if we have at least ten seconds of ES left or if use wants to fire it on cooldown AltarboyComposites.CastSpell("Mind Blast", ret => Me.IsSafelyFacing(TargetManager.ActiveTarget) && (AuraManager.GetAuraTimeLeft("Empowered Shadow", Me, true).TotalSeconds > 9 || AltarboySettings.Instance.UseMindBlastOnCD) , TargetManager.ActiveTarget ), //Mind blast if we have at least 1 orb up and no ES at all. (Want to get ES up as fast as possible) AltarboyComposites.CastSpell("Mind Blast", ret => Me.IsSafelyFacing(TargetManager.ActiveTarget) && AuraManager.HasMyAura("Shadow Orb", Me, 1) , TargetManager.ActiveTarget), //Always use MB when you have 3 orbs AltarboyComposites.CastSpell("Mind Blast", ret => Me.IsSafelyFacing(TargetManager.ActiveTarget) && (AuraManager.HasMyAura("Shadow Orb", Me, 3) ), TargetManager.ActiveTarget), //Mind flay when when you have nothing else to do.. Try and clip to account for lag. AltarboyComposites.CastSpell("Mind Flay", ret => ( Me.IsSafelyFacing(TargetManager.ActiveTarget) && (AuraManager.GetAuraTimeLeft("Mind Flay", TargetManager.ActiveTarget, true).TotalSeconds <= AltarboySettings.Instance.ClippingDuration) ), TargetManager.ActiveTarget) ) ) )); }
public static bool CanCast(string spellName, WoWUnit onUnit) { if (onUnit == null) { return(false); } //trying to prevent vt from doublecasting.... // Do we have spell? if (!SpellManager.Spells.ContainsKey(spellName)) { return(false); } WoWSpell spell = SpellManager.Spells[spellName]; if (spellName == "Vampiric Touch" && spell.Cooldown) { return(false); } // are we casting or channeling ? if (Me.ChanneledCastingSpellId == 15407 && spellName != "Vampiric Touch" && AuraManager.GetAuraTimeLeft("Mind Flay", onUnit, true).TotalSeconds >= AltarboySettings.Instance.ClippingDuration) { return(false); } if (Priest.ActiveSpec == TalentSpec.DisciplinePriest && (Me.IsCasting || Me.ChanneledCastingSpellId != 0)) { return(false); } if (SpellManager.GlobalCooldownLeft.TotalSeconds > AltarboySettings.Instance.CoolDownDuration) { return(false); } // is spell in CD? if (spell.CooldownTimeLeft.TotalSeconds >= AltarboySettings.Instance.CoolDownDuration) { return(false); } // minrange check if (spell.MinRange != 0 && onUnit.DistanceSqr < spell.MinRange * spell.MinRange) { return(false); } // do we have enough power? if (Me.GetCurrentPower(spell.PowerType) < spell.PowerCost) { return(false); } return(true); }