What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal
RebornBuddy Forums

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

CC Developers: Your insight into priority based casting instead of sequential.

ski

Well-Known Member
Joined
Feb 12, 2010
Messages
3,720
After looking through a bunch of other CC's, I notice most (all that I saw, actually) of them use sequential-based spell casting.

What I mean by that is, as Combat() is run through, each spell has its own separate If(conditions) statement before being cast.

Code:
if (useSpellA == true) {useSpellA();}
if (useSpellB == true) {useSpellB();}
if (useSpellC == true) {useSpellC();}
etc

I see a problem with this - it makes your CC not able to react quick enough to situations in game. Take the following sequence for example:
Code:
Combat(){
if (health < 50) {deathcoil();}
if (useCorruption) {corruption();}
if (useUA) {ua();}
if (useShadowbolt) {shadowbolt();}
}

In this example, if I'm at 75% health when Combat() is entered, it will skip death coil and begin casting the rest of the spells. Now if I get hit after the corruption and end up at 30% health, instead of Death Coiling, it will finish out Combat() by casting UA, then Shadowbolt. Only after both of those are done will it start again and use the death coil (at which point I'll likely be dead already).

What I'd LIKE to use, is some sort of priority-based spell casting where each cast is decided upon in real time. In the example above, I would like it to see that after casting Corruption my health is low, and use Death Coil.

I tried implementing something like this, but it seems that the code while running is too slow and there is a few seconds in between each cast:
Code:
Combat(){
if (health < 50) {deathcoil();}
else if (useCorruption) {corruption();}
else if (useUA) {ua();}
else if (useShadowbolt) {shadowbolt();}
}


In this case, it should run through Combat() for each spell, letting it choose based on which needs to be cast first. Only problem is Combat() wasn't being called fast enough for it to be efficient.

