Compare with Previous | Blame | View Log
local addon = LibStub("NaturCombat"); -- Get our library LibStub("LibWombat"):NewParser(addon); -- Set addon as our parser for Wombat local CPAura = false; ---------------------------------------------------------------------------------------------------- -- START PARSING ---------------------------------------------------------------------------------------------------- addon:StartParsing("VARIABLES_LOADED", function() -- Wipe saved variables of the old beta. local ver = GetAddOnMetadata("NaturCombat", "Version"); if (ver ~= NaturDB.Version) then NaturDB = addon.default; end -- Check to see if the user has chosen to display separate groups or a single one. addon.groups["NATUR"] = addon:CreateBarGroup("NaturCombat"); for name, group in pairs(addon.bargroups) do addon.groups[name] = addon:CreateBarGroup(group); if (not NaturDB.Groups) then addon.groups[name]:SetDisplayGroup("NaturCombat"); addon.groups[name]:SetAnchorVisible(false); else addon.groups["NATUR"]:SetAnchorVisible(false); end end end); ---------------------------------------------------------------------------------------------------- -- PLAYER_ENTERING_WORLD -- Wipe all bars when entering an arena game. ---------------------------------------------------------------------------------------------------- addon:StartParsing("PLAYER_ENTERING_WORLD", function() local _, zone = IsInInstance(); if (zone == "arena") then -- Player is in an arena match for anchor, _ in pairs(addon.groups) do addon.groups[anchor]:UnregisterAllBars(); -- Delete ALL Bars end for id, _ in pairs(addon.CDTable) do addon.CDTable[id] = nil; -- Remove an active cooldown from the cooldown table end end end); ---------------------------------------------------------------------------------------------------- -- SPELL_AURA_APPLIED -- Create Timer's for abilites from our spell DB ---------------------------------------------------------------------------------------------------- addon:StartParsing("SPELL_AURA_APPLIED", function(when, what, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...) local spell = addon:GetSpellData(...); -- Get spelldata on the spell applied. local auraType = select(4, ...); -- Check to see if we have 'only track our debuffs' option active if (NaturDB.Track) then return; end -- Enabled so don't do anything in this function if (UnitGUID("player") == dstGUID) then return; end if (NaturDB.TargetFocus and UnitGUID("target") ~= dstGUID and UnitGUID("focus") ~= dstGUID) then return; end if (spell and spell.duration) then -- Check that this spell is currently in our spell DB (spells.lua) --Does this debuff get affected by talents? This is a PLAYER only feature -- To understand the numbers - 1,2,3,4,5 = Tree #, Talent number in Tree, Original Duration of spell, Modifier of the duration, Class if (spell.talent) then if (spell.talent[5] == select(2, UnitClass("player"))) then local _, _, _, _, rank = GetTalentInfo(spell.talent[1], spell.talent[2]); if (rank and rank > 0) then spell.duration = spell.talent[3] + rank * spell.talent[4]; end end end -- Does this spell have a different duration on a PVP Enabled player? local duration = 0; if (spell.pvpdur and (bit.band(strsub(dstGUID, 1, 5), 0x00F) == 0)) then -- Is this target a player? And does this spell have a pvp duration? duration = spell.pvpdur; else duration = spell.duration; end -- TODO: Diminishing Returns if (dstGUID == UnitGUID("target") and spell.diminish and NaturDB.Diminishing) then addon:ApplyDiminish(spell.id, dstName, dstGUID); duration = duration * addon.multiplier; end --Combo point ability? if (spell.combo) then CPAura = true; end local barID = dstGUID .. spell.id; local text = spell.name .. " - " .. addon:StripName(dstName); local color = NaturDB.Colors["GREY"]; local anchor = "DEBUFFS"; if (auraType == "BUFF") then if (CombatLog_Object_IsA(dstFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS)) then color = NaturDB.Colors["HOSTILEBUFF"]; anchor = "HOSTILEGAIN"; elseif (CombatLog_Object_IsA(dstFlags, COMBATLOG_FILTER_FRIENDLY_UNITS)) then color = NaturDB.Colors["FRIENDLYBUFF"]; anchor = "FRIENDLYGAIN"; end elseif (auraType == "DEBUFF") then anchor = "DEBUFFS"; if (spell.stun) then color = NaturDB.Colors["STUN"]; elseif (spell.dot) then color = NaturDB.Colors["DOT"]; else color = NaturDB.Colors["DEBUFF"]; end end local ticon = nil; if (NaturDB.Icon) then -- Are we shoing Target and Focus icons? if (dstGUID == UnitGUID("target")) then ticon = addon.media:Fetch("icon", "Target"); elseif (dstGUID == UnitGUID("focus")) then ticon = addon.media:Fetch("icon", "Focus"); end end addon.groups[anchor]:RegisterBar(barID, text, duration, nil, spell.icon, ticon, color.r, color.g, color.b); end end); ---------------------------------------------------------------------------------------------------- -- SPELL_CAST_SUCCESS -- Deal with Instant casts and also Cooldowns ---------------------------------------------------------------------------------------------------- addon:StartParsing("SPELL_CAST_SUCCESS", function(when, what, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...) local spell = addon:GetSpellData(...); if (NaturDB.Track) then return end; if (spell and spell.duration) then if (NaturDB.TargetFocus and UnitGUID("target") == dstGUID or UnitGUID("focus") == dstGUID) then -- No way to determine anchor for k, v in pairs(addon.groups) do addon.groups[k]:SetTime(dstGUID..spell.id, spell.duration); end end end if (spell.special and srcGUID == UnitGUID("player")) then -- show timer for player local barID = srcGUID .. spell.id; local color = NaturDB.Colors["FRIENDLYBUFF"]; local text = spell.name .. " - " .. srcName; addon.groups["FRIENDLYGAIN"]:RegisterBar(barID, text, spell.duration, nil, spell.icon, nil, color.r, color.g, color.b); end if (UnitGUID("player") == srcGUID) then return; end if (spell and spell.cooldown) then -- Track CDS of current target/focus if (NaturDB.Cooldowns) then local barID = srcGUID .. spell.id .. "CD"; local color = NaturDB.Colors["COOLDOWN"]; local text = spell.name .. " [CD] - " .. addon:StripName(srcName); local ticon = nil; if (NaturDB.Icon) then if (srcGUID == UnitGUID("target")) then ticon = addon.media:Fetch("icon", "Target"); elseif (srcGUID == UnitGUID("focus")) then ticon = addon.media:Fetch("icon", "Focus"); end end if (NaturDB.TargetFocus and UnitGUID("target") ~= srcGUID and UnitGUID("focus") ~= srcGUID) then addon.CDTable[barID] = {srcGUID, spell.cooldown}; addon.groups["COOLDOWNS"]:RegisterBar(barID, text, spell.cooldown, nil, spell.icon, ticon, color.r, color.g, color.b); addon.groups["COOLDOWNS"]:HideBar(barID); else addon.CDTable[barID] = {srcGUID, spell.cooldown}; addon.groups["COOLDOWNS"]:RegisterBar(barID, text, spell.cooldown, nil, spell.icon, ticon, color.r, color.g, color.b); end end end end); ---------------------------------------------------------------------------------------------------- -- SPELL_AURA_REMOVED -- Remove a bar with an aura is applied ---------------------------------------------------------------------------------------------------- addon:StartParsing("SPELL_AURA_REMOVED", function(when, what, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...) local spell = addon:GetSpellData(...); if (spell and spell.duration) then if (spell.combo) then CPAura = false; end if (spell.diminish) then if (addon.dims[dstGUID .. spell.id .. spell.diminish .. "DR"]) then addon:RemoveDiminish(spell.id, dstName, dstGUID); end end for k, v in pairs(addon.groups) do addon.groups[k]:UnregisterBar(dstGUID .. spell.id); end end end); ---------------------------------------------------------------------------------------------------- -- SPELL_INTERRUPT -- Deal with interupt abilites ---------------------------------------------------------------------------------------------------- addon:StartParsing("SPELL_INTERRUPT", function(when, what, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...) local inter = addon:GetSpellData(...); local spell = addon:GetSpellData(select(12, ...)); if (NaturDB.Track) then return; end if (UnitGUID("player") == dstGUID) then return; end if (NaturDB.TargetFocus and UnitGUID("target") ~= dstGUID and UnitGUID("focus") ~= dstGUID) then return; end if (inter and inter.interrupt) then local barID = dstGUID .. inter.id; local color = NaturDB.Colors["DEBUFF"]; local text = inter.name .. " - " .. addon:StripName(dstName); local ticon = nil; if (NaturDB.Icon) then if (dstGUID == UnitGUID("target")) then ticon = addon.media:Fetch("icon", "Target"); elseif (dstGUID == UnitGUID("focus")) then ticon = addon.media:Fetch("icon", "Focus"); end end addon.groups["DEBUFFS"]:RegisterBar(barID, text, inter.duration, nil, inter.icon, ticon, color.r, color.g, color.b); end if (spell and spell.duration) then for k, v in pairs(addon.groups) do addon.groups[k]:UnregisterBar(dstGUID .. spell.id); end end end); ---------------------------------------------------------------------------------------------------- -- SPELL_AURA_APPLIED_DOSE -- Deal with abilites which stack ---------------------------------------------------------------------------------------------------- addon:StartParsing("SPELL_AURA_APPLIED_DOSE", function(when, what, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...) local spell = addon:GetSpellData(...); local stack = select(5, ...); local auraType = select(4, ...); if (UnitGUID("player") == dstGUID) then return; end if (NaturDB.TargetFocus and UnitGUID("target") ~= dstGUID and UnitGUID("focus") ~= dstGUID) then return; end if (NaturDB.Track) then return; end if (spell and spell.duration and spell.stacks) then local barID = dstGUID .. spell.id; local text = "(" .. stack .. ") " .. spell.name .. " - " .. addon:StripName(dstName); local anchor; if (auraType == "BUFF") then if (CombatLog_Object_IsA(dstFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS)) then anchor = "HOSTILEGAIN"; elseif (CombatLog_Object_IsA(dstFlags, COMBATLOG_FILTER_FRIENDLY_UNITS)) then anchor = "FRIENDLYGAIN"; end elseif (auraType == "DEBUFF") then anchor = "DEBUFFS"; end addon.groups[anchor]:SetBarText(barID, text); addon.groups[anchor]:SetTime(barID, spell.duration); end end); ---------------------------------------------------------------------------------------------------- -- SPELL_AURA_REMOVED_DOSE ---------------------------------------------------------------------------------------------------- addon:StartParsing("SPELL_AURA_REMOVED_DOSE", function(when, what, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...) local spell = addon:GetSpellData(...); local stack = select(5, ...); local auraType = select(4, ...); if (UnitGUID("player") == dstGUID) then return; end if (NaturDB.TargetFocus and UnitGUID("target") ~= dstGUID and UnitGUID("focus") ~= dstGUID) then return; end if (NaturDB.Track) then return; end if (spell and spell.duration and spell.stacks) then local barID = dstGUID .. spell.id; local text = "(" .. stack .. ") " .. spell.name .. " - " .. addon:StripName(dstName); local anchor; if (auraType == "BUFF") then if (CombatLog_Object_IsA(dstFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS)) then anchor = "HOSTILEGAIN"; elseif (CombatLog_Object_IsA(dstFlags, COMBATLOG_FILTER_FRIENDLY_UNITS)) then anchor = "FRIENDLYGAIN"; end elseif (auraType == "DEBUFF") then anchor = "DEBUFFS"; end addon.groups[anchor]:SetBarText(barID, text); end end); ---------------------------------------------------------------------------------------------------- -- UNIT_DIED -- Delete all bars we had assoiciated with the unit who died ---------------------------------------------------------------------------------------------------- addon:StartParsing("UNIT_DIED", function(when, what, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...) if (dstGUID == UnitGUID("player")) then return; end for k, v in pairs(addon.spelldata) do if (v.diminish) then addon.groups["COOLDOWNS"]:UnregisterBar(dstGUID .. k .. v.diminish .. "DR"); end for a, b in pairs(addon.groups) do addon.groups[a]:UnregisterBar(dstGUID..k); addon.groups[a]:UnregisterBar(dstGUID..k.."CD"); addon.CDTable[dstGUID..k.."CD"] = nil; end end end); ---------------------------------------------------------------------------------------------------- -- PLAYER_TARGET_CHANGED ---------------------------------------------------------------------------------------------------- addon:StartParsing("PLAYER_TARGET_CHANGED", function() for k, v in pairs(addon.CDTable) do if (UnitGUID("target") ~= v[1]) then addon.groups["COOLDOWNS"]:HideBar(k); else addon.groups["COOLDOWNS"]:ShowBar(k, v[2]); end end end); ---------------------------------------------------------------------------------------------------- -- PLAYER_FOCUS_CHANGED ---------------------------------------------------------------------------------------------------- addon:StartParsing("PLAYER_FOCUS_CHANGED", function() for k, v in pairs(addon.CDTable) do if (UnitGUID("focus") ~= v[1]) then addon.groups["COOLDOWNS"]:HideBar(k); else addon.groups["COOLDOWNS"]:ShowBar(k, v[2]); end end end); ---------------------------------------------------------------------------------------------------- -- PARTY_KILL -- When you score a killing blow ---------------------------------------------------------------------------------------------------- addon:StartParsing("PARTY_KILL", function(when, what, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...) if (srcGUID == UnitGUID("player") and (bit.band(strsub(dstGUID, 1, 5), 0x00F) == 0) and NaturDB.Sounds) then if (not addon.killtimer) or (GetTime() - addon.killtimer > 60) then PlaySoundFile(addon.media:Fetch("sound", "First Blood")); addon.killcounter = 0; elseif (GetTime() - addon.killtimer <= 60) then addon.killcounter = addon.killcounter + 1 if (addon.killcounter == 1) then PlaySoundFile(addon.media:Fetch("sound", "Dominating")); elseif (addon.killcounter == 2) then PlaySoundFile(addon.media:Fetch("sound", "Killing Spree")); elseif (addon.killcounter == 3) then PlaySoundFile(addon.media:Fetch("sound", "Unstoppable")); elseif (addon.killcounter == 4) then PlaySoundFile(addon.media:Fetch("sound", "Monster Kill")); elseif (addon.killcounter > 4) then PlaySoundFile(addon.media:Fetch("sound", "Godlike")); end end addon.killtimer = GetTime(); end end); ---------------------------------------------------------------------------------------------------- -- UNIT_AURA ---------------------------------------------------------------------------------------------------- addon:StartParsing("UNIT_AURA", function(unitid) if (UnitGUID(unitid) == UnitGUID("player")) then return; end if (NaturDB.TargetFocus and UnitGUID("target") ~= dstGUID and UnitGUID("focus") ~= dstGUID) then return; end if (not NaturDB.Track) then -- Deal with normal player combo point abilites if (not CPAura) then return; end local id = 0; while (true) do id = id + 1; local name, _, _, _, _, duration = UnitDebuff(unitid, id); if (not name) then return; end local keys, data = addon.spellkeys, addon.spelldata; if (keys[name]) then if (data[keys[name]].combo and data[keys[name]].duration) then if (not duration) then duration = data[keys[name]].duration; end addon.groups["DEBUFFS"]:SetTime(UnitGUID(unitid)..data[keys[name]].id, duration); CPAura = false; end end end else -- Track our stuff local id = 0; while (true) do id = id + 1; local keys, data = addon.spellkeys, addon.spelldata; -- BUFFS local buffName, _, buffIcon, buffCount, buffDuration = UnitBuff(unitid, id); if (not buffName) then return; end if (buffName and buffDuration) then if (keys[buffName]) then -- This buff is in our database local barID = UnitGUID(unitid) .. data[keys[buffName]].id; -- Check that we don't already have a timer for this ability if (addon.timers[barID]) then return; end local text = buffName .. " - " .. addon:StripName(UnitName(unitid)); local ticon = nil; local color = NaturDB.Colors["FRIENDLYBUFF"]; if (NaturDB.Icon) then if (unitid == "target") then ticon = addon.media:Fetch("icon", "Target"); elseif (unitid == "focus") then ticon = addon.media:Fetch("icon", "Focus"); end end addon.groups["FRIENDLYGAIN"]:RegisterBar(barID, text, buffDuration, nil, buffIcon, ticon, color.r, color.g, color.b); addon.timers[barID] = buffName; end end -- DEBUFFS local debuffName, _, debuffIcon, debuffStack, _, debuffDuration = UnitDebuff(unitid, id); if (not debuffName) then return; end if (debuffName and debuffDuration) then if (keys[debuffName]) then local barID = UnitGUID(unitid) .. data[keys[debuffName]].id; if (addon.timers[barID]) then return end; local text = debuffName .. " - " .. addon:StripName(UnitName(unitid)); local ticon = nil; local color = NaturDB.Colors["DEBUFF"]; if (data[keys[debuffName]].stun) then color = NaturDB.Colors["STUN"]; elseif (data[keys[debuffName]].dot) then color = NaturDB.Colors["DOT"]; end if (NaturDB.Icon) then if (unitid == "target") then ticon = addon.media:Fetch("icon", "Target"); elseif (unitid == "focus") then ticon = addon.media:Fetch("icon", "Focus"); end end addon.groups["DEBUFFS"]:RegisterBar(barID, text, debuffDuration, nil, debuffIcon, ticon, color.r, color.g, color.b); addon.timers[barID] = debuffName; end end end end end); ---------------------------------------------------------------------------------------------------- -- UNIT_SPELLCAST_START ---------------------------------------------------------------------------------------------------- addon:StartParsing("UNIT_SPELLCAST_START", function(unitid, spell, ...) if (UnitGUID(unitid) == UnitGUID("player")) then return; end if (not NaturDB.Casting) then return; end if (NaturDB.Casting and unitid ~= "target" and unitid ~= "focus") then return; end local color = NaturDB.Colors["GREY"]; local anchor = "FRIENDLYCAST"; if (UnitReaction(unitid, "player") < 4) then -- Hostile Player color = NaturDB.Colors["HOSTILECAST"]; anchor = "HOSTILECAST"; else color = NaturDB.Colors["FRIENDLYCAST"]; anchor = "FRIENDLYCAST"; end local barID = UnitGUID(unitid) .. "Cast"; local icon, sTime, eTime = select(4, UnitCastingInfo(unitid)); sTime, eTime = sTime / 1000, eTime / 1000; local text = spell .. " - " .. addon:StripName(UnitName(unitid)); local ticon = nil; if (NaturDB.Icon) then if (unitid == "target") then ticon = addon.media:Fetch("icon", "Target"); elseif (unitid == "focus") then ticon = addon.media:Fetch("icon", "Focus"); end end addon.groups[anchor]:RegisterBar(barID, text, eTime - sTime, nil, icon, ticon, color.r, color.g, color.b); end); ---------------------------------------------------------------------------------------------------- -- UNIT_SPELLCAST_STOP ---------------------------------------------------------------------------------------------------- addon:StartParsing("UNIT_SPELLCAST_STOP", function(unitid) -- This is meant to return the spell and rank aswell according to the wiki if (NaturDB.Casting and unitid ~= "target" and unitid ~= "focus") then return; end addon.groups["FRIENDLYCAST"]:UnregisterBar(UnitGUID(unitid).."Cast"); addon.groups["HOSTILECAST"]:UnregisterBar(UnitGUID(unitid).."Cast"); end); ---------------------------------------------------------------------------------------------------- -- UNIT_SPELLCAST_CHANNEL_START ---------------------------------------------------------------------------------------------------- addon:StartParsing("UNIT_SPELLCAST_CHANNEL_START", function(unitid, spell, ...) if (UnitGUID(unitid) == UnitGUID("player")) then return; end if (not NaturDB.Casting) then return; end if (NaturDB.Casting and unitid ~= "target" and unitid ~= "focus") then return; end local color = NaturDB.Colors["GREY"]; local anchor = "FRIENDLYCAST"; if (UnitReaction(unitid, "player") < 4) then -- Hostile Player color = NaturDB.Colors["HOSTILECAST"]; anchor = "HOSTILECAST"; else color = NaturDB.Colors["FRIENDLYCAST"]; anchor = "FRIENDLYCAST"; end local barID = UnitGUID(unitid) .. "Channel"; local icon, sTime, eTime = select(4, UnitChannelInfo(unitid)); sTime, eTime = sTime / 1000, eTime / 1000; local text = spell .. " - " .. addon:StripName(UnitName(unitid)); local ticon = nil; if (NaturDB.Icon) then if (unitid == "target") then ticon = addon.media:Fetch("icon", "Target"); elseif (unitid == "focus") then ticon = addon.media:Fetch("icon", "Focus"); end end addon.groups[anchor]:RegisterBar(barID, text, eTime - sTime, nil, icon, ticon, color.r, color.g, color.b); end); ---------------------------------------------------------------------------------------------------- -- UNIT_SPELLCAST_CHANNEL_STOP ---------------------------------------------------------------------------------------------------- addon:StartParsing("UNIT_SPELLCAST_CHANNEL_STOP", function(unitid) if (NaturDB.Casting and unitid ~= "target" and unitid ~= "focus") then return; end addon.groups["FRIENDLYCAST"]:UnregisterBar(UnitGUID(unitid).."Channel"); addon.groups["HOSTILECAST"]:UnregisterBar(UnitGUID(unitid).."Channel"); end); ---------------------------------------------------------------------------------------------------- -- APPLY DIMINISHING RETURN ---------------------------------------------------------------------------------------------------- local expTimer = {}; function addon:ApplyDiminish(spellID, dstName, dstGUID) local spell = addon:GetSpellData(spellID); local barID = dstGUID .. spell.id .. spell.diminish .. "DR"; local time = GetTime(); local multiplier = 100; if (expTimer[barID] and expTimer[barID] >= time) then multiplier = self:GetDR(addon.dims[barID]); addon.dims[barID] = multiplier; expTimer[barID] = GetTime() + 15; addon.groups["COOLDOWNS"]:UnregisterBar(barID); elseif (not expTimer[barID] or expTimer[barID] <= time) then addon.dims[barID] = multiplier; addon.multiplier = 1; expTimer[barID] = GetTime() + 15; end end; ---------------------------------------------------------------------------------------------------- -- REMOVE DIMINISHING RETURN ---------------------------------------------------------------------------------------------------- function addon:RemoveDiminish(spellID, dstName, dstGUID) local spell = addon:GetSpellData(spellID); local barID = dstGUID .. spell.id .. spell.diminish .. "DR"; if (addon.dims[barID]) then local text = spell.name .. " DR ["..spell.diminish.." |cffff2020"..select(2, self:GetDR(addon.dims[barID])).."/3|r] - " .. addon:StripName(dstName); local color = NaturDB.Colors["COOLDOWN"]; addon.groups["COOLDOWNS"]:RegisterBar(barID, text, 15, nil, spell.icon, nil, color.r, color.g, color.b); end expTimer[barID] = GetTime() + 15; end; function addon:GetDR(dr) if (dr == 100) then return 50, 1, 0.5; elseif (dr == 50) then return 25, 2, 0.25; elseif (dr == 25) then return 0, "Immune! 3", 0; end end;