Can anyone compare warlock rotation and shadow priest rotation? Which on is more complex? Which one is harder to code? I don't have a warlock and I have zero experience on how it work so I just want to ask Thank you.
Code: using System;using System.Collections.Generic; using System.Linq; using Styx; using Styx.CommonBot; using Styx.CommonBot.Routines; using Styx.TreeSharp; using Styx.WoWInternals; using Styx.WoWInternals.WoWObjects; using Action = Styx.TreeSharp.Action; namespace Armed { internal class Afflicted : CombatRoutine { #region Generic Wrapper Stuff private Composite _buffs; private Composite _combat; public override string Name { get { return "Afflicted"; } } public override WoWClass Class { get { return WoWClass.Warlock; } } public override Composite CombatBehavior { get { return _combat ?? (_combat = CreateCombat()); } } private WoWUnit GetTargetMissingDebuff(WoWUnit near, string debuff, float distance = -1f) { return UnfriendlyUnits.FirstOrDefault(u => u.Location.Distance(near.Location) <= distance && !u.HasAura(debuff, 1, true)); } private int EnemiesNearTarget(float range) { var target = StyxWoW.Me.CurrentTarget; if (target == null) return 0; var tarLoc = target.Location; return UnfriendlyUnits.Count(u => u.Guid != target.Guid && u.Location.Distance(tarLoc) <= range); } private IEnumerable<WoWUnit> UnfriendlyUnits { get { return ObjectManager.GetObjectsOfType<WoWUnit>(true, false).Where(u => !u.IsDead && u.CanSelect && u.Attackable && !u.IsFriendly); } } private void UseTrinkets() { WoWItem firstTrinket = StyxWoW.Me.Inventory.Equipped.Trinket1; WoWItem secondTrinket = StyxWoW.Me.Inventory.Equipped.Trinket2; if (firstTrinket != null && CanUseEquippedItem(firstTrinket)) firstTrinket.Use(); if (secondTrinket != null && CanUseEquippedItem(secondTrinket)) secondTrinket.Use(); } private static bool CanUseEquippedItem(WoWItem item) { // Check for engineering tinkers! var itemSpell = Lua.GetReturnVal<string>("return GetItemSpell(" + item.Entry + ")", 0); if (string.IsNullOrEmpty(itemSpell)) return false; return item.Usable && item.Cooldown <= 0; } private Composite Cast(string spell, Selection<bool> reqs = null, Selection<WoWUnit> onTarget = null, bool ignoreCheck = false) { return new Decorator( ret => (((reqs != null && reqs(ret)) || (reqs == null)) && SpellManager.CanCast(spell)) || ignoreCheck, new Action(ret => SpellManager.Cast(spell, (onTarget != null ? onTarget(ret) : null)))); } private Composite Debuff(string spell, Selection<bool> reqs = null, Selection<WoWUnit> onTarget = null, int msLeft = 0, bool ignoreCheck = false) { return new Decorator( ret => (((reqs != null && reqs(ret)) || (reqs == null)) && (ignoreCheck || SpellManager.CanCast(spell))) && !(onTarget != null ? onTarget(ret) : StyxWoW.Me.CurrentTarget).HasAura(spell, 0, true, msLeft), new Action(ret => { var castingSpell = StyxWoW.Me.CastingSpell; if (castingSpell != null && castingSpell.Name != spell) Lua.DoString("SpellStopCasting()"); SpellManager.Cast(spell, (onTarget != null ? onTarget(ret) : null)); })); } private Composite Apply(string spell, Selection<bool> reqs = null, Selection<WoWUnit> onTarget = null, int msLeft = 0, bool ignoreCanCast = false) { return new Decorator(ret => { if (reqs != null && !reqs(ret)) return false; var target = onTarget != null ? onTarget(ret) : StyxWoW.Me.CurrentTarget; if (!ignoreCanCast && !SpellManager.CanCast(spell, target)) return false; if (!target.HasAura(spell, 1, true, msLeft)) return true; return false; }, new Action(ret => { var castingSpell = StyxWoW.Me.CastingSpell; if (castingSpell != null && castingSpell.Name != spell) Lua.DoString("SpellStopCasting()"); SpellManager.Cast(spell, (onTarget != null ? onTarget(ret) : null)); })); } public static TimeSpan GetSpellCooldown(string spell) { SpellFindResults results; if (SpellManager.FindSpell(spell, out results)) { if (results.Override != null) return results.Override.CooldownTimeLeft; return results.Original.CooldownTimeLeft; } return TimeSpan.MaxValue; } private delegate T Selection<out T>(object context); #endregion #region Actual Logic public Composite CreateCombat() { return new PrioritySelector( // Free haste. Use it on CD. Cast("Dark Soul: Misery"), Cast("Life Tap", ret=>StyxWoW.Me.ManaPercent <= 35 && StyxWoW.Me.HealthPercent >= 60), CreateAoeCombat(), // Debuff CoE, refresh when <= 1500ms left on the debuff. Debuff("Curse of the Elements", msLeft:2000), Debuff("Haunt", ret=>StyxWoW.Me.CurrentSoulShards >= 1, msLeft:2500, ignoreCheck:true), Debuff("Agony", msLeft: 2000, ignoreCheck: true), Debuff("Corruption", msLeft: 2000, ignoreCheck: true), Debuff("Unstable Affliction", msLeft: 2500, ignoreCheck: true), new Decorator(ret=>!StyxWoW.Me.IsMoving, new PrioritySelector( Cast("Drain Soul", ret=>StyxWoW.Me.CurrentTarget.HealthPercent < 20), Cast("Malefic Grasp") )), Cast("Fel Flame", ret=>!StyxWoW.Me.IsChanneling) ); } public Composite CreateAoeCombat() { // More than 4 mobs near our current target, start the AOE rotation. return new Decorator(ret => EnemiesNearTarget(15) >= 4, new PrioritySelector( Cast("Soulburn", ret=>!StyxWoW.Me.HasAura("Soulburn")), Cast("Curse of the Elements", null, ret => GetTargetMissingDebuff(StyxWoW.Me.CurrentTarget, "Curse of the Elements", 15f)), Cast("Seed of Corruption") )); } #endregion } public static class Extensions { public static bool HasAura(this WoWUnit unit, string aura, int stacks, bool isMyAura = false, int msLeft = 0) { var result = unit.GetAuraByName(aura); if (result == null) return false; if (isMyAura && result.CreatorGuid != StyxWoW.Me.Guid) return false; if (result.TimeLeft.TotalMilliseconds > msLeft) return result.StackCount >= stacks; return false; } } } There, that should interrupt a few things from happening, and hopefully stop the double-casts on haunt/UA.
Im so on this when i get home. Im a nub to codeing, so not sure how to save this. Can you give me a quick idea? I can open on a current cc when i get home and poke around, but really want to test this asap. reforgeing, gemming, enchanting helps a TON. I went from 40k to 70k on some fights. Apoc, whats your donate link? Ill see if i can find some extra cash
Copy and paste the code into a text editor (Such as Notepad) and save it as a .cs file. Then place it in your Honorbuddy/Routines folder as normal and enjoy!
That sounds ok. Special name? Than just choose it when it pops up. It will list it along with CLU and what ever else for my class I've got? Do I need another folder listed as warlock?
This is what i found with my stats on a heroic dummy in stormwind self buffed. ilvl 483 sp 24,190 haste 3,491 hit 9.43 crit 12.37 mastery 61.79 Afflicted 43,000 (Agony very very tight) i sware to god its .1 or less before it falls off. corruption falls off but that doesnt seem to mater. CLU 46,000 FTW 26,000 (Agony falls off) Singular 41,000 (Agony falls off) Clu and this seem to be the best on dummies. Going to test it in a heroic//raid asap