So I tried something like this:
Code:
Combat(){
While(!Target.IsDead && Me.HaveTarget){
if (health < 50) {deathcoil(); break;}
else if (useCorruption) {corruption() break;;}
else if (useUA) {ua(); break;}
else if (useShadowbolt) {shadowbolt(); break;}
}

I ran into the same issue with long times between spell casts and I'm not entirely sure why.

What I'd like to know from the other developers is how (or if) you have implemented priority-based spell casting that chooses each spell for each cast, as opposed to just running through every spell before looping again.
 
Last edited:
The Combat void is called multiple times per second.

If you add a timer check to your combat void you'll see it completes in a matter of milliseconds.
 
The Combat void is called multiple times per second.

If you add a timer check to your combat void you'll see it completes in a matter of milliseconds.

Is it dependent on system specs or anything of that nature? I can't for the life of me figure out why when I test it one minute, it casts spells faster than I could myself, whereas other times I test it and there is a 4-5 second delay between spells (ping steady between 50-100 each test).
 
Regardless of the PC specification its still only going to take milliseconds the complete a cycle of the Combat Void. I too expierence delays from time-to-time with no explaination as to why.
 
Regardless of the PC specification its still only going to take milliseconds the complete a cycle of the Combat Void. I too expierence delays from time-to-time with no explaination as to why.

Hmm. Have you tried to do any sort of priority-based spell casting at all? Has it worked? I'd really like to implement it but I'm having trouble finding a stable way to do it.
 
I believe one of the other Warlock CC has implemented a priority-based casting system. Unfortunately I can't tell you which one, though I do recall seeing it a couple of days ago.
 
Last edited:
I believe one of the other Warlock CC has implemented a priority-based casting system. Unfortunately I can't tell you which one, though I do recall seeing it a couple of days ago.

That was mine. Unfortunately its also the one that will randomly work fine, and other times have a multiple second delay between casts. Was hoping to find a better (more stable) way of doing it than how I currently do :(
 
That was mine. Unfortunately its also the one that will randomly work fine, and other times have a multiple second delay between casts. Was hoping to find a better (more stable) way of doing it than how I currently do :(

Is the delay maybe tied into the issue being experienced by people in this thread:

http://www.buddyforum.de/showthread.php?2297-Gone-from-Great-to-Slow

I guess if they are connected then tracking down the root cause would fix a lot of current issues.
 
I'm aware of the issues Ski is referring to and from time to time I too experience this problem.
 
Is code for buffing;)
if (!Me.Buffs.ContainsKey("Arcane Intellect") && !Me.Buffs.ContainsKey("Fel Intelligence") && !Me.Buffs.ContainsKey("Dalaran Intellect") && !Me.Buffs.ContainsKey("Arcane Brilliance") && !Me.Buffs.ContainsKey("Dalaran Brilliance"))
{
if (Me.GotTarget &&
Me.CurrentTarget.Guid != Me.Guid)
{
Me.ClearTarget();
}
slog("Dont have Mage Buffs Buffing Intellect");
SpellManager.CastSpell("Arcane Intellect");
}
 
Although from a technical standpoint I use a sequential casting technique. There are many checks I use before each spell would be cast to determine the next spell.

And timers are very bad for HB. I use one and thats just during pull.
 
ski, for priority casting you can try something like this:

Code:
        public void CombatDecision()
        {
            if (!Me.GotTarget)
                return;
            if ( (Me.HealthPercent < 70 && SpellManager.KnownSpells.ContainsKey("Drain Life")))
            {
                CombatHealthManager();
            }
            else
                if (Me.GotTarget && Me.CurrentTarget.HealthPercent < 30 && SpellManager.KnownSpells.ContainsKey("Drain Soul"))
                {
                    CombatHealthManager();
                }
                else
                    if (Me.ManaPercent < 50 && Me.HealthPercent > 70 && SpellManager.KnownSpells.ContainsKey("Life Tap"))
                    {
                        CombatHealthManager();
                    }
                    else
                        if (Me.GotTarget && Me.ManaPercent < 50 && Me.CurrentTarget.ManaPercent > 30 && SpellManager.KnownSpells.ContainsKey("Drain Mana"))
                        {
                            CombatHealthManager();
                        }
                        else
                            if (DBWSettings.Default.useSpellShadowBolt)
                            {
                                ShadowBolt();
                            }
            Thread.Sleep(DBWSettings.Default.myLag);
            if (Me.GotTarget && SpellManager.CanCastSpell("Shoot"))
            {
                Shoot();
                Thread.Sleep(DBWSettings.Default.myLag);
                while (Me.IsCasting)
                    Thread.Sleep(DBWSettings.Default.myLag);
            }
                            
        }

Then place the CombatDecision() method in you pull and combat loop.
the CombatHealthManager is another priority of spells for recovering mana / health (life drain, life tap, etc).
 
For dots i have another function that is called before the Combat Decision, but i?m already placing it in to the CombatDecision.

Code:
        public void DotMyTarget()
        {
            while (Me.IsCasting)
            {
                Thread.Sleep(DBWSettings.Default.myLag);
            }
            if (combatChecks)
            {
                if (Me.CurrentTarget.HealthPercent > 40 && Me.ManaPercent > 40 && Me.HealthPercent > 40)
                {
                    if (isTotem)
                    {
                        slog(Me.CurrentTarget.Type.ToString());
                        slog("Dont DoT a Totem! Duh!");
                        if (SpellManager.CanCastSpell("Shoot"))
                            SpellManager.CastSpell("Shoot");
                        if (Me.GotAlivePet)
                            Lua.DoString("PetAttack()");
                        Thread.Sleep(DBWSettings.Default.myLag);
                    }
                    else
                    {
                        try
                        {
                            if (DBWSettings.Default.useCurse)
                            {
                                curseMyTarget();
                                Thread.Sleep(DBWSettings.Default.myLag);

                            }
                            if (SpellManager.KnownSpells.ContainsKey("Corruption") &&
                                DBWSettings.Default.useCorruption && !Me.CurrentTarget.Buffs.ContainsKey("Corruption"))
                            {
                                Corruption();
                                Thread.Sleep(DBWSettings.Default.myLag);
                            }

                            if (SpellManager.KnownSpells.ContainsKey("Immolate") &&
                                DBWSettings.Default.useImmolate && !Me.CurrentTarget.Buffs.ContainsKey("Immolate"))
                            {
                                if (Me.CurrentTarget.CreatureType != WoWCreatureType.Demon)
                                {
                                    Immolate();
                                    Thread.Sleep(DBWSettings.Default.myLag);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            slog(ex.Message);
                        }
                    }
                }
                else
                {
                    if (Me.HealthPercent <= 40)
                    {
                        slog("I'm low on Health. Wont DoT");
                    }
                    if (Me.CurrentTarget.HealthPercent <= 40)
                    {
                        slog("{0} is dying, dont DoT", Me.CurrentTarget.Name);
                    }
                }

                if (Me.CurrentTarget.HealthPercent > 20)
                {
                    if (SpellManager.KnownSpells.ContainsKey("Haunt"))
                    {
                        Haunt();
                    }
                }

                if (Me.CurrentTarget.HealthPercent > 40)
                {
                    UnstableAffliction();
                }

            }
        }
 
Sadly, I was doing exactly that, but it just doesn't work very well. I tried nested if's, I tried goto statements, I tried while loops. After a while, it just bogs down and starts leaving 3-4 seconds in between casts. I did these tests last night with sequential casting and priority casting:

1. Demo (notaunt) - Priority - 90k
2. Demo (notaunt) - NoPriority - 100k
3. Affli - Priority - 85k
4. Affli - NoPriority - 110k
5. Destro - Priority - 60k
6. Destro - NoPriority - 105k

50 kills each

Decided to just keep it sequential for now.
 
Ski, what about trying a switch statement instead? It's much faster than nesting a bunch of if statements

Good luck.
 
Ski, what about trying a switch statement instead? It's much faster than nesting a bunch of if statements

Good luck.

I've tried it on and off with switch/cases, ifs, whiles. Sometimes it works great, other times it slows down. Its too unreliable for me to be comfortable with it so what I ended up doing was writing 4 different methods, one for healing/emergency spells, one for mana and life drain, one for my blacklist checks (divine shield, etc), and one for my spell rotation. I call the other 3 after each spellcast, but the spells themselves are still sequential.

It goes something like this:
- Enter Combat
- Cast Combat Spell 1
- Check to see if we need to blacklist, drain, heal, or combat-utility spell
- Cast Combat Spell 2
- Check to see if we need to blacklist, drain, heal, or combat-utility spell
- Cast Combat Spell 3
- etc
- Combat Ends
 
Back
Top