Jump to content

C code to detect multiple buffs by ID


thetaxi

Recommended Posts

After many iterations and tries I have finally found a semi working solution to a custom debuff spell detection.  I have to use C sharp code to detect the buff.  However, there are multiple different buffs and so far I am creating a separate spell for each right now.  Is there a better way to do this?  Remember, I have to use spell IDs.

 new SpellState("CastSpellByName(\"Cleanse\");", 9, context => FightconfignameSettings.CurrentSetting.R && wManager.Wow.ObjectManager.ObjectManager.Me.HaveBuff (123456),
 new SpellState("CastSpellByName(\"Cleanse\");", 8, context => FightconfignameSettings.CurrentSetting.V && wManager.Wow.ObjectManager.ObjectManager.Me.HaveBuff (123457),
 new SpellState("CastSpellByName(\"Cleanse\");", 7, context => FightconfignameSettings.CurrentSetting.Z && wManager.Wow.ObjectManager.ObjectManager.Me.HaveBuff (123458), 

 

This is what I am working with but it seems to be slowing down my rotation a lot.  Any ideas on how to improve the C code or even go to LUA.

 

Thank You

Link to comment
Share on other sites

If I remember correctly, calling HaveBuff() is indeed very slow.

Assuming you've built your FC with a standard while loop, ideally, you want to cache all the buffs (aka Auras) of your characters at the beginning of the loop. A good implementation of this would be a dictionary.

Dictionary<uint, Aura> auras = new Dictionary<uint, Aura>();
foreach (Aura aura in BuffManager.GetAuras(ObjectManager.Me.GetBaseAddress))
{
	auras[aura.SpellId] = aura;
}

What you end up with is a dictionary containing all the spell ids of your character's auras as key, and their corresponding aura as value, which makes it very easy and fast to check for buffs.

if (auras.ContainsKey(123456))
{
	...
}

You'll also get additional infos from the Aura class (like the buff owner, stacks, time left etc..). Just be aware that on earlier expansions, some Aura members might always return default values.

Link to comment
Share on other sites

Hi,
To ger debuff of a target i use this code, but its seem to be very slow :

 

public void SerpentStingskill()
    {
        List<Aura> peon = Fight.CurrentTarget.GetAllBuff();
        bool shouldCastSerpentSting = true;
        //SERPENT STING
        foreach (Aura a in peon)
        {
            if (a.SpellId == 49001 && a.Owner == ObjectManager.Me.Guid && isTargetGood())
            {
                shouldCastSerpentSting = false;
                break;
            }
        }

        if (shouldCastSerpentSting)
        {

            Logging.Write($"{ObjectManager.Me.Guid} - SERPENT STING");

            SerpentSting.Launch();
        }
    }
}

 

Link to comment
Share on other sites

Hi,
With ur code Zero i modified my code to write that :
 

public void SerpentStingsSkill2()
    {
        Dictionary<uint, Aura> auras = new Dictionary<uint, Aura>();
        foreach (Aura aura in BuffManager.GetAuras(Fight.CurrentTarget.GetBaseAddress))
        {
            if (aura.Owner == ObjectManager.Me.Guid)
            auras[aura.SpellId] = aura;
           
        }
        if (!auras.ContainsKey(49001)) //Check if the target don't have te debuff Serpent Sting
        {
            Logging.Write($"{ObjectManager.Me.Guid} - SERPENT STING"); // Pas nécessaire pour le fonctionnement de la fonction

            SerpentSting.Launch();
        }
    }

That will be better than my precedent code ?

 

Thanks

Link to comment
Share on other sites

The idea behind recording the auras in a dictionary is to have them all cached for the entire rotation iteration for better performance. If you only use it once, or repeat the process for multiple spells, then it defeats the purpose.

Link to comment
Share on other sites

4 hours ago, thetaxi said:

Do you know of a better way to detect a debuff by ID? Perhaps some Lua code?

I don't know what you mean by "better way". With Auras, you get all buffs and debuffs alike, and recording them in a dictionary makes them extremely fast to access. The code I gave you does exactly what you need and more.

Link to comment
Share on other sites

Just wanted to point out that my framework is more for ease of use and built based on old ideas of how WRobot works.

If you built something more modern, you'd likely build a tick based system that caches important information on every ObjectManager update in your own classes to prevent expensive (Lua or memory read) calls to be executed more often than necessary. It's hard to tell what to cache in the first place too. Making unnecessary calls that you'll never need is equally unperformant.

However, unless you're looking for to cheat in PvP using a rotation bot, a couple hundred milliseconds between each rotation iteration isn't a huge issue.

Link to comment
Share on other sites

Agreed with @Matenia. Having a separate manager that records the state of the ObjectManager on each pulse is ideal, not only because your rotation can reuse these info very fast, but also besaue it gives you a reliable "snapshot" of the game state. There are pitfalls to this and it requires some thorough performance monitoring.

It's definitely overkill for a simple rotation, so I think the dictionary solution at the begining of your iteration is a fine compromise if you check on a lot of buffs.

Link to comment
Share on other sites

Personally I do a ton of my 'heavy' checks in tasks that aren't looped. But rather fires once every loop over my overall rotation. Do care about how many threads you open though especially if you plan to keep more than one on a loop.

Link to comment
Share on other sites

  • 2 weeks later...

That's not what he said. He said meta info is cached. Buffs are still read from memory every time you make a call. 
If you're making a fightclass and want it to be a efficient, create a state of truth for all units around you and make sure it doesn't change until after the iteration is over.
That holds true for ids, distance, buffs, debuffs, whatever you need to make decisions in your rotation

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...