WoWInterface SVN Critline

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 25 to Rev 24
    Reverse comparison

Rev 25 → Rev 24

trunk/AuraTracker.lua File deleted \ No newline at end of file
trunk/Critline.toc
1,6 → 1,6
## Interface: 40100
## Title: Critline
## Version: 4.1.0
## Version: 4.0.3
## Notes: Saves your normal and critical records and flashes a message if you break the record.
## Author: L'ombra
## SavedVariables: CritlineDB
31,5 → 31,4
announce.lua
reset.lua
Broker.lua
profiles.lua
AuraTracker.lua
\ No newline at end of file +profiles.lua \ No newline at end of file
trunk/templates.lua
431,10 → 431,6
local normal = data.normal and data.normal.amount
local crit = data.crit and data.crit.amount
item.icon:SetTexture(addon:GetSpellTexture(data.spellID))
if addon.filters then
item.icon:SetDesaturated(data.filtered)
item.spell:SetFontObject(data.filtered and "GameFontDisable" or "GameFontNormal")
end
item.spell:SetText(addon:GetFullSpellName(data.spellID, data.periodic))
item.target:SetFormattedText("%s / %s", data.normal and data.normal.target or "n/a", data.crit and data.crit.target or "n/a")
item.record:SetFormattedText("%s\n%s", addon:ShortenNumber(normal or 0), addon:ShortenNumber(crit or 0))
trunk/Broker.lua
51,17 → 51,14
 
 
local function updateRecords(event, tree)
if not tree then
if tree then
local normal, crit = addon:GetHighest(tree)
feeds[tree].text = format("%s/%s", addon:ShortenNumber(normal), addon:ShortenNumber(crit))
else
for k in pairs(feeds) do
updateRecords(event, k)
end
return
end
 
if addon.percharDB.profile[tree] then
local normal, crit = addon:GetHighest(tree)
feeds[tree].text = format("%s/%s", addon:ShortenNumber(normal), addon:ShortenNumber(crit))
end
end
 
 
trunk/changeLog.txt
1,18 → 1,3
4.1.0
- Remove water elemental from class pets as it's now treated as a permanent pet.
- Add Kill Command tooltip exception.
- Move aura tracker out of the filter module and into its own module.
- Aura tracker should now pick up auras even when no source was provided.
- Pet damage will now obey aura filtering.
- Fix error occuring upon attacking filtered targets.
- Add Berserking (battlegrounds), Spirit's Vengeance (Bloodord Mandokir) and Sunder Rift (Jin'do) to aura filters.
- Add new spell IDs for some Cataclysm raid auras.
- Add Ragezone (normal mode Deadmines), and remove it from target aura, since it no longer increases damage taken.
- Periodic healing done to yourself while under the effects of a filtered (healing-received-increased) aura should now be properly filtered.
- Periodic effects can now be registered if it ticks on a vulnerable target, as long as the effect was applied before the vulnerability aura. (somewhat experimental)
- Spells in the reset and announce lists will now be grayed out if they're filtered.
- Toggling short number format should no longer affect the Broker objects whose tree is disabled.
 
4.0.3
- Updated for WoW 4.1.
- Added Sweeping Strikes and Aimed Shot! exceptions.
62,7 → 47,7
- The frame's alpha can now be changed.
- It should no longer be possible to force show the frame when no trees are enabled, resulting in a weird appearance.
 
- Reset and announce spell lists had their appearance redesigned. Click to directly do your thing, instead of checking and then clicking.
- Reset and announce spell lists had their appearance redesigned. Click to directly to your thing, instead of checking and then clicking.
- New records achieved in the last fight can now be undone in the reset module. Eligible spells will have a different button.
- Spell profiles should now display the correct used profiles at all times.
- Updated libraries.
trunk/core.lua
11,7 → 11,7
local L = LibStub("AceLocale-3.0"):GetLocale(addonName)
local LSM = LibStub("LibSharedMedia-3.0")
local templates = Critline.templates
local _, playerClass = UnitClass("player")
local playerClass = select(2, UnitClass("player"))
local debugging
 
-- auto attack spell
50,10 → 50,12
 
-- non hunter pets whose damage we may want to register
local classPets = {
[510] = true, -- Water Elemental
[11859] = true, -- Doomguard
[15438] = true, -- Greater Fire Elemental
[27829] = true, -- Ebon Gargoyle
[29264] = true, -- Spirit Wolf
[37994] = true, -- Water Elemental (glyphed)
}
 
