Buff Tracking
Tracks all buffs and debuffs, shows who has/lacks and who last casted it.
If you like this or find it useful, check for updates as more functionality will be added.
|
Quick Facts |
---|
|
Tracks all buffs and debuffs, shows who has/lacks and who last casted it.
If you like this or find it useful, check for updates as more functionality will be added.
Contains custom functions.
Code has been reviewed and is safe to use, custom functions might affect in-game performance.
{
"m": "d",
"d": {
"iconSource": 0,
"color": [
1,
1,
1,
1
],
"yOffset": -56.666,
"anchorPoint": "CENTER",
"cooldownEdge": false,
"icon": true,
"triggers": {
"1": {
"trigger": {
"type": "custom",
"subeventSuffix": "_AURA_APPLIED",
"custom_hide": "timed",
"names": [],
"event": "Combat Log",
"subeventPrefix": "SPELL",
"custom_type": "event",
"custom": "function (a, b, event, d, casterName, f, g, targetName, i, j, spellName,l,m,n,o,p,q,r,critical,t,u,v)\n local should_show = not InCombatLockdown()\n \n if(not should_show) then \n aura_env.HideFrames2()\n end\n \n if(not casterName) then \n return should_show\n end\n if(UnitIsEnemy(UnitName(\"player\"),casterName)) then \n return should_show\n end\n \n if(not(aura_env[\"funcs\"][\"RelevantAbility\"](spellName))) then\n return should_show\n end\n \n if (event == \"SPELL_AURA_REFRESH\" or event == \"SPELL_CAST_SUCCESS\" or event == \"SPELL_AURA_APPLIED\" or event == \"SPELL_AURA_REMOVED\") and (GetNumRaidMembers() + GetNumPartyMembers() >= 0 or true) and aura_env[\"funcs\"][\"RelevantPlayer\"](targetName,casterName) then\n --print(spellName)\n --print(IsInGroup())\n --print(casterName)\n --print(spellName)\n --print(InCombatLockdown())\n local was_removal = event == \"SPELL_AURA_REMOVED\"\n \n if(spellName == \"Curse of Weakness\") then \n aura_env[\"funcs\"][\"UpsertPlayer\"](casterName,\"Curse of Weakness (AP)\",was_removal,aura_env)\n elseif(spellName == \"Blessing of Sanctuary\") then\n aura_env[\"funcs\"][\"UpsertPlayer\"](casterName,\"Blessing of Sanctuary (heal)\",was_removal,aura_env)\n elseif(spellName == \"Greater Blessing of Sanctuary\") then\n aura_env[\"funcs\"][\"UpsertPlayer\"](casterName,\"Greater Blessing of Sanctuary (heal)\",was_removal,aura_env)\n elseif (spellName == \"Totem of Wrath\") then\n aura_env[\"funcs\"][\"UpsertPlayer\"](casterName,\"Totem of Wrath (crit)\",was_removal,aura_env)\n elseif (aura_env[\"deep_wounds\"](spellName)) then\n casterName = nil\n -- check if target has Blood Frenzy\n -- cannot check by name so we have to pray\n local has_bf, _, _, _, _, _, _, bf_applier = UnitDebuff(\"target\",\"Blood Frenzy\")\n \n if (not was_removal and has_bf) then \n spellName = \"Blood Frenzy\"\n casterName = UnitName(bf_applier) -- who actually has the TE is undetectable?\n end\n end\n \n if(not UnitIsPlayer(casterName)) then \n local n = aura_env[\"funcs\"][\"PetOwner\"](casterName,aura_env)\n if(n) then \n casterName = n\n end\n end\n \n if(casterName) then \n aura_env[\"funcs\"][\"UpsertPlayer\"](casterName,spellName,was_removal,aura_env)\n end\n \n --print(UnitIsEnemy(\"player\",\"target\"))\n if(should_show) then \n aura_env.MakeSingleFrame(spellName)\n end\n \n end\n \n return should_show\nend",
"spellIds": [],
"use_sourceUnit": true,
"events": "COMBAT_LOG_EVENT_UNFILTERED",
"unit": "player",
"sourceUnit": "player",
"debuffType": "HELPFUL"
},
"untrigger": []
},
"2": {
"trigger": {
"useName": true,
"auranames": [
"Rampage",
"Leader of the Pack"
],
"unit": "group",
"type": "aura2",
"debuffType": "HELPFUL"
},
"untrigger": []
},
"disjunctive": "custom",
"customTriggerLogic": "function(t) \n return t[1]\nend",
"activeTriggerMode": -10
},
"internalVersion": 53,
"keepAspectRatio": false,
"selfPoint": "CENTER",
"desc": "Made by Aramis\/Fujoshi on Area 52\n\nVersion 1.0.0",
"subRegions": [
{
"type": "subbackground"
},
{
"text_shadowXOffset": 0,
"text_text_format_s_format": "none",
"text_text": "%s",
"text_shadowColor": [
0,
0,
0,
1
],
"text_selfPoint": "AUTO",
"text_automaticWidth": "Auto",
"text_fixedWidth": 64,
"anchorYOffset": 0,
"text_justify": "CENTER",
"type": "subtext",
"text_color": [
1,
1,
1,
1
],
"text_font": "Friz Quadrata TT",
"text_shadowYOffset": 0,
"text_wordWrap": "WordWrap",
"text_visible": true,
"text_anchorPoint": "INNER_BOTTOMRIGHT",
"text_fontSize": 12,
"anchorXOffset": 0,
"text_fontType": "OUTLINE"
},
{
"glowFrequency": 0.25,
"type": "subglow",
"glowXOffset": 0,
"glowType": "buttonOverlay",
"glowLength": 10,
"glowYOffset": 0,
"glowColor": [
1,
1,
1,
1
],
"useGlowColor": false,
"glow": false,
"glowScale": 1,
"glowThickness": 1,
"glowLines": 8,
"glowBorder": false
}
],
"height": 8,
"load": {
"ingroup": {
"single": "raid",
"multi": {
"raid": true
}
},
"use_never": false,
"talent": {
"multi": []
},
"class": {
"multi": []
},
"spec": {
"multi": []
},
"size": {
"multi": []
}
},
"regionType": "icon",
"xOffset": 474.17,
"animation": {
"start": {
"type": "none",
"easeStrength": 3,
"duration_type": "seconds",
"easeType": "none"
},
"main": {
"type": "none",
"easeStrength": 3,
"duration_type": "seconds",
"easeType": "none"
},
"finish": {
"type": "none",
"easeStrength": 3,
"duration_type": "seconds",
"easeType": "none"
}
},
"cooldown": false,
"conditions": [],
"zoom": 0,
"actions": {
"start": [],
"init": {
"do_custom": true,
"custom": "local funcs = {}\nlocal self = aura_env\n\nfunction CalculatePosition2(count,size,padding)\n --local data = self[\"positions\"]\n --local grow = data[\"grow\"]\n --local v_wrap = data[\"v_wrap\"]\n local grow = 4\n local v_wrap = 3\n \n \n local row_pos = 0\n local col_pos = 0\n \n if(v_wrap == 8)then \n v_wrap = nil -- infinite\n end\n --local h_wrap = data[\"h_wrap\"]\n local h_wrap = nil\n if(h_wrap == 0)then\n h_wrap = nil -- infinite \n end\n \n if(v_wrap ~= nil)then \n row_pos = (count) % v_wrap\n col_pos = math.floor(count\/v_wrap)\n elseif (h_wrap ~= nil) then\n row_pos = (count+1) % h_wrap\n col_pos = math.floor(count\/h_wrap)\n else \n if(grow == 1 or grow == 2 or grow == 5) then \n row_pos = count\n else\n col_pos = count \n end\n end\n \n local x = 0\n local y = 0\n if(grow == 1) then \n -- grow right\n x = row_pos*(size+padding)\n y = col_pos*(size+padding) * -1\n elseif (grow == 2) then\n -- grow left\n x = row_pos*(size+padding) * -1\n y = col_pos*(size+padding) * -1\n elseif (grow == 3) then\n -- grow up\n x = row_pos*(size+padding)\n y = col_pos*(size+padding)\n -- y = col_pos*(size+padding)\n elseif (grow == 4) then\n -- grow down\n x = row_pos*(size+padding)\n y = col_pos*(size+padding) * -1\n elseif (grow == 5) then\n -- expand horizontally\n local mod = 1\n if(count % 2 == 1)then \n mod = -1\n end\n row_pos = math.ceil(count \/ 2)\n -- y = col_pos*(size+padding)\n x = row_pos*(size+padding) * mod\n elseif (grow == 6) then\n -- expand vertically\n local mod = 1\n if(count % 2 == 1)then \n mod = -1\n end\n col_pos = math.ceil(count \/ 2)\n -- x = row_pos*(size+padding)\n y = col_pos*(size+padding) * mod\n end\n \n return x,y\n \nend\n\nfuncs[\"CountParty\"] = function() \n local raid_members = GetNumRaidMembers()\n if(raid_members > 1)then return raid_members end\n local party_members = GetNumPartyMembers() + 1\n return party_members\nend\n\nfuncs[\"CountBuff\"] = function(base_name, h_env)\n local env = h_env\n local source = nil\n local real_name = nil\n local d = env[\"spell_types\"]\n local relevant_types = {}\n local h_list = \"\"\n local l_list = \"\"\n for a,b in pairs(d) do \n if(b == base_name) then \n if(env[\"buff_mask\"][a]) then \n relevant_types[env[\"buff_mask\"][a]] = true\n else \n relevant_types[a] = true\n end\n end\n end\n \n local total_found = 0\n if not (GetNumRaidMembers() == 0) then\n for member_iter=1, GetNumRaidMembers() do\n local did_find_buff = false\n for name_iter, _ in pairs(relevant_types) do \n local name, _, _, _, _, _, _, caster = UnitBuff(\"raid\"..member_iter,name_iter)\n \n if(relevant_types[name])then \n total_found = total_found + 1\n if(caster ~= nil) then \n source = caster\n real_name = name\n end\n did_find_buff = true\n break\n end \n end\n local hn = UnitName(\"raid\"..member_iter)\n if(hn) then \n if(did_find_buff) then \n h_list = h_list..hn..\", \"\n else \n l_list = l_list..hn..\", \"\n end\n end\n end\n elseif not (GetNumPartyMembers() == 0) then\n for member_iter=0, GetNumPartyMembers() do\n local did_find_buff = false\n local party_member = member_iter==0 and \"player\" or \"party\"..member_iter\n for name_iter, _ in pairs(relevant_types) do \n local name, _, _, _, _, _, _, caster = UnitBuff(party_member,name_iter)\n \n if(relevant_types[name])then \n total_found = total_found + 1\n if(caster ~= nil) then \n source = caster\n real_name = name\n end\n did_find_buff = true\n break\n end\n end\n local hn = UnitName(party_member)\n if(hn) then \n if(did_find_buff) then \n h_list = h_list..hn..\", \"\n else \n l_list = l_list..hn..\", \"\n end\n end\n end\n else\n --we're alone\n local did_find_buff = false\n for name_iter, _ in pairs(relevant_types) do \n local name, _, _, _, _, _, _, caster = UnitBuff(\"player\",name_iter)\n \n if(relevant_types[name])then \n total_found = total_found + 1\n if(caster ~= nil) then \n source = caster\n real_name = name\n end\n did_find_buff = true\n break\n end\n end\n local hn = UnitName(\"player\")\n if(hn) then \n if(did_find_buff) then \n h_list = h_list..hn..\", \"\n else \n l_list = l_list..hn..\", \"\n end\n end\n end\n \n if(source) then \n source = UnitName(source)\n end\n if(source == nil) then \n source = \"Name not found\"\n end\n \n for a,b in pairs(env[\"buff_mask\"]) do \n if(b == real_name) then \n real_name = a\n break\n end\n end\n \n return total_found, source, real_name, string.gsub(h_list, \", $\", \"\"), string.gsub(l_list, \", $\", \"\")\nend\n\nfuncs[\"FormatTime\"] = function(sec) \n local min = sec \/ 60.0\n local hr = min \/ 60.0\n \n if(hr >= 1) then \n return string.format(\"%.1f\",hr)..\"hr\"\n elseif(min >= 1) then\n return string.format(\"%.0f\",min)..\"min\"\n end\n return string.format(\"%.0f\",sec)..\"sec\"\nend\n\nfuncs[\"RelevantPlayer\"] = function(targetName,casterName)\n if(casterName==UnitName(\"player\")) then\n return true \n end\n inRaid = UnitInRaid(casterName)\n if(inRaid) then \n return true\n end\n inGroup = UnitInGroup(casterName)\n if(inGroup) then \n return true\n end\n \n if(UnitExists(casterName))then \n return true\n end\n \n return false\nend\n\nfuncs[\"CalculatePostion\"] = CalculatePosition2\n\n\nbuffs = {}\n\nlocal sp = {}\nsp[\"Arcane Brilliance\"] = \"Arcane Brilliance\"\nsp[\"Demonic Pact\"] = \"Arcane Brilliance\"\nsp[\"Totem of Wrath\"] = \"Arcane Brilliance\"\nsp[\"Arcane Intellect\"] = \"Arcane Brilliance\"\nsp[\"Flametongue Totem\"] = \"Arcane Brilliance\"\n\nsp[\"Blessing of Kings\"] = \"Blessing of Kings\"\nsp[\"Greater Blessing of Kings\"] = \"Blessing of Kings\"\n\nsp[\"Blessing of Might\"] = \"Blessing of Might\"\nsp[\"Battle Shout\"] = \"Blessing of Might\"\nsp[\"Strength of Earth Totem\"] = \"Blessing of Might\"\nsp[\"Greater Blessing of Might\"] = \"Blessing of Might\"\n\nsp[\"Blessing of Wisdom\"] = \"Blessing of Wisdom\"\nsp[\"Greater Blessing of Wisdom\"] = \"Blessing of Wisdom\"\nsp[\"Mana Spring Totem\"] = \"Blessing of Wisdom\"\n\nsp[\"Divine Spirit\"] = \"Divine Spirit\"\nsp[\"Prayer of Spirit\"] = \"Divine Spirit\"\n\nsp[\"Mark of the Wild\"] = \"Mark of the Wild\"\nsp[\"Gift of the Wild\"] = \"Mark of the Wild\"\n\nsp[\"Power Word: Fortitude\"] = \"Power Word: Fortitude\"\nsp[\"Prayer of Fortitude\"] = \"Power Word: Fortitude\"\n\nsp[\"Commanding Shout\"] = \"Commanding Shout\"\nsp[\"Blood Pact\"] = \"Commanding Shout\"\n\nsp[\"Thorns\"] = \"Thorns\"\n\nsp[\"Blessing of Sanctuary\"] = \"Blessing of Sanctuary\"\nsp[\"Greater Blessing of Sanctuary\"] = \"Blessing of Sanctuary\"\n\nsp[\"Tree of Life\"] = \"Tree of Life\"\nsp[\"Blessing of Sanctuary (heal)\"] = \"Tree of Life\"\nsp[\"Greater Blessing of Sanctuary (heal)\"] = \"Tree of Life\"\n\nsp[\"Inspiration\"] = \"Inspiration\"\nsp[\"Ancestral Fortitude\"] = \"Inspiration\"\nsp[\"Growing Light\"] = \"Inspiration\"\n\n\nsp[\"Moonkin Aura\"] = \"Moonkin Aura\"\nsp[\"Elemental Oath\"] = \"Moonkin Aura\"\n\nsp[\"Wrath of Air Totem\"] = \"Wrath of Air Totem\"\nsp[\"Swift Retribution\"] = \"Wrath of Air Totem\"\nsp[\"Moonkin's Presence\"] = \"Wrath of Air Totem\"\n\nsp[\"Rampage\"] = \"Rampage\"\nsp[\"Leader of the Pack\"] = \"Rampage\"\n\nsp[\"Sanctified Retribution\"] = \"Sanctified Retribution\"\nsp[\"Ferocious Inspiration\"] = \"Sanctified Retribution\"\nsp[\"Arcane Empowerment\"] = \"Sanctified Retribution\"\n\nsp[\"Trueshot Aura\"] = \"Trueshot Aura\"\nsp[\"Unleashed Rage\"] = \"Trueshot Aura\"\n\nsp[\"Devotion Aura\"] = \"Devotion Aura\"\n\nsp[\"Aspect of the Wild\"] = \"Aspect of the Wild\"\nsp[\"Nature Resistance Totem\"] = \"Aspect of the Wild\"\n\nsp[\"Fire Resistance Aura\"] = \"Fire Resistance Aura\"\nsp[\"Fire Resistance Totem\"] = \"Fire Resistance Aura\"\n\nsp[\"Frost Resistance Aura\"] = \"Frost Resistance Aura\"\nsp[\"Frost Resistance Totem\"] = \"Frost Resistance Aura\"\n\nsp[\"Shadow Resistance Aura\"] = \"Shadow Resistance Aura\"\nsp[\"Shadow Protection\"] = \"Shadow Resistance Aura\"\nsp[\"Prayer of Shadow Protection\"] = \"Shadow Resistance Aura\"\n\nsp[\"Retribution Aura\"] = \"Retribution Aura\"\n\nsp[\"Stoneskin Totem\"] = \"Stoneskin Totem\"\n\nsp[\"Heroic Presence\"] = \"Heroic Presence\"\n\n\nsp[\"Curse of the Elements\"] = \"Curse of the Elements\"\nsp[\"Earth and Moon\"] = \"Curse of the Elements\"\nsp[\"Unleashed Storm\"] = \"Curse of the Elements\"\nsp[\"Veil of Shadow\"] = \"Curse of the Elements\"\n\nsp[\"Faerie Fire\"] = \"Faerie Fire\"\nsp[\"Faerie Fire (Feral)\"] = \"Faerie Fire\"\nsp[\"Fractured Defenses\"] = \"Faerie Fire\"\nsp[\"Earthborer Acid\"] = \"Faerie Fire\"\nsp[\"Earthborer's Acid\"] = \"Faerie Fire\"\nsp[\"Curse of Weakness\"] = \"Faerie Fire\"\nsp[\"Scorpid Sting\"] = \"Faerie Fire\"\n\nsp[\"Cripple\"] = \"Demoralizing Shout\"\nsp[\"Curse of Weakness (AP)\"] = \"Demoralizing Shout\"\nsp[\"Demoralizing Roar\"] = \"Demoralizing Shout\"\nsp[\"Demoralizing Screech\"] = \"Demoralizing Shout\"\nsp[\"Demoralizing Shout\"] = \"Demoralizing Shout\"\nsp[\"Echoing Frost\"] = \"Demoralizing Shout\"\nsp[\"Eldritch Condemnation\"] = \"Demoralizing Shout\"\nsp[\"Fracture\"] = \"Demoralizing Shout\"\nsp[\"Grim Strike\"] = \"Demoralizing Shout\"\nsp[\"Soul Leech\"] = \"Demoralizing Shout\"\nsp[\"Vindication\"] = \"Demoralizing Shout\"\n\nsp[\"Improved Scorch\"] = \"Improved Scorch\"\nsp[\"Winter's Chill\"] = \"Improved Scorch\"\nsp[\"Nature Mastery\"] = \"Improved Scorch\"\nsp[\"Shadow Mastery\"] = \"Improved Scorch\"\nsp[\"Guiding Strike\"] = \"Improved Scorch\"\n\nsp[\"Totem of Wrath (crit)\"] = \"Master Poisoner\"\nsp[\"Heart of the Crusader\"] = \"Master Poisoner\"\nsp[\"Master Poisoner\"] = \"Master Poisoner\"\n\nsp[\"Sunder Armor\"] = \"Sunder Armor\"\nsp[\"Acid Blast\"] = \"Sunder Armor\"\nsp[\"Acid Spit\"] = \"Sunder Armor\"\nsp[\"Acidic Strike\"] = \"Sunder Armor\"\nsp[\"Brutal Strike\"] = \"Sunder Armor\"\nsp[\"Corrosive Acid\"] = \"Sunder Armor\"\nsp[\"Corrosive Acid Breath\"] = \"Sunder Armor\"\nsp[\"Demoralizing Banner\"] = \"Sunder Armor\"\nsp[\"Expose Armor\"] = \"Sunder Armor\"\nsp[\"Magma Splash\"] = \"Sunder Armor\"\nsp[\"Sunder Armor (Pet)\"] = \"Sunder Armor\"\nsp[\"Torn to Scraps\"] = \"Sunder Armor\"\nsp[\"Void Strike\"] = \"Sunder Armor\"\n\nsp[\"Trauma\"] = \"Trauma\"\nsp[\"Mangle (Bear)\"] = \"Trauma\"\nsp[\"Mangle (Cat)\"] = \"Trauma\"\n\nsp[\"Blood Frenzy\"] = \"Blood Frenzy\"\nsp[\"Savage Combat\"] = \"Blood Frenzy\"\n-- hack to detect Blood Frenzy \/ Savage Combat\nsp[\"Deep Wounds\"] = \"Blood Frenzy\"\n-- sp[\"Mind-numbing Poison\"] = \"Blood Frenzy\"\n-- sp[\"Crippling Poison\"] = \"Blood Frenzy\"\n-- sp[\"Deadly Poison\"] = \"Blood Frenzy\"\n-- sp[\"Wound Poison\"] = \"Blood Frenzy\"\n--sp[\"\"] = \"\"\n\n\nlocal icon_collection = {}\nicon_collection[1] = \"Arcane Brilliance\"\nicon_collection[4] = \"Blessing of Kings\"\nicon_collection[7] = \"Blessing of Might\"\nicon_collection[10] = \"Blessing of Sanctuary\"\nicon_collection[13] = \"Blessing of Wisdom\"\nicon_collection[16] = \"Divine Spirit\"\nicon_collection[19] = \"Mark of the Wild\"\nicon_collection[22] = \"Power Word: Fortitude\"\nicon_collection[25] = \"Commanding Shout\"\nicon_collection[28] = \"Thorns\"\nicon_collection[31] = \"Inspiration\"\n\nicon_collection[2] = \"Devotion Aura\"\nicon_collection[5] = \"Aspect of the Wild\"\nicon_collection[8] = \"Fire Resistance Aura\"\nicon_collection[11] = \"Frost Resistance Aura\"\nicon_collection[14] = \"Shadow Resistance Aura\"\nicon_collection[17] = \"Retribution Aura\"\nicon_collection[20] = \"Trueshot Aura\"\nicon_collection[23] = \"Rampage\"\nicon_collection[26] = \"Moonkin Aura\"\nicon_collection[29] = \"Sanctified Retribution\"\nicon_collection[32] = \"Heroic Presence\"\n\nicon_collection[3] = \"Wrath of Air Totem\"\nicon_collection[6] = \"Stoneskin Totem\"\nicon_collection[9] = \"Tree of Life\"\nicon_collection[12] = \"Sunder Armor\"\nicon_collection[15] = \"Curse of the Elements\"\nicon_collection[18] = \"Master Poisoner\"\nicon_collection[21] = \"Improved Scorch\"\nicon_collection[24] = \"Faerie Fire\"\nicon_collection[27] = \"Demoralizing Shout\"\nicon_collection[30] = \"Trauma\"\nicon_collection[33] = \"Blood Frenzy\"\n\n\nlocal ability_ids = {}\nability_ids[\"Arcane Brilliance\"] = \"Interface\/icons\/spell_holy_magicalsentry\"\nability_ids[\"Faerie Fire\"] = \"Interface\/icons\/spell_nature_faeriefire\"\nability_ids[\"Improved Scorch\"] = \"Interface\/Icons\/spell_fire_soulburn\"\nability_ids[\"Wrath of Air Totem\"] = \"Interface\/Icons\/spell_nature_slowingtotem\"\nability_ids[\"Moonkin Aura\"] = \"Interface\/icons\/spell_nature_moonglow\"\nability_ids[\"Rampage\"] = \"Interface\/icons\/Ability_Warrior_Rampage\"\nability_ids[\"Trueshot Aura\"] = \"Interface\/icons\/Ability_TrueShot\"\nability_ids[\"Power Word: Fortitude\"] = \"Interface\/icons\/Spell_holy_wordfortitude\"\nability_ids[\"Blessing of Might\"] = \"Interface\/icons\/spell_holy_fistofjustice\"\nability_ids[\"Demoralizing Shout\"] = \"Interface\/icons\/ability_warrior_warcry\"\nability_ids[\"Mark of the Wild\"] = \"Interface\/icons\/spell_nature_regeneration\"\nability_ids[\"Blessing of Kings\"] = \"Interface\/icons\/spell_magic_magearmor\"\nability_ids[\"Divine Spirit\"] = \"Interface\/icons\/spell_holy_divinespirit\"\nability_ids[\"Blessing of Wisdom\"] = \"Interface\/icons\/spell_holy_sealofwisdom\"\nability_ids[\"Curse of the Elements\"] = \"Interface\/icons\/spell_shadow_chilltouch\"\nability_ids[\"Sanctified Retribution\"] = \"Interface\/icons\/spell_holy_mindvision\"\nability_ids[\"Devotion Aura\"] = \"Interface\/icons\/spell_holy_devotionaura\"\nability_ids[\"Aspect of the Wild\"] = \"Interface\/icons\/spell_nature_protectionformnature\"\nability_ids[\"Fire Resistance Aura\"] = \"Interface\/icons\/spell_fire_sealoffire\"\nability_ids[\"Frost Resistance Aura\"] = \"Interface\/icons\/spell_frost_wizardmark\"\nability_ids[\"Shadow Resistance Aura\"] = \"Interface\/icons\/spell_shadow_sealofkings\"\nability_ids[\"Master Poisoner\"] = \"Interface\/icons\/ability_creature_poison_06\"\nability_ids[\"Stoneskin Totem\"] = \"Interface\/icons\/spell_nature_stoneskintotem\"\nability_ids[\"Heroic Presence\"] = \"Interface\/icons\/inv_helmet_21\"\nability_ids[\"Sunder Armor\"] = \"Interface\/icons\/ability_warrior_sunder\"\nability_ids[\"Commanding Shout\"] = \"Interface\/icons\/ability_warrior_rallyingcry\"\nability_ids[\"Thorns\"] = \"Interface\/icons\/spell_nature_thorns\"\nability_ids[\"Retribution Aura\"] = \"Interface\/icons\/spell_holy_auraoflight\"\nability_ids[\"Blessing of Sanctuary\"] = \"Interface\/icons\/spell_nature_lightningshield\"\nability_ids[\"Tree of Life\"] = \"Interface\/icons\/ability_druid_treeoflife\"\nability_ids[\"Inspiration\"] = \"Interface\/icons\/spell_holy_layonhands\"\nability_ids[\"Trauma\"] = \"Interface\/icons\/ability_warrior_bloodnova\"\nability_ids[\"Blood Frenzy\"] = \"Interface\/icons\/ability_warrior_bloodfrenzy\"\n\nlocal buff_mask = {}\nbuff_mask[\"Strength of Earth Totem\"] = \"Strength of Earth\"\nbuff_mask[\"Mana Spring Totem\"] = \"Mana Spring\"\nbuff_mask[\"Nature Resistance Totem\"] = \"Nature Resistance\"\nbuff_mask[\"Fire Resistance Totem\"] = \"Fire Resistance\"\nbuff_mask[\"Frost Resistance Totem\"] = \"Frost Resistance\"\nbuff_mask[\"Stoneskin Totem\"] = \"Stoneskin\"\nbuff_mask[\"Blessing of Sanctuary (heal)\"] = \"Blessing of Sanctuary\"\nbuff_mask[\"Greater Blessing of Sanctuary (heal)\"] = \"Greater Blessing of Sanctuary\"\nbuff_mask[\"Curse of Weakness (AP)\"] = \"Curse of Weakness\"\nbuff_mask[\"Totem of Wrath (crit)\"] = \"Totem of Wrath\"\n\nlocal is_aura = {}\n-- 1 is the \"real\" trigger (NYI)\nis_aura[\"Rampage\"] = 2\nis_aura[\"Trueshot Aura\"] = 3\nis_aura[\"Sanctified Retribution\"] = 4\nis_aura[\"Devotion Aura\"] = 5\nis_aura[\"Aspect of the Wild\"] = 6\nis_aura[\"Fire Resistance Aura\"] = 7\nis_aura[\"Frost Resistance Aura\"] = 8\nis_aura[\"Shadow Resistance Aura\"] = 9\nis_aura[\"Wrath of Air Totem\"] = 10\nis_aura[\"Heroic Presence\"] = 11\nis_aura[\"Thorns\"] = 12\nis_aura[\"Retribution Aura\"] = 13\n\nlocal is_debuff = {}\nis_debuff[\"Improved Scorch\"] = true\nis_debuff[\"Faerie Fire\"] = true\nis_debuff[\"Demoralizing Shout\"] = true\nis_debuff[\"Curse of the Elements\"] = true\nis_debuff[\"Master Poisoner\"] = true\nis_debuff[\"Sunder Armor\"] = true\nis_debuff[\"Trauma\"] = true\nis_debuff[\"Blood Frenzy\"] = true\n\nself[\"spell_types\"] = sp\nself[\"icon_collection\"] = icon_collection\nself[\"is_debuff\"] = is_debuff\nself[\"ability_ids\"] = ability_ids\nself[\"buff_mask\"] = buff_mask\nself[\"is_aura\"] = is_aura\n\nself[\"players\"] = {}\nself[\"player_pool\"] = {}\n\nfuncs[\"UpsertPlayer\"] = function(casterName,spellName,was_removal,h_env)\n local env = h_env\n -- if(self == nil)then \n -- self = env\n -- end\n local players = env[\"players\"]\n local spellType = env[\"spell_types\"][spellName]\n \n if(not was_removal) then \n if(not players[casterName]) then \n players[casterName]={}\n end\n if(not players[casterName][spellType]) then \n players[casterName][spellType] = {}\n end\n \n local pd = nil\n if(players[casterName][spellType]) then \n pd = players[casterName][spellType]\n pd[\"cast_at\"] = GetTime()\n pd[\"spell_name\"] = spellName\n players[casterName][spellType] = pd\n else\n pd = {}\n pd[\"name\"] = casterName\n pd[\"spell_name\"] = spellName\n pd[\"stack_name\"] = spellType\n pd[\"cast_at\"] = GetTime()\n \n players[casterName][spellType] = pd\n end\n end\n \n if(not env[\"player_pool\"][spellType]) then \n env[\"player_pool\"][spellType] = {}\n end\n local p = env[\"player_pool\"][spellType]\n \n if (not was_removal) then \n local found = false\n for count,name in ipairs(p) do \n if(name == casterName) then \n found = true\n break\n end\n end\n \n if(not found) then \n table.insert(p,casterName) \n end\n end\n \n -- need this\n table.sort(p, function(a,b) \n local left = players[a][spellType][\"cast_at\"]\n local right = players[b][spellType][\"cast_at\"]\n return left > right\n end)\n \n -- test if icon should be greyed out \/ desaturated\n Timer.After(0.1, function() env[\"funcs\"][\"DesaturateIcon\"](spellType,env) end)\n -- env[\"funcs\"][\"DesaturateIcon\"](spellType,env)\n env[\"player_pool\"][spellType] = p\n -- need this\nend\n\nself.spell_cds = {}\n\nself[\"deep_wounds\"] = function(spellName)\n if(spellName == \"Deep Wounds\") then \n return true\n end\n return false\nend\n\n\nfuncs[\"RelevantAbility\"] = function(spellName) \n if(self[\"spell_types\"][spellName] or self[\"deep_wounds\"](spellName)) then \n local real_name = spellName\n local stack_name = self[\"spell_types\"][spellName]\n \n if(not self.spell_cds[stack_name]) then \n self.spell_cds[stack_name] = GetTime() + 0.1\n return true\n end\n \n if(GetTime() < self.spell_cds[stack_name])then \n return false\n end\n \n self.spell_cds[stack_name] = GetTime() + 0.1\n return true\n \n end\n \n return false\nend\n\nfuncs[\"PetOwner\"] = function(petName,env)\n local self = aura_env\n if(not self)then \n self = env\n end\n if(not self)then \n return nil\n end\n if(not self.scanTool) then \n return nil\n end\n if(not petName) then\n return nil \n end\n self.scanTool:ClearLines()\n self.scanTool:SetUnit(petName)\n local ownerText = self.scanText:GetText()\n if not ownerText then return nil end\n local owner, _ = string.split(\"'\",ownerText)\n return owner -- This is the pet's owner\nend\n\n\nfuncs[\"DesaturateIcon\"] = function(spell_base,h_env)\n local env = h_env\n if(not env) then \n return\n end\n \n local c = nil\n for index, spell in ipairs(env[\"icon_collection\"]) do \n if(spell == spell_base) then \n c = index\n break\n end\n end\n if(c == nil or not env.icons or not env.icons[c]) then\n return\n end\n \n local size = env[\"funcs\"][\"CountParty\"]()\n local has_buff = env[\"funcs\"][\"CountBuff\"](spell_base,env)\n local is_aura = env[\"is_aura\"][spell_base]\n \n -- if debuff, test if it's been applied in last 30 min\n \n if(size == has_buff or (is_aura and has_buff > 0))then \n env.icons[c]:SetDesaturated(true)\n else\n env.icons[c]:SetDesaturated(false)\n end\nend\n\n\nself[\"funcs\"]=funcs\n\n\nif(self.frames == nil) then\n self.frames = {}\n self.icons = {}\n self.tooltips = {}\n local scanTool = CreateFrame( \"GameTooltip\", \"ScanTooltip\", nil, \"GameTooltipTemplate\" )\n scanTool:SetOwner( WorldFrame, \"ANCHOR_NONE\" )\n local scanText = _G[\"ScanTooltipTextLeft2\"] -- This is the line with <[Player]'s Pet>\n self.scanTool = scanTool\n self.scanText = scanText\nelse\nend\n\n\nfunction MakeFrame2 (spellName,i)\n local icon_type = self[\"spell_types\"][spellName]\n local frame\n local icon\n local tooltip\n \n if(self.frames[i]) then \n frame = self.frames[i]\n icon = self.icons[i]\n tooltip = self.tooltips[i]\n -- update\n else\n frame = CreateFrame('Button', WeakAuras.GenerateUniqueID(), self.region,\n 'SecureActionButtonTemplate')\n frame:SetBackdrop({\n bgFile = \"Interface\\\\Tooltips\\\\UI-Tooltip-Background\",\n edgeFile = \"Interface\\\\Tooltips\\\\UI-Tooltip-Border\",\n tile = true,\n tileSize = 16,\n edgeSize = 16,\n insets = { left = 4, right = 4, top = 4, bottom = 4 }\n })\n frame:SetBackdropColor(0, 0, 0, 1) \n tooltip = CreateFrame(\"GameTooltip\", WeakAuras.GenerateUniqueID(), self.region, \"GameTooltipTemplate\")\n icon = frame:CreateTexture(nil,\"ARTWORK\")\n end\n --hardcoded for now\n \n size = 32\n padding = 2\n \n local hoisted_env = self\n local function OnEnter(x) \n local message = \"\"\n local spellType = x:GetAttribute(\"type1\")\n local tt_ref = x:GetAttribute(\"type2\")\n --local hoisted_env = x:GetAttribute(\"type3\")\n \n if(hoisted_env[\"is_aura\"][spellType]) then \n -- -- if it's an aura\n local size = hoisted_env[\"funcs\"][\"CountParty\"]()\n local has_buff, caster, specific, has, lacks = hoisted_env[\"funcs\"][\"CountBuff\"](spellType,hoisted_env)\n \n if(caster ~= \"Name not found\" and specific ~= nil) then \n hoisted_env[\"funcs\"][\"UpsertPlayer\"](caster,specific,false,hoisted_env)\n -- if(self ~= nil) then \n -- hoisted_env = self\n -- end\n end\n \n if(hoisted_env[\"player_pool\"] and hoisted_env[\"player_pool\"][spellType]) then\n for rank,casterName in pairs(hoisted_env[\"player_pool\"][spellType]) do \n local players = hoisted_env[\"players\"]\n if(players[casterName] and players[casterName][spellType]) then \n local pd = players[casterName][spellType]\n local formattedTime = funcs[\"FormatTime\"](GetTime()-pd[\"cast_at\"])\n \n local es = \"provided\"\n if(rank == 1 and has_buff > 0)then\n es = \"provides\" \n end\n \n message = message..\"|cffFFFFFF\"..rank..\"|r: \"..\"|cffFF7C0A\"..casterName..\"|r \"..es..\" \"..pd[\"spell_name\"]..\"\\n\"\n end\n end\n end\n \n local color = size == has_buff and \"00FF98\" or \"C41E3A\"\n \n if(has_buff == 0 and string.len(message) == 0) then \n message = \"Not provided currently\\n\"\n elseif(string.len(message) == 0) then \n message = \"Not provided recently\\n\"\n end\n \n message = message..(string.len(has) > 0 and (\"\\n|cff00FF98Has|r: \"..has..\"\\n\") or \"\")..(string.len(lacks) > 0 and (\"|cffC41E3ALacks|r: \"..lacks..\"\\n\") or \"\")\n message = \"|cff00ff00\"..spellType..\"|r (|cff\"..color..has_buff..\"|r\/\"..size..\")\\n\"..message\n \n -- elseif(hoisted_env[\"is_debuff\"][spellType]) then\n else\n -- if it's a normal buff\n if(hoisted_env[\"player_pool\"] and hoisted_env[\"player_pool\"][spellType]) then \n for rank,casterName in pairs(hoisted_env[\"player_pool\"][spellType]) do \n local players = hoisted_env[\"players\"]\n if(players[casterName] and players[casterName][spellType]) then \n local pd = players[casterName][spellType]\n local formattedTime = funcs[\"FormatTime\"](GetTime()-pd[\"cast_at\"])\n message = message..\"|cffFFFFFF\"..rank..\"|r: \"..\"|cffFF7C0A\"..casterName..\"|r applied \"..pd[\"spell_name\"]..\" \"..formattedTime..\" ago\\n\"\n end\n end\n end\n \n local has_buff, _, _, has, lacks = hoisted_env[\"funcs\"][\"CountBuff\"](spellType,hoisted_env)\n \n local size = hoisted_env[\"funcs\"][\"CountParty\"]()\n local color = size == has_buff and \"00FF98\" or \"C41E3A\"\n \n if(hoisted_env[\"is_debuff\"][spellType]) then \n if(string.len(message) == 0) then \n message = \"|cff00ff00\"..spellType..\"|r\\n\"..\"Not applied recently\"\n else \n message = \"|cff00ff00\"..spellType..\"|r\\n\"..message\n end\n else \n if(string.len(message) == 0) then \n message = \"|cff00ff00\"..spellType..\"|r (|cff\"..color..has_buff..\"|r\/\"..size..\")\\n\"..\"Not applied recently\"\n else\n message = \"|cff00ff00\"..spellType..\"|r (|cff\"..color..has_buff..\"|r\/\"..size..\")\\n\"..message\n message = message..(string.len(has) > 0 and (\"\\n|cff00FF98Has|r: \"..has..\"\\n\") or \"\")..(string.len(lacks) > 0 and (\"|cffC41E3ALacks|r: \"..lacks..\"\\n\") or \"\")\n end\n end\n \n end\n \n local tt = hoisted_env.tooltips[tt_ref]\n local f = hoisted_env.frames[tt_ref]\n if(tt and f) then\n tt:SetOwner(f,\"ANCHOR_BOTTOMRIGHT\")\n tt:SetPoint(\"LEFT\",f,\"RIGHT\")\n message = string.gsub(message, \"\\n$\", \"\")\n tt:SetText(message, 1.5, 0.82, 0.0, 0.75, true)\n tt:Show()\n end\n end\n local function OnLeave(x) \n local tt_ref = x:GetAttribute(\"type2\") \n local tt = hoisted_env.tooltips[tt_ref]\n if(tt) then\n tt:Hide()\n end\n end\n \n frame:SetScript(\"OnEnter\",OnEnter)\n frame:SetScript(\"OnLeave\",OnLeave) \n \n frame:SetWidth(size)\n frame:SetHeight(size)\n local x, y = CalculatePosition2(i-1,size,padding)\n frame:SetPoint(\"CENTER\", x, y)\n frame:SetAttribute(\"type1\",icon_type)\n frame:SetAttribute(\"type2\",i)\n \n local path = nil\n if(path == nil and self.ability_ids[icon_type]) then \n path = self.ability_ids[icon_type]\n end\n \n icon:SetTexture(path)\n icon:SetAllPoints(frame)\n \n -- test if icon should be greyed out \/ desaturated\n Timer.After(0.1, function() self[\"funcs\"][\"DesaturateIcon\"](spellName,self) end)\n --self[\"funcs\"][\"DesaturateIcon\"](spellName,self)\n \n frame:Show()\n icon:Show()\n \n self.frames[i] = frame\n self.icons[i] = icon\n self.tooltips[i] = tooltip\nend\n\nself.MakeFrame2 = MakeFrame2\n\nself.MakeFrames2 = function() \n for count,spell in ipairs(self[\"icon_collection\"]) do\n self.MakeFrame2(spell,count)\n end\nend \n\nself.MakeSingleFrame = function(arg)\n local s_arg = self[\"spell_types\"][arg]\n for count,spell in ipairs(self[\"icon_collection\"]) do\n if(spell == s_arg) then \n self.MakeFrame2(spell,count)\n break\n end\n end\nend \n\nself.MakeFrames2()\n\n\nfunction HideFrame2(spellName,i)\n local icon_type = self[\"spell_types\"][spellName]\n if(self.frames[i]) then \n self.frames[i]:Hide()\n end\nend\nself.HideFrame2 = HideFrame2\n\nself.HideFrames2 = function() \n for count,spell in ipairs(self[\"icon_collection\"]) do\n self.HideFrame2(spell,count)\n end\nend"
},
"finish": {
"do_glow": true
}
},
"tocversion": 30300,
"id": "Buff Tracking by Aramis",
"authorOptions": [],
"frameStrata": 1,
"width": 8.0002,
"uid": "8D(UM0ubguL",
"config": [],
"inverse": false,
"anchorFrameType": "SCREEN",
"alpha": 1,
"displayIcon": "Interface\\Icons\\_D3frenzy",
"information": [],
"desaturate": false
},
"s": "4.2.5",
"v": 1421
}