Example #1
0
        public override bool Do()
        {
            if (em == null)
            {
                return(true);                // WTF!
            }
            // mount if we're really far away
            if (monster.DistanceToSelf >= mountRange)
            {
                if (PPather.PatherSettings.UseMount != "Never Mount")
                {
                    if (PPather.PatherSettings.UseMount == "Always Mount" ||
                        (PPather.PatherSettings.UseMount == "Let Task Decide" &&
                         UseMount == true))
                    {
                        Helpers.Mount.MountUp();
                    }
                }
            }

            if (GContext.Main.Me.Target != monster &&
                tabSpam.IsReady &&
                monster.DistanceToSelf < 50f &&
                monster.Reaction != GReaction.Friendly)
            {
                GContext.Main.SendKey("Common.Target");
                tabSpam.Reset();
            }

            if (GetLocation().GetDistanceTo(to) > GContext.Main.MeleeDistance &&
                monster.DistanceToSelf < 30f || updateTimer.IsReady)
            {
                // need a new path, monster moved
                to = GetLocation();
                em = new EasyMover(ppather, to, false, true);
                updateTimer.Reset();
            }

            MoveResult = em.move(howClose);
            if (MoveResult != EasyMover.MoveResult.Moving)
            {
                return(true);                // done, can't do more
            }
            Location meLocation = new Location(GContext.Main.Me.Location);

            if (meLocation.GetDistanceTo(to) < howClose)
            {
                PPather.mover.Stop();
                Helpers.Mount.Dismount();
                monster.Face(PPather.PI / 8);
                return(true);
            }
            return(false);
        }
        //Combat overrride
        public override GCombatResult KillTarget(GUnit Target, bool IsAmbush)
        {
            //Stop walking/turning
            Context.ReleaseSpinRun();
            /* RecursiveBot 2.17.1 A
             * the following is the logical switch to control if the spell
             * shuffle function is called. This removes the randomizing of spells
             * but does not give the ability to cast them in any order.
             */
            if (USE_SPELLSHUFFLE)
            {
                SpellShuffle(ref SPELL_ORDER);
            }
            SoulShardCount = CountSoulShards();
            Reset();

            //Call function to wait for player death
            if (Target.IsPlayer)
            {
                if (((GPlayer)Target).IsSameFaction)
                {
                    Context.ClearTarget();
                    return GCombatResult.Success;
                }
                else if (FIGHT_BACK)
                {
                    Context.Log("Attempting PVP...");
                    return PVP(Target);
                }
                else
                {
                    Context.Log("No PVP");
                    WaitForPlayerDeath();
                    return GCombatResult.Died;
                }
            }

            //Send in pet and wait for predefined amount of time
            /* RecursiveBot 2.17.1 G
             * The following change was to ensure that multiple Petattacks weren't sent
             * due to the logic flow.
             */
            if (Me.HasLivePet && PET_ATTACK && !Me.Pet.IsInCombat)
            {
                SendKey("Common.PetAttack");
              //Context.Log("DBG - KillTarget Send Pet routine started!");
                if (WAIT_FOR_PET_AGGRO)
                {
                    Context.Log("Waiting for pet to approach target");
                    bool temp;
                    temp = WaitForEngage(Target,(PET_AGGRO_DELAY * 1000));
                    if (temp)
                    {
                        Context.Log("Pet aggroed target");
                    }
                    else
                    {
                        Context.Log("Pet failed to aggro target");
                    }
                }
                Thread.Sleep(500);
            }

            while (true)
            {
                //Refresh the target
                Target.Refresh(true);

                //Check the current GCombatResult
                GCombatResult CommonResult = Context.CheckCommonCombatResult((GMonster)Target, IsAmbush);

                //Return the GCombatResult
                if (CommonResult != GCombatResult.Unknown)
                {
                    SoulShardCount = CountSoulShards();
                    if (USE_CONSUMESHADOWS)
                    {
                        TwoSecTimer.Reset();
                        while (!TwoSecTimer.IsReady)
                        {
                            Thread.Sleep(150);
                            if (!Me.IsInCombat)
                            {
                                TwoSecTimer.ForceReady();
                            }
                        }
                        PetHealth();
                    }
                    return CommonResult;
                }
                else if (Target.IsDead)
                {
                    SoulShardCount = CountSoulShards();
                    if (USE_CONSUMESHADOWS)
                    {
                        TwoSecTimer.Reset();
                        while (!TwoSecTimer.IsReady)
                        {
                            Thread.Sleep(100);
                            if (!Me.IsInCombat)
                            {
                                TwoSecTimer.ForceReady();
                            }
                        }
                        // PetHealth(); //Moved to outside of If statement to resolve pet deaths
                    }
                    return GCombatResult.Success;
                }

                PetHealth();
                Target.Face();

                if (Me.HasLivePet && PET_ATTACK && RETURN_PET && DoReturnPet && Target.Health < HealthToReturnPet && Target.DistanceToSelf > 10 && Target.Target == Me.Pet)
                {
                    Context.Log("Returning the pet to me! Come to papa!");
                    SendKey("Common.PetFollow");
                    DoReturnPet = false;
                }

                if (Target.DistanceToSelf > PullDistance && Target.DistanceToSelf < (PullDistance + TARGET_DUMP_DISTANCE))
                {
                    Target.Approach(PullDistance - 2, false);
                }

                if (Target.DistanceToSelf > (PullDistance + TARGET_DUMP_DISTANCE))
                {
                    Context.ClearTarget();
                    return GCombatResult.Success;
                }

                //Stop Walking, Face
                Context.ReleaseSpinRun();

                TargetUnit(Target, false);

                //Deal with players
                if (FIGHT_BACK)
                {
                    //Decide what to do depending on what is returned
                    switch (CheckPlayers(Target))
                    {
                        case 0:
                            break;
                        case 1:
                            Context.Log("Targeted by enemy faction, fighting back!");
                            return GCombatResult.SuccessWithAdd;
                        case -1:
                            Context.Log("Target by enemy faction but unable to target them");
                            break;
                    }
                }

                //Deal with adds
                //Context.Log("DBG - Are we set to deal with adds?" + DEAL_WITH_ADDS);
                if (DEAL_WITH_ADDS)
                {
                   // Context.Log("DBG - Starting Check Add's function call");
                    CheckAdds(Target);
                }

                //Check health
                //Context.Log("DBG - Me.IsInCombat is returning" + Me.IsInCombat);
                CheckHealth(Me.IsInCombat); //Changed Parameter from true to Me.IsInCombat
                //Check pet

                /* RecursiveBot 2.17.1 B
                 * The following was changed to check if the player is mounted before running
                 * CheckPet() due to the fact that checkpet would call for a resummon upon
                 * finding a target and not having a pet.
                 * This is a quick fix. Logic for checking a pet might need rework.
                 */
                if (!IsMounted(Me))
                {
                    CheckPet();
                }
                if (!Target.IsDead)
                {
                    //Cast Debuffs
                    //Context.Log("DBG - Test Target Not Dead code initiated");

                    CastSequence(Target, false);
                    ShadowCheck(Target);
                    //Check various things
                    if (PetHealth())
                    {
                    }
                    else if (DrainSoul(Target))
                    {
                    }
                    else if (DrainLife(Target, false))
                    {
                    }
                    else if (PrimaryAttack(Target))
                    {
                    }
                    else if (CheckMana(Target) && !IsMounted())
                    {
                    }
                    else LastResort(Target);
                }
                Thread.Sleep(150);
            }
        }
 //Cast wand
 void Wand(GUnit Target)
 {
     Target.Face();
     if (!Interface.IsKeyFiring("PL.Wand"))
     {
         SendKey("PL.Wand");
         Thread.Sleep(MISCDELAY);
     }
 }
 //Target a specified unit if not already targeted
 void TargetUnit(GUnit Target, bool FirstTarget)
 {
     Target.Refresh(true);
     if (Target.IsDead || (Me.TargetGUID == Target.GUID)) return;
     Target.Face();
     Target.SetAsTarget(FirstTarget);
 }
        //PVP combat function
        GCombatResult PVP(GUnit Target)
        {
            PVPTimer.Reset();
            //Reset timers
            Reset();
            //Sets an anchor to keep from getting too far away
            GLocation startLocation = Me.Location;
            //Send in pet and wait for predefined amount of time
            if (Me.HasLivePet && PET_ATTACK)
            {
                SendKey("Common.PetAttack");
            }

            if (Target.DistanceToSelf > FearRange) Target.Approach(FearRange - 3, false);
            CastSpell("PL.Fear", Target);

            //While less than PVPTimer seconds passed...
            while (!PVPTimer.IsReady)
            {
                Target.Refresh(true);

                //If target is dead, return to start point and report Success
                if (Target.IsDead)
                {
                    SoulShardCount = CountSoulShards();
                    Context.Log("Killed target, returning to start");
                    Movement.MoveToLocation(startLocation, 20, false);
                    return GCombatResult.Success;
                }
                //If further than 40 away from start, return to start point and report Success
                else if (startLocation.DistanceToSelf > (PullDistance + TARGET_DUMP_DISTANCE))
                {
                    SoulShardCount = CountSoulShards();
                    Context.Log("Straying too far, returning to start");
                    Movement.MoveToLocation(startLocation, 20, false);
                    return GCombatResult.Success;
                }

                Me.Refresh(true);
                if (Me.IsDead)
                {
                    return GCombatResult.Died;
                }

                //If target further than PullDistance and less than 60, approach to PullDistance
                if (Target.DistanceToSelf > PullDistance && Target.DistanceToSelf < (PullDistance + TARGET_DUMP_DISTANCE)) Target.Approach(PullDistance - 3, false);

                if (Target.DistanceToSelf > (PullDistance + TARGET_DUMP_DISTANCE)) //Added 2.15 dump target if too far
                {
                    Context.Log("We tried to fight " + Target.Name + " but we travelled > " + TARGET_DUMP_DISTANCE + " to fight him. Resetting!");
                    SendKey("Common.ClearTargetMacro");
                    if (Me.HasLivePet && RETURN_PET)
                    {
                        Context.Log("Recalling Pet.");
                        SendKey("Common.PetFollow");
                    }
                    return GCombatResult.Success;
                }

                //Stop Walking, Face
                Context.ReleaseSpinRun();
                Target.Face();

                TargetUnit(Target, false);

                //Check health
                CheckHealth(Me.IsInCombat);

                /* RecursiveBot 2.17.1 B
                 * Following check is to ensure that we don't resummon a pet needlessly. Quick fix
                 * to the summon new pet every time your mounted and have a target.
                 */
                if (!IsMounted(Me))
                {
                    CheckPet();
                }
                if (!Target.IsDead)
                {
                    //Cast Debuffs

                    CastSequence(Target, false);

                    //Cast Fear
                    if (Fear.IsReady)
                    {
                        if (Target.DistanceToSelf > FearRange) Target.Approach(FearRange - 3, false);
                        CastSpell("PL.Fear", Target);
                        Fear.Reset();
                    }
                    ShadowCheck(Target);
                    //Check various things
                    if (PetHealth())
                    {
                    }
                    /*else if (DrainSoul(Target))
                    {
                    }*/
                    else if (CheckMana(Target))
                    {
                    }
                    else if (DrainLife(Target, false))
                    {
                    }
                    else if (PrimaryAttack(Target))
                    {
                    }
                    else LastResort(Target);
                }
                Thread.Sleep(100);
            }
            //If timer runs out, return to start point and report Bugged
            Context.Log("PVP Timer expired, returning to start.");
            Movement.MoveToLocation(startLocation, 20, false);
            return GCombatResult.Success;
        }
        //Checks for and casts Drain Life
        bool DrainLife(GUnit Target, bool ForceUse)
        {
            //Added logging to Drainlife for testing  BEANS
            //Context.Log("DrainLife function check on ForceUse is " + ForceUse);
            //Context.Log("My health pct is "+Me.Health+" and my mana pct is " + Me.Mana);
            CheckHealth(Me.IsInCombat);
            if ((USE_DRAINLIFE && (Me.Health < DRAINLIFE_PCT) || ForceUse))
            {
                //Because its channeling it will often kill before we have a chance to drain soul so we do castspellwithinterrupt to fix it
                //Context.Log("DrainLife SS Check - My current SS count is " + SoulShardCount + " with a max of " + SOULSHARDS_MAX);
                if (SoulShardCount < SOULSHARDS_MAX && (Target.Health < MIN_MOB_HEALTH_PCT))
                {
                    ShadowCheck(Target);
                    if (USE_LIFETAP && (Me.Health > EMERGENCY_HEALTH))
                    {
                        //Context.Log("Casting Lifetap from within DrainLife function");
                        CastSpell("PL.Lifetap");
                        Thread.Sleep(250);
                    }
                    if (SoulShardCount < 1)
                    {
                        SoulShardCount = 0;
                    }
                    Target.Face();
                    if (!Target.IsDead)
                    {
                        CastSwitchSpell("PL.DrainLife", "PL.DrainSoul", Target, DRAINSOUL_PCT);
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {

                    ShadowCheck(Target);
                    //Context.Log("Use Lifetap is " + USE_LIFETAP);
                    if (USE_LIFETAP && (Me.Health > MIN_HEALTH_PCT) && (Me.Mana < MIN_MANA_PCT))
                    {
                        //Context.Log("Casting Lifetap from within DrainLife function");
                        CastSpell("PL.Lifetap");
                        Thread.Sleep(250);
                    }
                    try
                    {
                        Target.Face();
                        if (!Target.IsDead)
                        {
                            CastSpell("PL.DrainLife");
                            Thread.Sleep(250);
                        }
                        if ((Me.Health < MIN_HEALTH_PCT) && (Me.Mana > .3)&&(!Target.IsDead)) //If we are low on health and have at least 30% lets throw another Drain Life
                        {
                            Target.Face();
                            CastSpell("PL.DrainLife");
                            Thread.Sleep(250);
                        }
                    }
                    catch (Exception e)
                    {
                        if (Target == null)
                            Context.Log("You errored out during DrainLife - Notes Target = null so I tried to bomb out.");
                        else
                            Context.Log("You Errored out during DrainLife - \r\n " + e.ToString());
                    }
                    return true;
                }
            }
            return false;
        }
 //Checks mana (Overloaded) - First check Drain Mana, Second check Life Tap
 bool CheckMana(GUnit Target)
 {
     if (USE_DRAINMANA && Target.Mana > .5 && Me.Mana > .1 && Me.Health > MIN_HEALTH_PCT && (Me.Mana < DRAINMANA_PCT || (USE_FEEDMANA && Me.HasLivePet && Me.Pet.Mana < FEEDMANA_PCT)))
     {
      //   Context.Log("CheckMana SS Check - My current SS count is " + SoulShardCount + " with a max of " + SOULSHARDS_MAX);
         if (SoulShardCount < SOULSHARDS_MAX)
         {
             if (SoulShardCount < 1)
             {
                 SoulShardCount = 0;
             }
             Target.Face();
             CastSwitchSpell("PL.DrainMana", "PL.DrainSoul", Target, DRAINSOUL_PCT);
         }
         else
         {
             Target.Face();
             CastSpell("PL.DrainMana");
         }
         return true;
     }
     else if (USE_DARKPACT && Me.HasLivePet && Me.Mana < MIN_MANA_PCT && Me.Pet.Mana > MaintainPetMana)
     {
         CastSpell("PL.DarkPact");
         return true;
     }
     else if (USE_LIFETAP && (Me.Health > MIN_HEALTH_PCT) && (Me.Mana < MIN_MANA_PCT || (USE_FEEDMANA && Me.HasLivePet && Me.Pet.Mana < FEEDMANA_PCT)))
     {
         CastSpell("PL.Lifetap");
         return true;
     }
     return false;
 }
 //Takes two spells. First MUST be channeling, second CAN be channeling.
 void CastSwitchSpell(string FirstSpell, string SecondSpell, GUnit Target, double TargetHealthToSwitch)
 {
     Context.Log(Format(Replace(Replace(FirstSpell, "PL.", "Casting: "), "Common.", "Casting: ")));
     if (Interface.IsKeyFiring("PL.Wand"))
     {
         SendKey("PL.Wand");
         GlobalCooldown.Reset();
     }
     if (Me.IsSitting)
     {
         SendKey("Common.Back");
         Thread.Sleep(200);
     }
     GlobalCooldown.Wait();
     Target.Face();
     //Context.CastSpell(FirstSpell, false, true);
     Context.SendKey(FirstSpell);
     GlobalCooldown.Reset();
     OneSecTimer.Reset();
     while (!OneSecTimer.IsReady)
     {
         Thread.Sleep(100);
         if (Me.IsCasting)
         {
             while (Me.IsCasting)
             {
                 if (Target.Health < TargetHealthToSwitch)
                 {
                     CastSpell(SecondSpell);
                     break;
                 }
                 Target.Face();
                 Thread.Sleep(100);
             }
             break;
         }
     }
 }
 //Modified Context.CastSpell() (Overloaded - directional casting) - turns off wand, waits for key, pause for specified delay, cast - keeps facing target while casting
 void CastSpell(string Spell, GUnit Target)
 {
     Context.Log(Format(Replace(Replace(Spell, "PL.", "Casting: "), "Common.", "Casting: ")));
     if (Interface.IsKeyFiring("PL.Wand"))
     {
         SendKey("PL.Wand");
         GlobalCooldown.Reset();
     }
     if (Me.IsSitting)
     {
         SendKey("Common.Back");
         Thread.Sleep(200);
     }
     GlobalCooldown.Wait();
     while (!Interface.IsKeyReady(Spell))
     {
         Thread.Sleep(200);
     }
     Target.Face();
     //Context.CastSpell(Spell, false, true);
     Context.SendKey(Spell);
     GlobalCooldown.Reset();
     OneSecTimer.Reset();
     while (!OneSecTimer.IsReady)
     {
         Thread.Sleep(100);
         if (Me.IsCasting)
         {
             while (Me.IsCasting)
             {
                 Target.Face();
                 Thread.Sleep(100);
             }
             break;
         }
     }
 }
 //Checks for and casts ShadowBolt
 bool CastShadowBolt(GUnit Target)
 {
     if (Target.Health > MIN_MOB_HEALTH_PCT && Me.Mana > MIN_MANA_PCT)
     {
         //Context.Log("DBG - ShadowBolt code!");
         if (Target.DistanceToSelf > ShadowBoltRange) Target.Approach(ShadowBoltRange, false);
         Target.Face();
         CastSpell("PL.ShadowBolt", Target);
         Thread.Sleep(250);
         return true;
     }
     return false;
 }
        //Debuff cast sequence
        void CastSequence(GUnit Target, bool ForceAll)
        {
            //Check if monster health is great enough to debuff
            SoulShardCount = CountSoulShards();
            if (Target.Health > MIN_MOB_HEALTH_PCT)
            {
                int i;
                //Loop for length of spell array
                for (i = 0; (i < SPELL_ORDER.Length && !Target.IsDead); i++)
                {
                    ShadowCheck(Target);
                    //Check for min mana
                    if (Me.Mana > MIN_MANA_PCT && Me.Health > EMERGENCY_HEALTH && Target.Health > MIN_MOB_HEALTH_PCT && Target.DistanceToSelf < (PullDistance + TARGET_DUMP_DISTANCE))
                    {
                        if (Target.IsDead)
                        {
                            break;
                        }

                        if (USE_BLOODFURY && BloodFury.IsReady)
                        {
                            CastSpell("PL.BloodFury");
                            BloodFury.Reset();
                            GlobalCooldown.ForceReady();
                            Thread.Sleep(MISCDELAY);
                        }
                        //Switch to select correct spell
                        //Context.Log("Casting spell '" + SPELL_ORDER[i] + "' which is spell " + (i+1) + " of " + SPELL_ORDER.Length + "!");
                        Thread.Sleep(250);
                        CheckHealth(Me.IsInCombat);
                        /* RecursiveBot 2.17.1 D
                         * The following is to ensure that we send in the pet after dismounting
                         * and starting to cast.
                         */
                        if (Me.HasLivePet && PET_ATTACK && !Me.Pet.IsInCombat)
                        {
                            //Context.Log("Your pet should being attacking now");
                            SendKey("Common.PetAttack");
                        }
                        switch (SPELL_ORDER[i])
                        {
                            case "UnstableAffliction":
                                //Context.Log("DBG - Unstable Affliction ready check is " + UnstableAffliction.IsReady);
                                while (!Interface.IsKeyReady("PL."+SPELL_ORDER[i]))
                                {
                                    Thread.Sleep(150);
                                }
                                if (UnstableAffliction.IsReady || ForceUnstableAffliction || ForceAll)
                                {
                                    if (ForceUnstableAffliction) Context.Log("Recast");
                                    Target.Face();
                                    CastSpell("PL.UnstableAffliction");
                                    Thread.Sleep(150);
                                    if (!ForceAll)
                                    {
                                        UnstableAffliction.Reset();
                                        ForceUnstableAffliction = false;
                                    }
                                }
                                break;

                            case "SiphonLife":
                                //Context.Log("DBG - Siphon Life ready check is " + SiphonLife.IsReady);
                                while (!Interface.IsKeyReady("PL."+SPELL_ORDER[i]))
                                {
                                    Thread.Sleep(150);
                                }
                                if (SiphonLife.IsReady || ForceSiphonLife || ForceAll)
                                {
                                    if (ForceSiphonLife) Context.Log("Recast");
                                    Target.Face();
                                    CastSpell("PL.SiphonLife");
                                    Thread.Sleep(150);
                                    if (!ForceAll)
                                    {
                                        SiphonLife.Reset();
                                        ForceSiphonLife = false;
                                    }
                                }
                                break;

                            case "CurseofAgony":
                                //Context.Log("DBG - Curse of Agony ready check 1 is " + CurseOfAgony.IsReady);
                                while (!Interface.IsKeyReady("PL."+SPELL_ORDER[i]))
                                {
                                    Thread.Sleep(150);
                                }
                                if (CurseOfAgony.IsReady || ForceCurseOfAgony || ForceAll)
                                {
                                    if (USE_AMPLIFYCURSE && AmplifyCurse.IsReady)
                                    {
                                        SendKey("PL.AmplifyCurse");
                                        AmplifyCurse.Reset();
                                        Thread.Sleep(MISCDELAY);
                                    }
                                    if (ForceCurseOfAgony) Context.Log("Recast");
                                    Target.Face();
                                    CastSpell("PL.CurseofAgony");
                                    Thread.Sleep(150);
                                    if (!ForceAll)
                                    {
                                        CurseOfAgony.Reset();
                                        ForceCurseOfAgony = false;
                                    }
                                }
                                break;

                            case "Corruption":
                                //Context.Log("DBG - Corruption ready check 1 is " + Corruption.IsReady);
                                while (!Interface.IsKeyReady("PL."+SPELL_ORDER[i]))
                                {
                                    Thread.Sleep(150);
                                }
                                if (Corruption.IsReady || ForceCorruption || ForceAll)
                                {
                                    if (ForceCorruption) Context.Log("Recast");
                                    Target.Face();
                                    CastSpell("PL.Corruption", Target);
                                    Thread.Sleep(150);
                                    if (!ForceAll)
                                    {
                                        Corruption.Reset();
                                        ForceCorruption = false;
                                    }
                                }
                                break;

                            case "CurseOfRecklessness":
                                //Context.Log("DBG - CurseOfRecklessness ready check is " + CurseOfRecklessness.IsReady);
                                while (!Interface.IsKeyReady("PL."+SPELL_ORDER[i]))
                                {
                                    Thread.Sleep(150);
                                }
                                if (CurseOfRecklessness.IsReady || ForceCurseOfRecklessness || ForceAll)
                                {
                                    if (ForceCurseOfRecklessness) Context.Log("Recast");
                                    Target.Face();
                                    CastSpell("PL.CurseOfRecklessness", Target);
                                    Thread.Sleep(150);
                                    if (!ForceAll)
                                    {
                                        CurseOfRecklessness.Reset();
                                        ForceCurseOfRecklessness = false;
                                    }
                                }
                                break;

                            case "Immolate":
                               //Context.Log("DBG - Immolate ready check 1 is " + Immolate.IsReady);
                               while (!Interface.IsKeyReady("PL."+SPELL_ORDER[i]))
                                {
                                    Thread.Sleep(150);
                                }
                                if (Immolate.IsReady || ForceImmolate || ForceAll)
                                {
                                    if (ForceImmolate) Context.Log("Recast");
                                    Target.Face();
                                    CastSpell("PL.Immolate", Target);
                                    Thread.Sleep(150);
                                    if (!ForceAll)
                                    {
                                        Immolate.Reset();
                                        ForceImmolate = false;
                                    }
                                }
                                break;

                            case "Shadowburn":
                                //Context.Log("DBG - Shadowburn ready check is " + Shadowburn.IsReady);
                                while (!Interface.IsKeyReady("PL."+SPELL_ORDER[i]))
                                {
                                    Thread.Sleep(150);
                                }
                                if ((Shadowburn.IsReady || ForceShadowburn || ForceAll) && SoulShardCount > 0 && Target.Health < 20)
                                {
                                    if (ForceShadowburn) Context.Log("Recast");
                                    Target.Face();
                                    CastSpell("PL.Shadowburn", Target);
                                    Thread.Sleep(150);
                                    if (!ForceAll)
                                    {
                                        Shadowburn.Reset();
                                        ForceShadowburn = false;
                                    }
                                }
                                break;

                            case "ShadowBolt":
                                //Context.Log("DBG - ShadowBolt ready check is " + ShadowBolt.IsReady);
                                while (!Interface.IsKeyReady("PL."+SPELL_ORDER[i]))
                                {
                                    Thread.Sleep(150);
                                }
                                if (ShadowBolt.IsReady || ForceShadowBolt || ForceAll)
                                {
                                    if (ForceShadowBolt) Context.Log("Recast");
                                    Target.Face();
                                    CastSpell("PL.ShadowBolt", Target);
                                    Thread.Sleep(150);
                                    if (!ForceAll)
                                    {
                                        ShadowBolt.Reset();
                                        ForceShadowBolt = false;
                                    }
                                }
                                break;

                            case "Conflagurate":
                                //Context.Log("DBG - Conflagurate ready check is " + Conflagurate.IsReady);
                                while (!Interface.IsKeyReady("PL."+SPELL_ORDER[i]))
                                {
                                    Thread.Sleep(150);
                                }
                                if ((Conflagurate.IsReady || ForceConflagurate || ForceAll) && (!Immolate.IsReady)) //We only want to cast if Immolate is on target
                                {
                                    if (ForceConflagurate) Context.Log("Recast");
                                    Target.Face();
                                    CastSpell("PL.Conflagurate", Target);
                                    Thread.Sleep(150);
                                    if (!ForceAll)
                                    {
                                        Conflagurate.Reset();
                                        ForceConflagurate = false;
                                    }
                                }
                                break;

                            case "Incinerate":
                                //Context.Log("DBG - Incinerate ready check is " + Conflagurate.IsReady);
                                while (!Interface.IsKeyReady("PL."+SPELL_ORDER[i]))
                                {
                                    Thread.Sleep(150);
                                }
                                if ((Incinerate.IsReady || ForceIncinerate || ForceAll) && (!Immolate.IsReady)) //We only want to cast if Immolate is on target
                                {
                                    if (ForceIncinerate) Context.Log("Recast");
                                    Target.Face();
                                    CastSpell("PL.Incinerate", Target);
                                    Thread.Sleep(150);
                                    if (!ForceAll)
                                    {
                                        Incinerate.Reset();
                                        ForceIncinerate = false;
                                    }
                                }
                                break;
                        }

                    }
                }
            }
        }