-- spells that are essentially the same, but has different IDs, we'll register them under the same ID
99,7 → 101,6
[31801] = 42463, -- Seal of Truth
[31850] = 66235, -- Ardent Defender
[33076] = 33110, -- Prayer of Mending
[34026] = 83381, -- Kill Command
[43265] = 52212, -- Death and Decay
[47540] = 47666, -- Penance
[47541] = 47632, -- Death Coil (death knight)
623,8 → 624,10
 
-- if sourceGUID is not us or our pet, we leave
if not CombatLog_Object_IsA(sourceFlags, COMBATLOG_FILTER_MINE) then
local isMyPet = CombatLog_Object_IsA(sourceFlags, COMBATLOG_FILTER_MY_PET)
local isGuardian = band(sourceFlags, COMBATLOG_OBJECT_TYPE_GUARDIAN) ~= 0
-- only register if it's a real pet, or a guardian tree pet that's included in the filter
if self:IsMyPet(sourceFlags, sourceGUID) then
if isMyPet and ((not isGuardian and HasPetUI()) or classPets[tonumber(sourceGUID:sub(7, 10), 16)]) then
isPet = true
-- self:Debug(format("This is my pet (%s)", sourceName))
else
688,16 → 691,16
end
end
 
local isPvPTarget = band(destFlags, COMBATLOG_OBJECT_CONTROL_PLAYER) ~= 0
local isPlayer = band(destFlags, COMBATLOG_OBJECT_CONTROL_PLAYER) ~= 0
local friendlyFire = band(destFlags, COMBATLOG_OBJECT_REACTION_FRIENDLY) ~= 0
local hostileTarget = band(destFlags, COMBATLOG_OBJECT_REACTION_HOSTILE) ~= 0
 
if not (isPvPTarget or self.db.profile.PvE or isHeal) then
if not (isPlayer or self.db.profile.PvE or isHeal) then
self:Debug(format("Target (%s) is an NPC and PvE damage is not registered.", destName))
return
end
 
if isPvPTarget and not (self.db.profile.PvP or isHeal or friendlyFire) then
if isPlayer and not (self.db.profile.PvP or isHeal or friendlyFire) then
self:Debug(format("Target (%s) is a player and PvP damage is not registered.", destName))
return
end
760,20 → 763,13
data.amount = amount
data.target = destName
data.targetLevel = targetLevel
data.isPvPTarget = isPvPTarget
data.isPvPTarget = isPlayer
 
self:UpdateRecords(tree, isFiltered)
end
end
 
 
function Critline:IsMyPet(flags, guid)
local isMyPet = CombatLog_Object_IsA(flags, COMBATLOG_FILTER_MY_PET)
local isGuardian = band(flags, COMBATLOG_OBJECT_TYPE_GUARDIAN) ~= 0
return isMyPet and ((not isGuardian and HasPetUI()) or classPets[tonumber(guid:sub(7, 10), 16)])
end
 
 
function Critline:GetLevelFromGUID(destGUID)
tooltip:SetOwner(UIParent, "ANCHOR_NONE")
tooltip:SetHyperlink("unit:"..destGUID)
trunk/filters.lua
3,12 → 3,15
local L = LibStub("AceLocale-3.0"):GetLocale(addonName)
local templates = addon.templates
 
local band = bit.band
local CombatLog_Object_IsA = CombatLog_Object_IsA
local IsSpellKnown = IsSpellKnown
local UnitAura = UnitAura
local UnitName = UnitName
local UnitGUID = UnitGUID
local CombatLog_Object_IsA = CombatLog_Object_IsA
local band = bit.band
 
local COMBATLOG_FILTER_ME = COMBATLOG_FILTER_ME
local COMBATLOG_OBJECT_REACTION_FRIENDLY = COMBATLOG_OBJECT_REACTION_FRIENDLY
 
