WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Tweaking an addon: associating a SpellID (https://www.wowinterface.com/forums/showthread.php?t=55023)

Anaea 01-22-17 09:05 AM

Tweaking an addon: associating a SpellID
 
2 Attachment(s)
Hi developers,

I'm looking to tweak a raid frame addon. The addon in question, PerfectRaid (written by Cladhaire) has reached the point of its life cycle where it's lightly supported by the author with feature additions largely contributed by the community. I've been using it since 2009/2010, and it still works great for 99% of what a raiding healer needs.

However, I'm running into issues with some of the newer mechanics. Specifically, on Chronomatic Anomaly, we're dealing with a healing absorb shield called Time Release that explodes unless it's healed through in time: whatever health remains on the Time Release will discharge for potentially wipe-worthy damage.

This spell, with the same name for all of them, is either:

http://www.wowhead.com/spell=219964/time-release (almost clear of the debuff)
http://www.wowhead.com/spell=219965/time-release (not safe)
http://www.wowhead.com/spell=219966/time-release (totally not clear of the debuff)

Default raid frames will show different colors for the different versions of the debuff, but because PerfectRaid calls (and caches) debuffs by the name it does not differentiate.

Step 1: Associate buffname with spellID
So I figure my first step is to associate the spell name ("buffname" in the PerfectRaid code) with the spell ID. I think I would do this in line 176, where I see:

Code:

for i=1,40 do
                local name,rank,texture,count,dispelType,duration,expires,caster,stealable = UnitBuff(unit, i)
                if not name then break end
                if caster == "player" then
                        mybuffs[name] = true
                        mystacks[name] = (mystacks[name] or 0) + count
                        buffexpiry[name] = expires
                end

                buffcache[name] = (buffcache[name] or 0) + 1
                buffstacks[name] = (buffstacks[name] or 0) + count
        end

I think I can acquire the spellId just by adding the variable to the UnitBuff query (and the UnitDebuff query that follows in line 201).
Code:

for i=1,40 do
                local name,rank,texture,count,dispelType,duration,expires,caster,stealable,spellID = UnitBuff(unit, i)
                if not name then break end
                if caster == "player" then
                        mybuffs[name] = true
                        mystacks[name] = (mystacks[name] or 0) + count
                        buffexpiry[name] = expires
                end

                buffcache[name] = (buffcache[name] or 0) + 1
                buffstacks[name] = (buffstacks[name] or 0) + count
        end

At this point, I have a few questions.
  1. Is this a valid query? Between stealable (isStealable I think is the new label) and spellID is another variable -- nameplateShowPersonal -- and I'm not sure if I'm allowed to just skip it in the query or not. I've seen some constructions where that blank variable is indicated with an underscore, but I'm not sure if that's required.
  2. Does this address the question of multiple spellIDs associated with one spell name? For example, will this request pull all three spellIDs for Time Release, or will something else need to be done to get that information?
  3. I know that if I were dealing with a database or a table, just tossing in a new variable would blow stuff up. But I think local cache spell information is saved as text? So it shouldn't be an issue? I'm a complete newbie to LUA so if I'm asking questions that make it sound like I'm missing really obvious things, that's probably because I am missing really obvious things.

I think if this was working, I could probably stop there for my purposes. I'd be able to add the specific spellIDs as default debuffs in the LUA file and move along. This would require editing the PerfectRaid files every time I wanted to add similar debuffs, but it would work. If I wanted to submit something more broadly useful though, I should probably also do Step 2.

Step 2: Allow either spellID or buffname entries
So, working on the assumption that the query for spellID is successful, I would then need to find a way to update the UI so that either the spell name or the spellID is a valid entry for setting up a buff check in PerfectRaid. I'm at much more of a loss on this one. I think that happens around line 322...

Code:

function Buffs:CreateBuffEntry(buffname, entry)
        local expires = buffexpiry[buffname]
        local num = buffcache[buffname]
        local stacks = buffstacks[buffname]
        local mine = mybuffs[buffname]

        -- show only my stacks
        if entry.onlymine then
                stacks = mystacks[buffname]
        end
       
        if ( ( num and num > 1 ) or ( stacks and stacks > 1 ) ) and not entry.onlymine then
                local num = num
                -- If the buff is mine, and it should be masked
                -- A buff is masked when there is a "mine" filter set for it
                if mine and not mymask[buffname] then
                        num = num - 1
                end

                if (expires and entry.showexpiry) and (stacks > 1 and entry.showstacks) then
                        work[#work + 1] = string.format("%s(%d,%d)", entry.colortext, stacks, -1 * (GetTime()-expires) )                                       
                elseif (stacks and stacks > 1 and entry.showstacks) then
                        work[#work + 1] = string.format("%s(%d)", entry.colortext, stacks )                               
                elseif ( num and expires and entry.showexpiry) then
                        work[#work + 1] = string.format("%s(%d,%d)", entry.colortext, num, -1 * (GetTime() - expires))
                elseif ( num and num > 1 ) then
                        work[#work + 1] = string.format("%s(%d)", entry.colortext, num)
                else
                        work[#work + 1] = string.format("%s", entry.colortext)
                end
        else
                if (entry.onlymine and not mine) or (not entry.onlymine and mymask[buffname]) then
                        -- Don't show
                else
                        if (expires and entry.showexpiry) and (stacks > 1 and entry.showstacks) then
                                work[#work + 1] = string.format("%s(%d,%d)", entry.colortext, stacks, -1 * (GetTime()-expires) )                                       
                        elseif (stacks and stacks > 1 and entry.showstacks) then
                                work[#work + 1] = string.format("%s(%d)", entry.colortext, stacks )                                                       
                        elseif (expires and entry.showexpiry) then
                                work[#work + 1] = string.format("%s(%d)", entry.colortext, -1 * (GetTime()-expires))
                        else
                                work[#work + 1] = entry.colortext
                        end
                end
        end
end

Or, it could happen at line 258?

Code:

                -- Determine which spell name we matched
                local buffname
                if buffcache[entry.buffname] then
                        buffname = entry.buffname
                elseif buffcache[entry.groupname or "nil"] then
                        buffname = entry.groupname
                elseif buffcache[entry.groupname2 or "nil"] then
                        buffname = entry.groupname2               
                elseif buffcache[entry.groupname3 or "nil"] then
                        buffname = entry.groupname3
                elseif buffcache[entry.groupname4 or "nil"] then
                        buffname = entry.groupname4
                end

My questions are much more basic here, because I'm definitely at a loss in parsing this. Is there an obvious place here where I can incorporate a spellID? Or am I completely off base on this part?

I've attached the relevant LUA file (PerfectRaid_Buffs) as well as the full addon zip file.

Many, many thanks for anyone who helps out with this -- I realize my ignorance here, and know how much of a pain it can be helping someone with so little base knowledge to work with.

Jonisaurus 02-02-17 10:23 PM

This ability is technically a buff, correct? How is it displayed in PerfectRaid? I can't make it out on the addon page. Is it an icon?
Does it display one of the icons for all stages of the buff?

Quote:

Does this address the question of multiple spellIDs associated with one spell name? For example, will this request pull all three spellIDs for Time Release, or will something else need to be done to get that information?
The addon loops over a unit's buffs 40 times (for i=1, 40 do). You can query spellID but you're gonna have to somehow alter the table that auras (buffs/debuffs) are stored in. Depending on how those are used further in addon, it might break if you use spellID (or 'name .. "_ " .. spellID').

I'll have a look tomorrow. It doesn't look too complicated but I don't see him using the texture that he queries for in that same UnitBuff() request.

Quote:

local name,rank,texture,count,dispelType,duration,expires,caster = UnitDebuff(unit, i)

That's why it would be helpful if you described the addon's buff functionality in more detail.

Anaea 02-03-17 07:12 AM

Quote:

Originally Posted by Jonisaurus (Post 321867)
That's why it would be helpful if you described the addon's buff functionality in more detail.

I'd be happy to, though my perspective will be as a user. :)

In brief, PerfectRaid is a "classic" style unit frame. What it offers that many other raid frames don't is an extraordinary ability to customize how buffs and debuffs are presented on that raid frame.

Users go into a buff/debuff interface and set up how they want PRaid to display a particular buff. Here's an older screenshot of that interface:
https://i.ytimg.com/vi/x4AyIQLvT2M/maxresdefault.jpg

So for example, I might need to monitor how many stacks of a debuff my tanks have -- but not actually respond to that information. I enter the debuff name (e.g., Chronometric Particles) and check the option to "show stacks." I then tell Praid to display this debuff as "CP" and maybe I color it gray so I know it's just an FYI and not something I need to react to.

On the addon's side, I think that breaks down into the following general steps:
  • check to see if the user-entered debuff name matches a spell name
  • if it doesn't, end the process
  • if it does, get the spell name, some other stuff that i don't think is used, get stack information, get expiry information
  • store that spell information in the local cache
  • (it also looks like there's code to tell the addon when to refresh that spell information, but i don't really know enough to parse it)

All of this is working fine. I'm just hoping to extend it so that when, as a user, I enter the debuff GUI I can enter the specific spellID I need to deal with (e.g. Time Release version 3) and tell PRaid how to handle that differently from the debuff with which it shares a name (e.g. Time Release versions 2 and 1).

To the question about the information grabbed, you're right, I think there are some queries that maybe were used once and aren't anymore, or maybe they're just placeholders. I do know the addon uses:
- spellname
- debuff type
- stack/count
- expiration

I don't know if it uses the caster attribute, or the isStealable attribute (for buffs).

In combat, the addon (more specifically this module) does a lot of things that I don't need to change:
  • checks to see if any magic, disease, poison debuff is on a raid member
  • displays a colored highlight bar to indicate that there is some debuff on that raid member
  • (by default, this behavior is enabled by user class: so as a priest, I see magic and disease highlights but not poison)
  • (this behavior can be adjusted to show all the highlights, though I think that's done in another module)
  • using the list of user-entered buffs and debuffs, check to see if those debuffs are on a raid member
  • displays the buff, debuff status on the raid frame according to user specifications
  • (this can include expiration, if the user has enabled that for this particular debuff, but is not shown as a default)
  • (this can include stack count, if the user has enabled that for this particular debuff, but is not shown as a default)

Jonisaurus 02-06-17 05:34 PM

Just letting you know that I'm working on it. The addon's 'buff component' has some very obtuse code. Weirdly named functions, barely any documentation and manipulating/passing data in strange ways. I spent a lot of time just trying to understand what each function does. I'm much more used to web development than WoW addon code so it takes a while to get used to it.

I've added a Spell ID entrybox into the buff entry options and have its content be inserted into the saved profile. Next step is reading the spell ID data into the proper 'buffs' variables (I haven't quite figured out how 'buffs', 'buffcache' and 'mybuffs' interact yet).

I can't spend great amounts of time on it right now but I will fix this for you, you just need to be patient with me a little, okay?

Anaea 02-07-17 06:43 AM

Quote:

Originally Posted by Jonisaurus (Post 321909)
Just letting you know that I'm working on it. The addon's 'buff component' has some very obtuse code. Weirdly named functions, barely any documentation and manipulating/passing data in strange ways. I spent a lot of time just trying to understand what each function does. I'm much more used to web development than WoW addon code so it takes a while to get used to it.

I've added a Spell ID entrybox into the buff entry options and have its content be inserted into the saved profile. Next step is reading the spell ID data into the proper 'buffs' variables (I haven't quite figured out how 'buffs', 'buffcache' and 'mybuffs' interact yet).

I can't spend great amounts of time on it right now but I will fix this for you, you just need to be patient with me a little, okay?

I am the last person to complain about free help! I appreciate you taking a look -- I was able to make some simpler updates but this was way beyond me. :) Thanks!


All times are GMT -6. The time now is 01:32 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI