public void Initialize(IClassRotation specialization)
        {
            settings = WarlockSettings.Current;
            if (settings.PartyDrinkName != "")
            {
                ToolBox.AddToDoNotSellList(settings.PartyDrinkName);
            }
            cast = new Cast(ShadowBolt, UseWand, settings);

            this.specialization          = specialization as Warlock;
            (RotationType, RotationRole) = ToolBox.GetRotationType(specialization);
            TalentsManager.InitTalents(settings);

            WarlockPetAndConsumables.Setup();

            _petPulseThread.DoWork += PetThread;
            _petPulseThread.RunWorkerAsync();

            RangeManager.SetRange(ShadowBolt.MaxRange);

            // Set pet mode
            if (settings.PetInPassiveWhenOOC)
            {
                Lua.LuaDoString("PetPassiveMode();");
            }
            else
            {
                Lua.LuaDoString("PetDefensiveMode();");
            }

            FightEvents.OnFightEnd   += FightEndHandler;
            FightEvents.OnFightStart += FightStartHandler;

            Rotation();
        }
        private void FightStartHandler(WoWUnit unit, CancelEventArgs cancelable)
        {
            if (UseWand.IsSpellUsable)
            {
                _iCanUseWand = true;
            }
            Lua.LuaDoString("PetDefensiveMode();");

            // Imp Firebolt
            if (WarlockPetAndConsumables.MyWarlockPet().Equals("Imp"))
            {
                ToolBox.TogglePetSpellAuto("Firebolt", true);
            }

            // Imp BloodPact
            if (WarlockPetAndConsumables.MyWarlockPet().Equals("Imp"))
            {
                ToolBox.TogglePetSpellAuto("Blood Pact", true);
            }
        }
        protected override void BuffRotation()
        {
            if (!Me.HaveBuff("Drink") || Me.ManaPercentage > 95)
            {
                base.BuffRotation();

                // Unending Breath
                if (!Me.HaveBuff("Unending Breath") &&
                    settings.UseUnendingBreath &&
                    cast.OnSelf(UnendingBreath))
                {
                    return;
                }

                // Demon Skin
                if (!Me.HaveBuff("Demon Skin") &&
                    !DemonArmor.KnownSpell &&
                    !FelArmor.KnownSpell &&
                    cast.OnSelf(DemonSkin))
                {
                    return;
                }

                // Demon Armor
                if ((!Me.HaveBuff("Demon Armor")) &&
                    !FelArmor.KnownSpell &&
                    cast.OnSelf(DemonArmor))
                {
                    return;
                }

                // Fel Armor
                if (!Me.HaveBuff("Fel Armor") &&
                    cast.OnSelf(FelArmor))
                {
                    return;
                }

                // Health Funnel OOC
                if (ObjectManager.Pet.HealthPercent < 50 &&
                    Me.HealthPercent > 40 &&
                    ObjectManager.Pet.GetDistance < 19 &&
                    !ObjectManager.Pet.InCombatFlagOnly &&
                    settings.HealthFunnelOOC)
                {
                    Lua.LuaDoString("PetWait();");
                    MovementManager.StopMove();
                    Fight.StopFight();

                    if (WarlockPetAndConsumables.MyWarlockPet().Equals("Voidwalker"))
                    {
                        cast.PetSpell("Consume Shadows", false, true);
                    }

                    if (cast.OnSelf(HealthFunnel))
                    {
                        Thread.Sleep(500);
                        Usefuls.WaitIsCasting();
                        Lua.LuaDoString("PetFollow();");
                        return;
                    }
                    Lua.LuaDoString("PetFollow();");
                }

                // Health Stone
                if (!WarlockPetAndConsumables.HaveHealthstone() &&
                    cast.OnSelf(CreateHealthStone))
                {
                    return;
                }

                // Create Soul Stone
                if (!WarlockPetAndConsumables.HaveSoulstone() &&
                    cast.OnSelf(CreateSoulstone))
                {
                    return;
                }

                // PARTY Soul Stone
                if (CreateSoulstone.KnownSpell &&
                    ToolBox.HaveOneInList(WarlockPetAndConsumables.SoulStones()) &&
                    ToolBox.GetItemCooldown(WarlockPetAndConsumables.SoulStones()) <= 0)
                {
                    WoWPlayer noSoulstone = AIOParty.GroupAndRaid
                                            .Find(m => !m.HaveBuff("Soulstone Resurrection") &&
                                                  m.GetDistance < 20 &&
                                                  m.Name != "Unknown" &&
                                                  !TraceLine.TraceLineGo(Me.Position, m.Position) &&
                                                  (m.WowClass == WoWClass.Paladin || m.WowClass == WoWClass.Priest || m.WowClass == WoWClass.Shaman || m.WowClass == WoWClass.Druid));
                    if (noSoulstone != null)
                    {
                        Logger.Log($"Using Soulstone on {noSoulstone.Name}");
                        MovementManager.StopMoveNewThread();
                        MovementManager.StopMoveToNewThread();
                        Lua.RunMacroText($"/target {noSoulstone.Name}");
                        if (ObjectManager.Target.Name == noSoulstone.Name)
                        {
                            ToolBox.UseFirstMatchingItem(WarlockPetAndConsumables.SoulStones());
                            Usefuls.WaitIsCasting();
                            Lua.RunMacroText("/cleartarget");
                            ToolBox.ClearCursor();
                        }
                    }
                }

                // PARTY Drink
                if (AIOParty.PartyDrink(settings.PartyDrinkName, settings.PartyDrinkThreshold))
                {
                    return;
                }

                // Life Tap
                if (Me.HealthPercent > Me.ManaPercentage &&
                    settings.UseLifeTap &&
                    cast.OnSelf(LifeTap))
                {
                    return;
                }
            }
        }
        protected override void BuffRotation()
        {
            base.BuffRotation();

            // Life Tap
            if (Me.HealthPercent > Me.ManaPercentage &&
                settings.UseLifeTap &&
                !Me.IsMounted &&
                cast.OnSelf(LifeTap))
            {
                return;
            }

            // Unending Breath
            if (!Me.HaveBuff("Unending Breath") &&
                settings.UseUnendingBreath &&
                cast.OnSelf(UnendingBreath))
            {
                return;
            }

            // Fel Armor
            if (!Me.HaveBuff("Fel Armor") &&
                settings.UseFelArmor &&
                cast.OnSelf(FelArmor))
            {
                return;
            }

            // Demon Armor
            if (!Me.HaveBuff("Demon Skin") &&
                !Me.HaveBuff("Demon Armor") &&
                !Me.HaveBuff("Fel Armor") &&
                cast.OnSelf(DemonArmor))
            {
                return;
            }

            // Demon Skin
            if (!Me.HaveBuff("Demon Skin") &&
                !Me.HaveBuff("Demon Armor") &&
                !Me.HaveBuff("Fel Armor") &&
                cast.OnSelf(DemonSkin))
            {
                return;
            }

            // Soul Link
            if (!Me.HaveBuff("Soul Link") &&
                ObjectManager.Pet.IsAlive &&
                cast.OnSelf(SoulLink))
            {
                return;
            }

            // Health Funnel OOC
            if (ObjectManager.Pet.HealthPercent < 50 &&
                Me.HealthPercent > 40 &&
                ObjectManager.Pet.GetDistance < 19 &&
                !ObjectManager.Pet.InCombatFlagOnly &&
                settings.HealthFunnelOOC)
            {
                Lua.LuaDoString("PetWait();");
                MovementManager.StopMove();
                Fight.StopFight();

                if (WarlockPetAndConsumables.MyWarlockPet().Equals("Voidwalker"))
                {
                    cast.PetSpell("Consume Shadows", false, true);
                }

                if (cast.OnSelf(HealthFunnel))
                {
                    Thread.Sleep(500);
                    Usefuls.WaitIsCasting();
                    Lua.LuaDoString("PetFollow();");
                    return;
                }
                Lua.LuaDoString("PetFollow();");
            }

            // Health Stone
            if (!WarlockPetAndConsumables.HaveHealthstone() &&
                cast.OnSelf(CreateHealthStone))
            {
                return;
            }

            // Create Soul Stone
            if (!WarlockPetAndConsumables.HaveSoulstone() &&
                cast.OnSelf(CreateSoulstone))
            {
                return;
            }

            // Use Soul Stone
            if (!Me.HaveBuff("Soulstone Resurrection") &&
                CreateSoulstone.KnownSpell &&
                ToolBox.HaveOneInList(WarlockPetAndConsumables.SoulStones()) &&
                ToolBox.GetItemCooldown(WarlockPetAndConsumables.SoulStones()) <= 0)
            {
                MovementManager.StopMoveNewThread();
                MovementManager.StopMoveToNewThread();
                Lua.RunMacroText("/target player");
                ToolBox.UseFirstMatchingItem(WarlockPetAndConsumables.SoulStones());
                Usefuls.WaitIsCasting();
                Lua.RunMacroText("/cleartarget");
            }
        }
        protected override void CombatRotation()
        {
            base.CombatRotation();

            WoWUnit Me                    = ObjectManager.Me;
            WoWUnit Target                = ObjectManager.Target;
            double  _myManaPC             = Me.ManaPercentage;
            bool    _overLowManaThreshold = _myManaPC > _innerManaSaveThreshold;

            // Drain Soul
            bool _shouldDrainSoul = ToolBox.CountItemStacks("Soul Shard") < settings.NumberOfSoulShards || settings.AlwaysDrainSoul;

            if (_shouldDrainSoul &&
                ObjectManager.Target.HealthPercent < settings.DrainSoulHP &&
                ObjectManager.Target.Level >= Me.Level - 8 &&
                !UnitImmunities.Contains(ObjectManager.Target, "Drain Soul(Rank 1)"))
            {
                if (settings.DrainSoulLevel1 &&
                    cast.OnTarget(DrainSoulRank1))
                {
                    return;
                }
                else if (cast.OnTarget(DrainSoul))
                {
                    return;
                }
            }

            // How of Terror
            if (ToolBox.GetNumberEnemiesAround(10f, Me) > 1 &&
                cast.OnSelf(HowlOfTerror))
            {
                return;
            }

            // Use Health Stone
            if (Me.HealthPercent < 15)
            {
                WarlockPetAndConsumables.UseHealthstone();
            }

            // Shadow Trance
            if (Me.HaveBuff("Shadow Trance") &&
                _overLowManaThreshold &&
                cast.OnTarget(ShadowBolt))
            {
                return;
            }

            // Siphon Life
            if (Me.HealthPercent < 90 &&
                _overLowManaThreshold &&
                Target.HealthPercent > 20 &&
                !Target.HaveBuff("Siphon Life") &&
                settings.UseSiphonLife &&
                cast.OnTarget(SiphonLife))
            {
                return;
            }

            // Death Coil
            if (Me.HealthPercent < 20 &&
                cast.OnTarget(DeathCoil))
            {
                return;
            }

            // Drain Life low
            if (Me.HealthPercent < 30 &&
                Target.HealthPercent > 20 &&
                cast.OnTarget(DrainLife))
            {
                return;
            }

            // Curse of Agony
            if (!Target.HaveBuff("Curse of Agony") &&
                _overLowManaThreshold &&
                Target.HealthPercent > 20 &&
                cast.OnTarget(CurseOfAgony))
            {
                return;
            }

            // Unstable Affliction
            if (!Target.HaveBuff("Unstable Affliction") &&
                _overLowManaThreshold &&
                Target.HealthPercent > 30 &&
                cast.OnTarget(UnstableAffliction))
            {
                return;
            }

            // Corruption
            if (!Target.HaveBuff("Corruption") &&
                _overLowManaThreshold &&
                Target.HealthPercent > 20 &&
                cast.OnTarget(Corruption))
            {
                return;
            }

            // Immolate
            if (!Target.HaveBuff("Immolate") &&
                !ObjectManager.Target.HaveBuff("Fire Ward") &&
                _overLowManaThreshold &&
                Target.HealthPercent > 30 &&
                (settings.UseImmolateHighLevel || !UnstableAffliction.KnownSpell) &&
                cast.OnTarget(Immolate))
            {
                return;
            }

            // Drain Life high
            if (Me.HealthPercent < 70 &&
                Target.HealthPercent > 20 &&
                cast.OnTarget(DrainLife))
            {
                return;
            }

            // Health Funnel
            if (ObjectManager.Pet.IsValid &&
                ObjectManager.Pet.HealthPercent < 30 &&
                Me.HealthPercent > 30)
            {
                if (RangeManager.GetRange() > 19)
                {
                    RangeManager.SetRange(19f);
                }
                if (HealthFunnel.IsDistanceGood && cast.OnTarget(HealthFunnel))
                {
                    return;
                }
            }

            // Dark Pact
            if (Me.ManaPercentage < 70 &&
                ObjectManager.Pet.Mana > 0 &&
                ObjectManager.Pet.ManaPercentage > 60 &&
                settings.UseDarkPact &&
                cast.OnSelf(DarkPact))
            {
                return;
            }

            // Drain Mana
            if (Me.ManaPercentage < 70 &&
                Target.Mana > 0 &&
                Target.ManaPercentage > 30 &&
                cast.OnTarget(DrainMana))
            {
                return;
            }

            // Incinerate
            if (Target.HaveBuff("Immolate") &&
                _overLowManaThreshold &&
                Target.HealthPercent > 30 &&
                settings.UseIncinerate &&
                cast.OnTarget(Incinerate))
            {
                return;
            }

            // Shadow Bolt
            if ((!settings.PrioritizeWandingOverSB || !_iCanUseWand) &&
                (ObjectManager.Target.HealthPercent > 50 || Me.ManaPercentage > 90 && ObjectManager.Target.HealthPercent > 10) &&
                _myManaPC > 40 &&
                cast.OnTarget(ShadowBolt))
            {
                return;
            }

            // Life Tap
            if (Me.HealthPercent > 50 &&
                Me.ManaPercentage < 40 &&
                !ObjectManager.Target.IsTargetingMe &&
                settings.UseLifeTap &&
                cast.OnSelf(LifeTap))
            {
                return;
            }

            // Stop wand if banned
            if (ToolBox.UsingWand() &&
                UnitImmunities.Contains(ObjectManager.Target, "Shoot") &&
                cast.OnTarget(UseWand))
            {
                return;
            }

            // Spell if wand banned
            if (UnitImmunities.Contains(ObjectManager.Target, "Shoot") &&
                cast.OnTarget(ShadowBolt))
            {
                return;
            }

            // Use Wand
            if (!ToolBox.UsingWand() &&
                _iCanUseWand &&
                cast.OnTarget(UseWand, false))
            {
                return;
            }

            // Go in melee because nothing else to do
            if (!ToolBox.UsingWand() &&
                !UseWand.IsSpellUsable &&
                !RangeManager.CurrentRangeIsMelee() &&
                Target.IsAlive)
            {
                Logger.Log("Going in melee");
                RangeManager.SetRangeToMelee();
                return;
            }
        }
        // Pet thread
        protected void PetThread(object sender, DoWorkEventArgs args)
        {
            while (Main.isLaunched)
            {
                try
                {
                    if (StatusChecker.BasicConditions() &&
                        ObjectManager.Pet.IsValid &&
                        ObjectManager.Pet.IsAlive)
                    {
                        bool multiAggroImTargeted = false;
                        // Pet Switch target on multi aggro
                        if (Me.InCombatFlagOnly &&
                            ObjectManager.GetNumberAttackPlayer() > 1)
                        {
                            Lua.LuaDoString("PetDefensiveMode();");
                            // Get list of units targeting me in a multiaggro situation
                            List <WoWUnit> unitsAttackingMe = ObjectManager.GetUnitAttackPlayer()
                                                              .OrderBy(u => u.Guid)
                                                              .Where(u => u.TargetObject.Guid == Me.Guid)
                                                              .ToList();

                            foreach (WoWUnit unit in unitsAttackingMe)
                            {
                                multiAggroImTargeted = true;
                                if (unit.Guid != ObjectManager.Pet.TargetObject.Guid &&
                                    ObjectManager.Pet.TargetObject.Target == ObjectManager.Pet.Guid)
                                {
                                    Logger.Log($"Forcing pet aggro on {unit.Name}");
                                    Me.FocusGuid = unit.Guid;
                                    cast.PetSpell("PET_ACTION_ATTACK", true);
                                    if (WarlockPetAndConsumables.MyWarlockPet().Equals("Voidwalker"))
                                    {
                                        cast.PetSpell("Torment", true);
                                        cast.PetSpell("Suffering", true);
                                    }
                                    if (WarlockPetAndConsumables.MyWarlockPet().Equals("Felguard"))
                                    {
                                        cast.PetSpell("Anguish", true);
                                    }
                                    Lua.LuaDoString("ClearFocus();");
                                }
                            }
                        }

                        // Pet attack on single aggro
                        if ((Me.InCombatFlagOnly || Fight.InFight) &&
                            Me.Target > 0 &&
                            !multiAggroImTargeted)
                        {
                            Lua.LuaDoString("PetAttack();", false);
                        }

                        // Voidwalker Torment + Felguard Anguish
                        if ((!settings.AutoTorment || !settings.AutoAnguish) &&
                            ObjectManager.Target.Target == Me.Guid &&
                            Me.InCombatFlagOnly)
                        {
                            if (WarlockPetAndConsumables.MyWarlockPet().Equals("Voidwalker"))
                            {
                                if (cast.PetSpell("Torment") || cast.PetSpell("Suffering"))
                                {
                                    continue;
                                }
                            }
                            if (WarlockPetAndConsumables.MyWarlockPet().Equals("Felguard"))
                            {
                                if (cast.PetSpell("Anguish"))
                                {
                                    continue;
                                }
                            }
                        }

                        // Switch Auto Torment & Suffering off
                        if (WarlockPetAndConsumables.MyWarlockPet().Equals("Voidwalker"))
                        {
                            ToolBox.TogglePetSpellAuto("Torment", settings.AutoTorment);
                            ToolBox.TogglePetSpellAuto("Suffering", false);
                        }

                        // Switch Felguard Auto Cleave/Anguish
                        if (WarlockPetAndConsumables.MyWarlockPet().Equals("Felguard") && specialization.RotationType == Enums.RotationType.Solo)
                        {
                            ToolBox.TogglePetSpellAuto("Cleave", settings.FelguardCleave);
                            ToolBox.TogglePetSpellAuto("Anguish", settings.AutoAnguish);
                        }
                    }
                }
                catch (Exception arg)
                {
                    Logging.WriteError(string.Concat(arg), true);
                }
                Thread.Sleep(300);
            }
        }
        protected virtual void BuffRotation()
        {
            // Delete additional Soul Shards
            if (ToolBox.CountItemStacks("Soul Shard") > settings.NumberOfSoulShards)
            {
                Logger.Log("Deleting excess Soul Shard");
                ToolBox.LuaDeleteOneItem("Soul Shard");
            }

            // Define the demon to summon
            AIOSpell SummonSpell  = null;
            bool     shouldSummon = false;

            if (SummonImp.KnownSpell)
            {
                if (ToolBox.CountItemStacks("Soul Shard") < 1 || !SummonVoidwalker.KnownSpell && !SummonFelguard.KnownSpell)
                {
                    SummonSpell = SummonImp;
                }

                if (SummonVoidwalker.KnownSpell && !SummonFelguard.KnownSpell)
                {
                    SummonSpell = SummonVoidwalker;
                }

                if (specialization.RotationType == Enums.RotationType.Party)
                {
                    SummonSpell = SummonImp;
                }

                if (SummonFelguard.KnownSpell)
                {
                    SummonSpell = SummonFelguard;
                }

                if (!ObjectManager.Pet.IsValid ||
                    ObjectManager.Pet.ManaPercentage < settings.ManaThresholdResummon && SummonSpell != SummonImp ||
                    ObjectManager.Pet.HealthPercent < settings.HealthThresholdResummon ||
                    !SummonSpell.Name.Contains(WarlockPetAndConsumables.MyWarlockPet()))
                {
                    shouldSummon = true;
                }
            }

            if (shouldSummon)
            {
                // Make sure we have mana to summon
                if (ObjectManager.Me.Mana < SummonSpell.Cost &&
                    !ObjectManager.Me.HaveBuff("Drink") &&
                    !Me.InCombatFlagOnly)
                {
                    Logger.Log($"Not enough mana to summon {SummonSpell.Name}, forcing regen");
                    wManager.wManagerSetting.CurrentSetting.DrinkPercent = 95;
                    Thread.Sleep(1000);
                    return;
                }

                Thread.Sleep(Usefuls.Latency + 500); // Safety for Mount check
                if (!ObjectManager.Me.IsMounted && !ObjectManager.Me.IsOnTaxi)
                {
                    if (cast.OnSelf(FelDomination))
                    {
                        Thread.Sleep(200);
                    }
                    if (cast.OnSelf(SummonSpell))
                    {
                        Usefuls.WaitIsCasting();
                        Thread.Sleep(1000); // Prevent double summon
                        return;
                    }
                }
            }
            else
            {
                wManager.wManagerSetting.CurrentSetting.DrinkPercent = _saveDrinkPercent;
            }
        }