-- mobs whose received hits won't be tracked due to various vulnerabilities
local specialMobs = {
24,9 → 27,9
[34496] = true, -- Eydis Darkbane
[34497] = true, -- Fjola Lightbane
[38567] = true, -- Phantom Hallucination
[42347] = true, -- Exposed Head of Magmaw ?
[42803] = true, -- Drakeadon Mongrel
[46083] = true, -- Drakeadon Mongrel
[42347] = true, -- Exposed Head of Magmaw (Point of Vulnerability [79011]) ?
[42803] = true, -- Drakeadon Mongrel (Brood Power: Red/Green/Black/Blue/Bronze [80368+80369+80370+80371+80372])
[46083] = true, -- Drakeadon Mongrel (Brood Power: Red/Green/Black/Blue/Bronze [80368+80369+80370+80371+80372])
[46273] = true, -- Debilitated Apexar
[48270] = true, -- Exposed Head of Magmaw
}
34,7 → 37,6
-- auras that when gained will suppress record tracking
local specialAuras = {
[18173] = true, -- Burning Adrenaline (Vaelastrasz the Corrupt)
[24378] = true, -- Berserking (battlegrounds)
[41337] = true, -- Aura of Anger (Reliquary of Souls)
[41350] = true, -- Aura of Desire (Reliquary of Souls)
[44335] = true, -- Energy Feedback (Vexallus)
49,18 → 51,18
[58549] = true, -- Tenacity (Lake Wintergrasp)
[59641] = true, -- Warchief's Blessing (The Battle For The Undercity)
[60964] = true, -- Strength of Wrynn (The Battle For The Undercity)
[61888] = true, -- Overwhelming Power (Assembly of Iron 25)
[61888] = true, -- Overwhelming Power (Assembly of Iron - 25 man)
[62243] = true, -- Unstable Sun Beam (Elder Brightleaf)
[62650] = true, -- Fortitude of Frost (Yogg-Saron)
[62670] = true, -- Resilience of Nature (Yogg-Saron)
[62671] = true, -- Speed of Invention (Yogg-Saron)
[62702] = true, -- Fury of the Storm (Yogg-Saron)
[63277] = true, -- Shadow Crash (General Vezax)
[63711] = true, -- Storm Power (Hodir 10)
[63711] = true, -- Storm Power (Hodir - 10 man)
[64320] = true, -- Rune of Power (Assembly of Iron)
[64321] = true, -- Potent Pheromones (Freya)
[64637] = true, -- Overwhelming Power (Assembly of Iron 10)
[65134] = true, -- Storm Power (Hodir 25)
[64637] = true, -- Overwhelming Power (Assembly of Iron - 10 man)
[65134] = true, -- Storm Power (Hodir - 25 man)
[70867] = true, -- Essence of the Blood Queen (Blood Queen Lana'thel)
[70879] = true, -- Essence of the Blood Queen (Blood Queen Lana'thel, bitten by a player)
[72219] = true, -- Gastric Bloat (Festergut)
72,20 → 74,16
[76355] = true, -- Blessing of the Sun (Rajh)
[76693] = true, -- Empowering Twilight (Crimsonborne Warlord)
[79624] = true, -- Power Generator (Arcanotron) ?
[79629] = true, -- Power Generator (Arcanotron 10)
[81096] = true, -- Red Mist (Red Mist)
[86622] = true, -- Engulfing Magic (Theralion) ?
[86872] = true, -- Frothing Rage (Thundermar Ale)
[89879] = true, -- Blessing of the Sun (Rajh heroic)
[90932] = true, -- Ragezone (Defias Blood Wizard)
[90933] = true, -- Ragezone (Defias Blood Wizard heroic)
[89879] = true, -- Blessing of the Sun (Rajh - heroic)
[90933] = true, -- Ragezone (Defias Blood Wizard)
[91871] = true, -- Lightning Charge (Siamat)
[91555] = true, -- Power Generator (Arcanotron 25)
[93777] = true, -- Invocation of Flame (Skullcrusher the Mountain)
[95639] = true, -- Engulfing Magic (Theralion) ?
[95640] = true, -- Engulfing Magic (Theralion) ?
[95641] = true, -- Engulfing Magic (Theralion) ?
[96493] = true, -- Spirit's Vengeance (Bloodlord Mandokir)
}
 
-- these are auras that increases the target's damage or healing received
97,19 → 95,16
[75846] = true, -- Superheated Quicksilver Armor (Karsh Steelbender) ?
[76015] = true, -- Superheated Quicksilver Armor (Karsh Steelbender) ?
[76232] = true, -- Storm's Fury (Ragnaros - Mount Hyjal) ?
[77615] = true, -- Debilitating Slime (Maloriak)
[77717] = true, -- Vertigo (Atramedes 10)
[77717] = true, -- Vertigo (Atramedes)
[80164] = true, -- Chemical Cloud (Toxitron)
[87683] = true, -- Dragon's Vengeance (Halfus Wyrmbreaker)
[87904] = true, -- Feedback (Al'Akir)
[91086] = true, -- Shadow Gale (Erudax heroic)
[91478] = true, -- Chemical Cloud (Toxitron 25) ?
[92389] = true, -- Vertigo (Atramedes 25) ?
[90933] = true, -- Ragezone (Defias Blood Wizard) ?
[91086] = true, -- Shadow Gale (Erudax - heroic)
[92390] = true, -- Vertigo (Atramedes) ?
[92910] = true, -- Debilitating Slime (Maloriak) ?
[93567] = true, -- Superheated Quicksilver Armor (Karsh Steelbender) ?
[95723] = true, -- Storm's Fury (Ragnaros - Mount Hyjal) ?
[97320] = true, -- Sunder Rift (Jin'do the Godbreaker)
}
 
-- these heals are treated as periodic, but has no aura associated with them, or is associated to an aura with a different name, need to add exceptions for them to filter properly
118,16 → 113,24
-- [63106] = "Corruption", -- Siphon Life
}
 
local activeAuras = {
player = {},
pet = {},
local activeAuras = {}
local corruptSpells = {}
local corruptTargets = {}
 
local playerAuras = {
session = {},
instance = {},
lastFight = {},
}
local corruptSpells = {
player = {},
pet = {},
local enemyAuras = {
session = {},
instance = {},
lastFight = {},
}
local corruptTargets = {}
 
-- name of current instance
local currentInstance = L["n/a"]
 
-- amount of buttons in the spell, mob and aura filter scroll lists
local NUMSPELLBUTTONS = 8
local SPELLBUTTONHEIGHT = 22
504,14 → 507,10
delete:SetText(L["Delete aura"])
delete.msg = L["%s removed from aura filter."]
delete.func = function(spellID)
activeAuras.player[spellID] = nil
activeAuras.pet[spellID] = nil
if not filters:IsEmpowered("player") then
addon:Debug("No filtered aura detected on player. Resuming record tracking.")
activeAuras[spellID] = nil
if not filters:IsEmpowered() then
addon:Debug("No filtered aura detected. Resuming record tracking.")
end
if not filters:IsEmpowered("pet") then
addon:Debug("No filtered aura detected on pet. Resuming record tracking.")
end
end
end
 
550,6 → 549,346
end
 
 
do
local auraList = CreateFrame("Frame", nil, UIParent)
auraList:SetFrameStrata("DIALOG")
auraList:EnableMouse(true)
auraList:SetSize(320, 360)
auraList:SetPoint("CENTER")
auraList:SetBackdrop({
bgFile = [[Interface\ChatFrame\ChatFrameBackground]],
edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
edgeSize = 16,
insets = {left = 4, right = 4, top = 4, bottom = 4},
})
auraList:SetBackdropColor(0, 0, 0)
auraList:SetBackdropBorderColor(0.5, 0.5, 0.5)
auraList:Hide()
 
local closeButton = CreateFrame("Button", nil, auraList, "UIPanelCloseButton")
closeButton:SetPoint("TOPRIGHT")
 
Critline.SlashCmdHandlers["aura"] = function() auraList:Show() end
 
local currentFilter = playerAuras.session
 
local function auraSort(a, b)
return currentFilter[a].spellName < currentFilter[b].spellName
end
 
local function sourceSort(a, b)
a, b = currentFilter[a], currentFilter[b]
if a.source == b.source then
return a.spellName < b.spellName
else
return a.source < b.source
end
end
 
local auraFilters = {
BUFF = true,
DEBUFF = true,
targetAffiliation = playerAuras,
sourceType = "npc",
sort = auraSort,
}
 
local function onClick(self, text)
self.owner:SetSelectedValue(self.value)
self.owner:SetText(text)
currentFilter = auraFilters.targetAffiliation[self.value]
CritlineAuraListScrollFrame:Update()
end
 
local menuList = {
{
text = L["Current fight"],
value = "lastFight",
},
{
text = L["Current instance (%s)"],
value = "instance",
},
{
text = L["Current session"],
value = "session",
},
}
 
local auraListFilter = templates:CreateDropDownMenu("CritlineAuraListFilter", auraList)
auraListFilter:SetPoint("TOP", 0, -16)
auraListFilter:SetFrameWidth(220)
auraListFilter:JustifyText("LEFT")
auraListFilter:SetSelectedValue("session")
auraListFilter:SetText(L["Current session"])
auraListFilter.initialize = function(self)
for i, v in ipairs(menuList) do
local info = UIDropDownMenu_CreateInfo()
info.text = format(v.text, currentInstance)
info.value = v.value
info.func = onClick
info.owner = self
info.arg1 = info.text
UIDropDownMenu_AddButton(info)
end
end
 
local auraListAuraType = templates:CreateDropDownMenu("CritlineAuraListAuraType", auraList)
auraListAuraType:SetPoint("TOPLEFT", auraListFilter, "BOTTOMLEFT")
auraListAuraType:SetFrameWidth(96)
auraListAuraType:JustifyText("LEFT")
auraListAuraType:SetText(L["Aura type"])
 
do
local function onClick(self)
auraFilters[self.value] = self.checked
CritlineAuraListScrollFrame:Update()
end
 
local menuList = {
{
text = L["Buffs"],
value = "BUFF",
},
{
text = L["Debuffs"],
value = "DEBUFF",
},
}
 
auraListAuraType.initialize = function(self)
for i, v in ipairs(menuList) do
local info = UIDropDownMenu_CreateInfo()
info.text = v.text
info.value = v.value
info.func = onClick
info.checked = auraFilters[v.value]
info.isNotRadio = true
info.keepShownOnClick = true
UIDropDownMenu_AddButton(info)
end
end
end
 
local auraListFilters = templates:CreateDropDownMenu("CritlineAuraListFilters", auraList)
auraListFilters:SetPoint("TOPRIGHT", auraListFilter, "BOTTOMRIGHT")
auraListFilters:SetFrameWidth(96)
auraListFilters:JustifyText("LEFT")
auraListFilters:SetText(FILTERS)
 
do
local function onClick(self, key)
auraFilters[key] = self.value
self.owner:Refresh()
self.owner:SetText(FILTERS)
currentFilter = auraFilters.targetAffiliation[auraListFilter:GetSelectedValue()]
CritlineAuraListScrollFrame:Update()
end
 
local function checked(self)
return auraFilters[self.arg1] == self.value
end
 
local menuList = {
{
text = L["Show auras cast on me"],
value = playerAuras,
arg1 = "targetAffiliation",
},
{
text = L["Show auras cast on hostile NPCs"],
value = enemyAuras,
arg1 = "targetAffiliation",
},
{
text = L["Show auras cast by NPCs"],
value = "npc",
arg1 = "sourceType",
},
{
text = L["Show auras cast by players"],
value = "pvp",
arg1 = "sourceType",
},
{
text = L["Sort by aura name"],
value = auraSort,
arg1 = "sort",
},
{
text = L["Sort by source name"],
value = sourceSort,
arg1 = "sort",
},
}
 
auraListFilters.initialize = function(self)
for i, v in ipairs(menuList) do
local info = UIDropDownMenu_CreateInfo()
info.text = v.text
info.value = v.value
info.func = onClick
info.checked = checked
info.owner = self
info.keepShownOnClick = true
info.arg1 = v.arg1
UIDropDownMenu_AddButton(info)
end
end
end
 
local search = templates:CreateEditBox(auraList)
search:SetPoint("TOPLEFT", auraListAuraType, "BOTTOMLEFT", 18, -8)
search:SetPoint("TOPRIGHT", auraListFilters, "BOTTOMRIGHT", -18, -8)
search:SetWidth(192)
search:SetScript("OnTextChanged", function() CritlineAuraListScrollFrame:Update() end)
search:SetScript("OnEscapePressed", search.ClearFocus)
 
local label = search:CreateFontString(nil, nil, "GameFontNormalSmall")
label:SetPoint("BOTTOMLEFT", search, "TOPLEFT")
label:SetText(L["Text filter"])
 
local NUM_BUTTONS = 6
local BUTTON_HEIGHT = 36
 
local auraListScrollFrame = CreateFrame("ScrollFrame", "CritlineAuraListScrollFrame", auraList, "FauxScrollFrameTemplate")
auraListScrollFrame:SetHeight(NUM_BUTTONS * BUTTON_HEIGHT)
auraListScrollFrame:SetPoint("TOP", search, "BOTTOM", 0, -8)
auraListScrollFrame:SetPoint("LEFT", 32, 0)
auraListScrollFrame:SetPoint("RIGHT", -32, 0)
auraListScrollFrame:SetScript("OnVerticalScroll", function(self, offset) FauxScrollFrame_OnVerticalScroll(self, offset, BUTTON_HEIGHT, self.Update) end)
 
local sortedAuras = {}
 
function auraListScrollFrame:Update()
if not auraList:IsShown() then
self.doUpdate = true
return
end
 
self.doUpdate = nil
 
wipe(sortedAuras)
 
local n = 0
local search = search:GetText():lower()
for spellID, v in pairs(currentFilter) do
if auraFilters[v.type] and v.sourceType == auraFilters.sourceType and (v.spellName:lower():find(search, nil, true) or v.sourceName:lower():find(search, nil, true)) then
n = n + 1
sortedAuras[n] = spellID
end
end
 
sort(sortedAuras, auraFilters.sort)
 
FauxScrollFrame_Update(self, n, NUM_BUTTONS, BUTTON_HEIGHT)
 
local offset = FauxScrollFrame_GetOffset(self)
local buttons = self.buttons
for line = 1, NUM_BUTTONS do
local button = buttons[line]
local lineplusoffset = line + offset
if lineplusoffset <= n then
local spellID = sortedAuras[lineplusoffset]
button:SetFormattedText("%s (%d)", currentFilter[spellID].spellName, spellID)
button.source:SetText(currentFilter[spellID].source)
button.icon:SetTexture(addon:GetSpellTexture(spellID))
button.spellID = spellID
-- local disabled = filters:IsFilteredAura(spellID)
-- button.icon:SetDesaturated(disabled)
-- button.text:SetFontObject(disabled and "GameFontDisable" or "GameFontNormal")
button:Show()
else
button:Hide()
end
end
end
 
auraList:SetScript("OnShow", function(self)
if auraListScrollFrame.doUpdate then
auraListScrollFrame:Update()
end
end)
 
local auraListButtons = {}
auraListScrollFrame.buttons = auraListButtons
 
-- local function onClick(self)
-- local disabled = filters:IsFilteredAura(self.spellID)
-- if disabled then
-- if specialAuras[self.spellID] then
-- addon:Message("Cannot delete integrated auras.")
-- return
-- else
-- local t = filters.db.global.auras
-- for i = 1, #t do
-- if t[i] == self.spellID then
-- tremove(t, i)
-- addon:Message(format("Removed aura (%s) from filter.", GetSpellInfo(self.spellID)))
-- break
-- end
-- end
-- end
-- else
-- filters:AddAura(self.spellID)
-- end
-- disabled = not disabled
-- self.icon:SetDesaturated(disabled)
-- self.text:SetFontObject(disabled and "GameFontDisable" or "GameFontNormal")
-- end
 
local function onEnter(self)
GameTooltip:SetOwner(self, "ANCHOR_LEFT")
GameTooltip:SetSpellByID(self.spellID)
GameTooltip:AddLine(" ")
GameTooltip:AddLine(format(L["Spell ID: |cffffffff%d|r"], self.spellID))
GameTooltip:Show()
end
 
for i = 1, NUM_BUTTONS do
local btn = CreateFrame("Button", nil, auraList)
btn:SetHeight(BUTTON_HEIGHT)
if i == 1 then
btn:SetPoint("TOP", auraListScrollFrame)
else
btn:SetPoint("TOP", auraListButtons[i - 1], "BOTTOM")
end
btn:SetPoint("LEFT", auraListScrollFrame)
btn:SetPoint("RIGHT", auraListScrollFrame)
btn:SetPushedTextOffset(0, 0)
-- btn:SetScript("OnClick", onClick)
btn:SetScript("OnEnter", onEnter)
btn:SetScript("OnLeave", GameTooltip_Hide)
 
if i % 2 == 0 then
local bg = btn:CreateTexture(nil, "BACKGROUND")
bg:SetAllPoints()
bg:SetTexture(1, 1, 1, 0.1)
end
 
local icon = btn:CreateTexture()
icon:SetSize(32, 32)
icon:SetPoint("LEFT")
btn.icon = icon
 
local text = btn:CreateFontString(nil, nil, "GameFontNormal")
text:SetPoint("TOPLEFT", icon, "TOPRIGHT", 4, -4)
text:SetPoint("RIGHT")
text:SetJustifyH("LEFT")
btn:SetFontString(text)
btn.text = text
 
local source = btn:CreateFontString(nil, nil, "GameFontHighlightSmall")
source:SetPoint("BOTTOMLEFT", icon, "BOTTOMRIGHT", 4, 4)
source:SetPoint("RIGHT")
source:SetJustifyH("LEFT")
btn.source = source
 
auraListButtons[i] = btn
end
end
 
 
StaticPopupDialogs["CRITLINE_ADD_MOB_BY_NAME"] = {
text = L["Enter mob name:"],
button1 = OKAY,
698,6 → 1037,8
addon.RegisterCallback(self, "SpellsChanged", "UpdateSpellFilter")
 
self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
self:RegisterEvent("PLAYER_REGEN_DISABLED")
self:RegisterEvent("PLAYER_ENTERING_WORLD")
self:RegisterEvent("PLAYER_LOGIN")
self:RegisterEvent("UNIT_NAME_UPDATE")
self:RegisterEvent("PLAYER_CONTROL_LOST")
712,52 → 1053,80
addon.RegisterCallback(filters, "AddonLoaded")
 
 
function filters:COMBAT_LOG_EVENT_UNFILTERED(timestamp, eventType, hideCaster, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellID, spellName)
function filters:COMBAT_LOG_EVENT_UNFILTERED(timestamp, eventType, hideCaster, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellID, spellName, spellSchool, auraType)
if eventType == "SPELL_AURA_APPLIED" or eventType == "SPELL_AURA_REFRESH" then
-- if this is one of the damage-taken-increased auras, we flag this target - along with the aura in question - as rotten
if targetAuras[spellID] then
corruptTargets[destGUID] = corruptTargets[destGUID] or {}
corruptTargets[destGUID][spellID] = true
addon:Debug(format("Target (%s) gained filtered aura. (%s) Ignore received damage.", destName, spellName))
addon:Debug(format("Target (%s) gained filtered aura. (%s) Ignore received damage.", destName, spellID))
end
 
local destUnit = self:GetUnit(destFlags, destGUID)
if destUnit and self:IsFilteredAura(spellID) then
-- if we gain any aura in the filter we can just stop tracking records
if not (self:IsEmpowered(destUnit) or self.profile.ignoreAuraFilter) then
addon:Debug(format("%s gained filtered aura. (%s) Disabling combat log tracking.", destUnit:gsub(".", string.upper, 1), spellName))
if CombatLog_Object_IsA(destFlags, COMBATLOG_FILTER_ME) then
self:RegisterAura(playerAuras, sourceName, sourceGUID, spellID, spellName, auraType)
if self:IsFilteredAura(spellID) then
-- if we gain any aura in the filter we can just stop tracking records
if not (self:IsEmpowered() or self.profile.ignoreAuraFilter) then
addon:Debug(format("Filtered aura gained. (%s) Disabling combat log tracking.", spellName))
end
activeAuras[spellID] = true
end
activeAuras[destUnit][spellID] = true
else
if CombatLog_Object_IsA(sourceFlags, COMBATLOG_FILTER_ME) then
corruptSpells[spellID] = corruptSpells[spellID] or {}
corruptSpells[spellID][destGUID] = self:IsEmpowered() or self:IsVulnerableTarget(destGUID)
end
-- only non friendly NPC units
local unitType = band(destGUID:sub(1, 5), 0x007)
if (unitType ~= 0 and unitType ~= 4) and (band(destFlags, COMBATLOG_OBJECT_REACTION_FRIENDLY) == 0) then
self:RegisterAura(enemyAuras, sourceName, sourceGUID, spellID, spellName, auraType)
end
end
 
local sourceUnit = self:GetUnit(sourceFlags, sourceGUID)
if sourceUnit then
local corruptSpell = corruptSpells[sourceUnit][spellID] or {}
corruptSpell[destGUID] = self:IsEmpowered(sourceUnit) or self:IsVulnerableTarget(destGUID)
corruptSpells[sourceUnit][spellID] = corruptSpell
end
elseif (eventType == "SPELL_AURA_REMOVED" or eventType == "SPELL_AURA_BROKEN" or eventType == "SPELL_AURA_BROKEN_SPELL" or eventType == "SPELL_AURA_STOLEN") then
if targetAuras[spellID] then
corruptTargets[destGUID] = corruptTargets[destGUID] or {}
corruptTargets[destGUID][spellID] = nil
addon:Debug(format("Filtered aura (%s) faded from %s.", spellName, destName))
end
 
if self:IsFilteredAura(spellID) then
local unit = self:GetUnit(destFlags, destGUID)
if unit then
addon:Debug(format("Filtered aura (%s) faded from %s.", spellName, unit))
if CombatLog_Object_IsA(destFlags, COMBATLOG_FILTER_ME) then
if self:IsFilteredAura(spellID) then
addon:Debug(format("Filtered aura (%s) faded from player.", spellName))
-- if we lost a special aura we have to check if any other filtered auras remain
activeAuras[unit][spellID] = nil
if not filters:IsEmpowered(unit) then
addon:Debug(format("No filtered aura detected on %s. Resuming record tracking.", unit))
activeAuras[spellID] = nil
if not filters:IsEmpowered() then
addon:Debug("No filtered aura detected. Resuming record tracking.")
end
-- elseif CombatLog_Object_IsA(sourceFlags, COMBATLOG_FILTER_ME) then
-- corruptSpells[spellID] = corruptSpells[spellID] or {}
-- corruptSpells[spellID][destGUID] = nil
end
-- else
end
end
end
 
 
-- reset current fight auras upon entering combat
function filters:PLAYER_REGEN_DISABLED()
wipe(playerAuras.lastFight)
wipe(enemyAuras.lastFight)
CritlineAuraListScrollFrame:Update()
end
 
 
function filters:PLAYER_ENTERING_WORLD()
-- wipe instance buff data when entering a new instance
local instanceName = GetInstanceInfo()
if IsInInstance() and instanceName ~= currentInstance then
wipe(playerAuras.instance)
wipe(enemyAuras.instance)
currentInstance = instanceName
if CritlineAuraListFilter:GetSelectedValue() == "instance" then
CritlineAuraListFilter:SetText(format(L["Current instance (%s)"], currentInstance))
end
CritlineAuraListScrollFrame:Update()
end
end
 
 
function filters:PLAYER_LOGIN()
self:ScanAuras()
end
807,8 → 1176,10
if specialAuras[spellID] then
activeAuras[spellID] = true
end
self:RegisterAura(playerAuras, source and UnitName(source), source and UnitGUID(source), spellID, spellName, auraType)
end
end
CritlineAuraListScrollFrame:Update()
if next(auras) then
self:UnregisterEvent("UNIT_NAME_UPDATE")
end
845,7 → 1216,7
 
-- adds a mob to the mob filter
function filters:AddMob(name)
if self:IsFilteredTarget(name) then
if self:IsFilteredMob(name) then
addon:Message(L["%s is already in mob filter."]:format(name))
else
tinsert(self.db.global.mobs, name)
888,19 → 1259,17
 
-- check if a spell passes the filter settings
function filters:SpellPassesFilters(tree, spellName, spellID, isPeriodic, destGUID, destName, school, targetLevel)
local isPet = tree == "pet"
if spellID and not IsSpellKnown(spellID, isPet) and self.profile.onlyKnown then
addon:Debug(format("%s is not in your%s spell book. Return.", spellName, isPet and " pet's" or ""))
if spellID and not IsSpellKnown(spellID, tree == "pet") and self.profile.onlyKnown then
addon:Debug(format("%s is not in your%s spell book. Return.", spellName, tree == "pet" and " pet's" or ""))
return
end
 
local unit = isPet and "pet" or "player"
if ((corruptSpells[unit][spellID] and corruptSpells[unit][spellID][destGUID]) or (self:IsEmpowered(unit) and (not isPeriodic or directHoTs[spellID]))) and not self.profile.ignoreAuraFilter then
if ((corruptSpells[spellID] and corruptSpells[spellID][destGUID]) or (self:IsEmpowered() and (not isPeriodic or directHoTs[spellID]))) and not self.profile.ignoreAuraFilter then
addon:Debug(format("Spell (%s) was cast under the influence of a filtered aura. Return.", spellName))
return
end
 
if self:IsVulnerableTarget(destGUID) and not isPeriodic and not self.profile.ignoreAuraFilter then
if self:IsVulnerableTarget(destGUID) and not self.profile.ignoreAuraFilter then
addon:Debug("Target is vulnerable. Return.")
return
end
917,9 → 1286,9
return
end
 
local filteredTarget = self:IsFilteredTarget(destName, destGUID)
if filteredTarget then
addon:Debug(format("Target (%s) is in %s target filter.", destName, filteredTarget))
local filteredMob = self:IsFilteredMob(destName, destGUID)
if filteredMob then
addon:Debug(format("Target (%s) is in %s target filter.", mobName, filteredMob))
return
end
 
935,8 → 1304,8
 
 
-- scan for filtered auras from the specialAuras table
function filters:IsEmpowered(unit)
if next(activeAuras[unit]) or not self.inControl then
function filters:IsEmpowered()
if next(activeAuras) or not self.inControl then
return true
end
end
951,13 → 1320,13
end
 
 
function filters:IsFilteredTarget(targetName, guid)
function filters:IsFilteredMob(mobName, guid)
-- GUID is provided if the function was called from the combat event handler
if guid and not self.profile.ignoreMobFilter and specialMobs[tonumber(guid:sub(7, 10), 16)] then
return "default"
end
for _, v in ipairs(self.db.global.mobs) do
if v:lower() == targetName:lower() then
if v:lower() == mobName:lower() then
return "custom"
end
end
976,10 → 1345,36
end
 
 
function filters:GetUnit(unitFlags, unitGUID)
if CombatLog_Object_IsA(unitFlags, COMBATLOG_FILTER_ME) then
return "player"
elseif addon:IsMyPet(unitFlags, unitGUID) then
return "pet"
function filters:RegisterAura(auraTable, sourceName, sourceGUID, spellID, spellName, auraType)
local session = auraTable.session
if session[spellID] or IsSpellKnown(spellID) or not sourceName then
return
end
 
local source = L["n/a"]
local sourceType
 
local unitType = bit.band(sourceGUID:sub(1, 5), 0x007)
if unitType == 0 or unitType == 4 then
-- this is a player or a player's permanent pet
source = PVP
sourceType = "pvp"
else
source = tonumber(sourceGUID:sub(7, 10), 16)
sourceType = "npc"
end
 
local aura = {
source = format("%s (%s)", sourceName, source),
sourceName = sourceName,
spellName = spellName,
sourceType = sourceType,
type = auraType,
}
auraTable.lastFight[spellID] = aura
if IsInInstance() then
auraTable.instance[spellID] = aura
end
session[spellID] = aura
CritlineAuraListScrollFrame:Update()
end
\ No newline at end of file