• You've discovered RedGuides, an EverQuest multi-boxing and scripting community 🧙‍♀️⚙️. We want you to play several EQ characters at once, come join us and say hello! 👋

  • A TLP without truebox has thawed (Very Vanilla ready)
    Frostreaver

Problem - Me.Buff[] and other TLO problems?

Joined
Dec 4, 2016
RedCents
7,973¢
Is there a buff slot limit to TLO's like Me.Buff, Me.Snared, Me.Poisoned, etc?

I've been working on some cure checking routines and the issue I've come across is depending on how far down the buff list a debuff is I cant detect it, even when searching for that specific debuff.
The debuff in question is: Drachnid Entangle
If I have this debuff and it is near the top of my buff list ${Me.Snared.ID},${Me.Buff[Drachnid Entangle].ID},${Me.TotalCounters} all return a value, ${Debuff.Detrimentals} returns TRUE, if the debuff is way down my buff list the ID's are null, totalcounters is 0 and detrimentals is false.
Is this a bug? Is there a way around this?
 
i have not seen any problems with them anywhere in the buff lists. but i'm not using the debuff plugin. as for a way around it. i have one written but its all DanNet based.
 
Last edited:
i have not seen any problems with them anywhere in the buff lists. but i'm not using the debuff plugin. as for a way around it. i have one written but its all DanNet based.

I used the debuff plugin only to see if it could find the debuff. I'm stumped ${Me.Buff[Drachnid Entangle].ID} cant find it directly on the character with the debuff even if I click it and bring up the description window, making curing kinda tough cause my chars always have a billion buffs on em.
 
MQ2Debuff is so old it only has 30 buff slots, that's why you experiencing what you do, when using it.

and then i wonder if it influences the main mq2 tlos. when you run it.
 
MQ2Debuff is so old it only has 30 buff slots, that's why you experiencing what you do, when using it.

and then i wonder if it influences the main mq2 tlos. when you run it.
yeah looks like the array size is set to 30 - likely an easy fix, eh? one of you c++ dudes wanna chime in and teach me your ways! @Knightly @ChatWithThisName is this a matter of just changing the array size?

MQ2Debuffs
Code:
private:
  PSPELL dList[30]; long dSize;
  PSPELL bList[30]; long bSize;
  PSPELL aList[30]; long aSize;
 
actually i think the maxbuff variable is the one that sets it, which i noticed is at 25 buffs.
 
If its looking at the first 25-30 buff slots that does not explain why .TotalCounters doesnt identify it. Or, identify the enchanter AA tash proc debuff. Or are we just picking a random 25 buffs to check?
 
I think most of the functionality of MQ2Debuffs exists in core now which is what IHC was using with "Me.". But you're both right about MQ2Debuffs -- you'd need to change the array size and you'd need to change the define since changing the define (but not the array size) would overflow the array and changing the array size (but not the define) would still only loop without filling the slots. Still, IHC was just using that as a double check to see what was going on in core and saying he got the same result. So, I'd probably just let MQ2Debuffs die and unload it, that's going to be a different issue than core.

Core hardcodes the buffs at 42. Through testing, do you know at which buff slot position the value stops getting returned?
 
my thoughts not allways right, but sometimes like 1 out 759 it hits jackpot
 
Ok so to follow up on this a bit it really seems like a bug, I cant tell if it's an MQ2 bug or and EQ bug. I mention an EQ bug because I have both Spirit of Tala'tak and Selo's on and sometimes Drachnid Entangle will overwrite one or the other and other times it wont overwrite either. MQ2Debuff is unloaded while I ran this test, I had 29 total buff's including Drachnid Entangle on me when I ran this /echo:

Code:
/echo TotalCounters:${Me.TotalCounters}|Snare Spell:${Me.Snared}|Snare ID:${Me.Snared.ID}|Buff String Search ID:${Me.Buff[Drachnid Entangle].ID}|Buff ID Search ID:${Me.Buff[49968].ID}

Here is the result:
TLOchk.jpg

This time it did find it by specific name search but this is NOT always the case and not how we should be looking for debuffs. Why is TotalCounters 0? Why no result from either of the snare checks? Even stranger why did it find it with a string search but not ID search? For reference here is the spell info in game so you can see I was searching the proper ID:
EntangleDbf.jpg

Its a rare case (PVP/dueling) but this happens with the debuff proc from ench tash also.
 
it may be they are looking for specific spells when doing "snared"

If I recall rightly when EQMule was doing .slowed he asked for a list of slow spells. So part of the issue may be that X spell has not been added to a list someplace. But that is just a guess.
 
He probably didn't ask for the list to hardcode it, he probably asked so he could see what SPAs were associated with those spells.

@ihc385 When you ran that test with less than 29 buffs it comes out properly, but at 29 it fails?
 
@Warl0ck45 Slowed is handled by SPA.

C++:
    case Slowed:
        Dest.Type = pBuffType;
        if (PCHARINFO2 pChar2 = GetCharInfo2()) {
            int nBuff = -1;
            if ((nBuff = GetSelfBuffBySPA(11, 0)) != -1)//Slowed
            {
                Dest.Ptr = &pChar2->Buff[nBuff];
                return true;
            }
        }
        return false;

