Jump to content

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
https://wrobot.eu/forums/topic/15157-c-code-to-detect-multiple-buffs-by-id/
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.

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();
        }
    }
}

 

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

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.

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.

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.

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.

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.

  • 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

Search the documentation for the word 'cache' : https://wrobot.eu/forums/topic/12802-official-wrobot-api-documentation/

The name of the items may be missing (compared to their ID). Traceline also use a cache of few ms.

But why do you need to know this?

 

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...