For the function GetSelfBuffBySPA the proto is as follows
C++:
int GetSelfBuffBySPA(int spa, bool bIncrease, int startslot)
So it's looking for case 11 on SPA, Which is Melee Speed, then it checks bIncrease which in this case is 0.
the GetSelfBuffBySPA iterates though all Buffs in normal buff window (Up to ox2a or 42). If they go to the short duration window it would be checked in
C++:
int GetSelfShortBuffBySPA(int spa, bool bIncrease, int startslot)

It should be noted that at current that the short buffs are not checked by this case.

For case 11

C++:
case 11: //Melee Speed
                        if (!bIncrease && base < 100) { //below 100 means its a slow above its haste...
                            return i;
                        }
                        else if (bIncrease && base > 100) {
                            return i;
                        }
                        return -1;

So since bincrease = 0, it gets the base from

C++:
if (LONG base = ((EQ_Spell *)pSpell)->SpellAffectBase(spa)) {

to determine if the value is lower than 100 then it's a slow.

Of course, each of these are handled differently. Such as Snare is SPA 3, which is movement rate. the check is spa 3 with !bIncrease. So the value would theoretically be less than 0, thus returning any buff that has a snared movement rate modifier in it.

One would need to check SPA's on those abilities to see what SPA's it contains so that they can be verified to match the existing conditions available in the GetSelfBuffBySPA function to return more accurate information.

As for MQ2Debuffs.

C++:
        case Detrimentals:
          Dest.Type=pBoolType;
          Dest.DWord=(dSize)?true:false;

The above reflects the information shown for MQ2Debuffs.
The arrays of PSPELL for dList, bList, and aList are all 30 in size.
dSize doesn't appear to get initialized, as neither does bSize, or aSize, but are all defined as "long" for a type.

I find that there is a function void SetBuffs(PCHAR Index) that appears to be the one that determines the number of buffs/debuffs a player has on them.

In that particular function it checks "MAXBUFF_MYSELF" which is defined as 25, which significantly is limiting the possible opportunity to actually find the debuffs because it's only checking up to 25 slots instead of up to the 42 available in MQ2.

Without actually testing I wouldn't be able to verify this is the issue with certainty, but I believe it should use the same #define that core does to ensure this iterates through all buff slots available as opposed to requiring it be updated to stay current. MQ2BerZerker uses the same globals as MQ2's core code and I've had no issues.

C++:
    ZeroMemory(&dList,sizeof(dList)); dSize=0;
    ZeroMemory(&bList,sizeof(bList)); bSize=0;
    ZeroMemory(&aList,sizeof(aList)); aSize=0;
    if(!Index[0] || !_stricmp(Index,"self") || !_stricmp(Index,"myself")) {
      for(int b=0; b<MAXBUFF_MYSELF; b++) {
        if(PSPELL spell=GetSpellByID(GetCharInfo2()->Buff[b].SpellID))
          if(spell->DurationCap>0) {
            ((spell->SpellType)?bList[bSize++]:dList[dSize++])=spell;
            aList[aSize++]=spell;
          }
      }
      return;
    }

The above is part of the code I'm referencing.

It should be noted that MQ2Debuffs hasn't been updated since it's initial import to very vanilla 2 years ago or more, unless you count the gitlab update that includes adding a space to one line in the comments.

My personal function removes the need to check each individually with a TLO and instead checks normal buffs, short buffs, and aura all at once to save me the headache of getting specific with which box to check.

C++:
bool IHaveBuff(PSPELL pSpell) {
    if (!InGame()) return false;
    for (int i = 0; i < NUM_LONG_BUFFS; i++) {
        if (GetCharInfo2() && GetCharInfo2()->Buff) {
            if (PSPELL pBuff = GetSpellByID(GetCharInfo2()->Buff[i].SpellID)) {
                if (strstr(pBuff->Name, pSpell->Name)) {
                    return true;
                }
            }
        }
    }
    for (int i = 0; i < NUM_SHORT_BUFFS; i++) {
        if (GetCharInfo2() && GetCharInfo2()->ShortBuff) {
            if (PSPELL pBuff = GetSpellByID(GetCharInfo2()->ShortBuff[i].SpellID)) {
                if (strstr(pBuff->Name, pSpell->Name)) {
                    return true;
                }
            }
        }
    }
    if (pAuraMgr) {
        if (PAURAMGR pAura = (PAURAMGR)pAuraMgr)
        {
            if (pAura->NumAuras)
            {
                PAURAS pAuras = (PAURAS)(*pAura->pAuraInfo);
                for (DWORD n = 0; n < pAura->NumAuras; n++)
                {
                    if (strstr(pAuras->Aura[n].Name, pSpell->Name))
                    {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

Those ranges are the same ranges used for core MQ2 with NUM_LONG_BUFFS expanding to 42, and NUM_SHORT_BUFFS expanding to 55. These are defined (for me on test) in EQData(Test).h and thus should require no intervention from me if they ever get updated. I expect given the right situation the same could be tested for MQ2Debuffs
 
Last edited:
Problem - Me.Buff[] and other TLO problems?

Users who are viewing this thread

Back
Top
Cart