dpslog: DPSMate CLEU adapter with per-combat A/B profiling
Adds DPSMate_CLEUAdapter.lua -- replaces DPSMate's string-parsing CHAT_MSG_* system with structured COMBAT_LOG_EVENT data from our DLL. Adapter maps CLEU subevents directly to DPSMate.DB API calls: DamageDone, DamageTaken, EnemyDamage, Healing, HealingTaken, DeathHistory, Kick, Dispels, BuildBuffs, CCBreaker, etc. Eliminates all strfind pattern matching from the combat log path. Toggle: /dpscleu (on/off/status) Benchmark: /dpsbench -- always-on per-combat A/B profiling. Resets at combat start, reports at combat end, flips mode for next combat. Reports events, total ms, us/event, GC delta, and percentage comparison between CLEU and original modes. Starts in CLEU mode by default.
@@ -0,0 +1,5 @@
|
|||||||
|
<Bindings>
|
||||||
|
<Binding name="DPSMATE_RESET" header="DPSMATE">DPSMate_PopUp:Show()</Binding>
|
||||||
|
<Binding name="DPSMATE_TOGGLE">DPSMate.Options:ToggleVisibility()</Binding>
|
||||||
|
<Binding name="DPSMATE_REPORT">if not DPSMate_Report:IsVisible() then DPSMate_Report:Show() else DPSMate_Report:Hide() end</Binding>
|
||||||
|
</Bindings>
|
||||||
@@ -0,0 +1,970 @@
|
|||||||
|
-- Global Variables
|
||||||
|
DPSMate = {}
|
||||||
|
DPSMate.VERSION = 130
|
||||||
|
DPSMate.LOCALE = GetLocale()
|
||||||
|
DPSMate.SYNCVERSION = DPSMate.VERSION..DPSMate.LOCALE
|
||||||
|
DPSMate.Parser = CreateFrame("Frame", nil, UIParent)
|
||||||
|
DPSMate.L = {}
|
||||||
|
DPSMate.DB = CreateFrame("Frame", nil, UIParent)
|
||||||
|
DPSMate.Options = CreateFrame("Frame", nil, UIParent)
|
||||||
|
DPSMate.Sync = CreateFrame("Frame", nil, UIParent)
|
||||||
|
DPSMate.Modules = {}
|
||||||
|
DPSMate.Events = {
|
||||||
|
--"CHAT_MSG_ADDON",
|
||||||
|
"PLAYER_AURAS_CHANGED",
|
||||||
|
|
||||||
|
-- Damage
|
||||||
|
"CHAT_MSG_COMBAT_SELF_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_SELF_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_PARTY_HITS",
|
||||||
|
"CHAT_MSG_SPELL_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_PARTY_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
|
||||||
|
-- Pet Damage
|
||||||
|
"CHAT_MSG_COMBAT_PET_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_PET_MISSES",
|
||||||
|
--"CHAT_MSG_SPELL_PET_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PET_DAMAGE",
|
||||||
|
|
||||||
|
-- EDD (Enemy player) / DeathHistory
|
||||||
|
"CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE",
|
||||||
|
|
||||||
|
-- Damage taken (Also EDD) / DeathHistory
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE",
|
||||||
|
|
||||||
|
-- Healing/Absorbs/Fail/DeathHistory/Dispels
|
||||||
|
"CHAT_MSG_SPELL_SELF_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_PARTY_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS",
|
||||||
|
|
||||||
|
-- Absorbs/Auras
|
||||||
|
"CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF",
|
||||||
|
"CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS",
|
||||||
|
"CHAT_MSG_SPELL_BREAK_AURA",
|
||||||
|
"CHAT_MSG_SPELL_AURA_GONE_SELF",
|
||||||
|
"CHAT_MSG_SPELL_AURA_GONE_OTHER",
|
||||||
|
"CHAT_MSG_SPELL_AURA_GONE_PARTY",
|
||||||
|
|
||||||
|
-- Death/DeathHistory
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLY_DEATH",
|
||||||
|
"CHAT_MSG_COMBAT_HOSTILE_DEATH",
|
||||||
|
}
|
||||||
|
DPSMate.Registered = true
|
||||||
|
DPSMate.RegistredModules = {}
|
||||||
|
DPSMate.ModuleNames = {}
|
||||||
|
DPSMate.UserId = nil
|
||||||
|
DPSMate.AbilityId = nil
|
||||||
|
DPSMate.Key = 1
|
||||||
|
DPSMate.DelayMsg = {}
|
||||||
|
DPSMate.BabbleSpell = BabbleSpell
|
||||||
|
DPSMate.BabbleBoss = BabbleBoss
|
||||||
|
|
||||||
|
-- Knife was wrong - 11.06.2018
|
||||||
|
|
||||||
|
-- Local Variables
|
||||||
|
local _G = getglobal
|
||||||
|
local classcolor = {
|
||||||
|
rogue = {r=1.0, g=0.96, b=0.41},
|
||||||
|
priest = {r=1,g=1,b=1},
|
||||||
|
druid = {r=1,g=0.49,b=0.04},
|
||||||
|
warrior = {r=0.78,g=0.61,b=0.43},
|
||||||
|
warlock = {r=0.58,g=0.51,b=0.79},
|
||||||
|
mage = {r=0.41,g=0.8,b=0.94},
|
||||||
|
hunter = {r=0.67,g=0.83,b=0.45},
|
||||||
|
paladin = {r=0.96,g=0.55,b=0.73},
|
||||||
|
shaman = {r=0,g=0.44,b=0.87},
|
||||||
|
}
|
||||||
|
local t = {}
|
||||||
|
local tinsert = table.insert
|
||||||
|
local strgsub = string.gsub
|
||||||
|
local func = function(c) tinsert(t, c) end
|
||||||
|
local strformat = string.format
|
||||||
|
local strgfind = string.gfind
|
||||||
|
local pairs = pairs
|
||||||
|
local strlen = strlen
|
||||||
|
local strsub = strsub
|
||||||
|
local tonumber = tonumber
|
||||||
|
local getn = getn
|
||||||
|
local tconcat = table.concat
|
||||||
|
local SendChatMessage = function(prio, prefix, text, chattype, language, destination)
|
||||||
|
ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, language, destination)
|
||||||
|
end
|
||||||
|
|
||||||
|
local DPSSettings = {}
|
||||||
|
local DPSHist = {}
|
||||||
|
local fontRefreshAt = nil
|
||||||
|
local savedFontSettings = nil
|
||||||
|
local GT = GetTime
|
||||||
|
|
||||||
|
-- Begin functions
|
||||||
|
|
||||||
|
function DPSMate:OnLoad()
|
||||||
|
SLASH_DPSMate1 = "/dps"
|
||||||
|
SlashCmdList["DPSMate"] = function(msg) DPSMate:SlashCMDHandler(msg) end
|
||||||
|
|
||||||
|
DPSMate:UpdatePointer()
|
||||||
|
|
||||||
|
-- Snapshot font settings before skinning addons can overwrite them
|
||||||
|
savedFontSettings = {}
|
||||||
|
for k, w in pairs(DPSSettings["windows"]) do
|
||||||
|
savedFontSettings[k] = {
|
||||||
|
barfont = w["barfont"],
|
||||||
|
barfontsize = w["barfontsize"],
|
||||||
|
barfontflag = w["barfontflag"],
|
||||||
|
titlebarfont = w["titlebarfont"],
|
||||||
|
titlebarfontsize = w["titlebarfontsize"],
|
||||||
|
titlebarfontflag = w["titlebarfontflag"],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate:InitializeFrames()
|
||||||
|
DPSMate.Options:InitializeConfigMenu()
|
||||||
|
|
||||||
|
if DPSMate.L.UpdateFrameTexts then
|
||||||
|
DPSMate.L.UpdateFrameTexts()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Schedule a deferred font refresh so that font settings survive
|
||||||
|
-- skinning addons (e.g. pfUI) that override fonts after load.
|
||||||
|
fontRefreshAt = GT() + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:UpdatePointer()
|
||||||
|
DPSSettings = DPSMateSettings
|
||||||
|
DPSHist = DPSMateHistory
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:SlashCMDHandler(msg)
|
||||||
|
if (msg) then
|
||||||
|
local cmd = msg
|
||||||
|
if cmd == "lock" then
|
||||||
|
DPSMate.Options:Lock()
|
||||||
|
elseif cmd == "unlock" then
|
||||||
|
DPSMate.Options:Unlock()
|
||||||
|
elseif cmd == "config" then
|
||||||
|
DPSMate_ConfigMenu:Show()
|
||||||
|
elseif cmd == "reset" then
|
||||||
|
DPSMate:SendMessage(DPSMate.L["resetconfirm"])
|
||||||
|
elseif cmd == "resetconfirm" then
|
||||||
|
DPSMateUser = {}
|
||||||
|
DPSMateAbility = {}
|
||||||
|
DPSMate.DB.abilitylen = 1
|
||||||
|
DPSMate.DB.userlen = 1
|
||||||
|
DPSMate.UserId = {}
|
||||||
|
DPSMate.Options:PopUpAccept(true, true)
|
||||||
|
DPSMate:SendMessage(DPSMate.L["resetdone"])
|
||||||
|
elseif cmd == "showAll" then
|
||||||
|
for _, val in DPSSettings["windows"] do DPSMate.Options:Show(getglobal("DPSMate_"..val["name"])) end
|
||||||
|
elseif cmd == "hideAll" then
|
||||||
|
for _, val in DPSSettings["windows"] do DPSMate.Options:Hide(getglobal("DPSMate_"..val["name"])) end
|
||||||
|
elseif strsub(cmd, 1, 4) == "show" then
|
||||||
|
local frame = _G("DPSMate_"..strsub(cmd, 6))
|
||||||
|
if frame then
|
||||||
|
DPSMate.Options:Show(frame)
|
||||||
|
else
|
||||||
|
DPSMate:SendMessage(DPSMate.L["framesavailable"])
|
||||||
|
for _, val in pairs(DPSSettings["windows"]) do
|
||||||
|
DPSMate:SendMessage("|c3ffddd80- "..val["name"].."|r")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif strsub(cmd, 1, 4) == "hide" then
|
||||||
|
local frame = _G("DPSMate_"..strsub(cmd, 6))
|
||||||
|
if frame then
|
||||||
|
DPSMate.Options:Hide(frame)
|
||||||
|
else
|
||||||
|
DPSMate:SendMessage(DPSMate.L["framesavailable"])
|
||||||
|
for _, val in pairs(DPSSettings["windows"]) do
|
||||||
|
DPSMate:SendMessage("|c3ffddd80- "..val["name"].."|r")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
DPSMate:SendMessage(DPSMate.L["slashabout"])
|
||||||
|
DPSMate:SendMessage(DPSMate.L["slashusage"])
|
||||||
|
DPSMate:SendMessage(DPSMate.L["slashlock"])
|
||||||
|
DPSMate:SendMessage(DPSMate.L["slashunlock"])
|
||||||
|
DPSMate:SendMessage(DPSMate.L["slashshowAll"])
|
||||||
|
DPSMate:SendMessage(DPSMate.L["slashhideAll"])
|
||||||
|
DPSMate:SendMessage(DPSMate.L["slashshow"])
|
||||||
|
DPSMate:SendMessage(DPSMate.L["slashhide"])
|
||||||
|
DPSMate:SendMessage(DPSMate.L["slashconfig"])
|
||||||
|
DPSMate:SendMessage(DPSMate.L["slashreset"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:InitializeFrames()
|
||||||
|
if not DPSSettings["windows"][1] then return end
|
||||||
|
for k, val in pairs(DPSSettings["windows"]) do
|
||||||
|
if not _G("DPSMate_"..val["name"]) then
|
||||||
|
local f=CreateFrame("Frame", "DPSMate_"..val["name"], UIParent, "DPSMate_Statusframe")
|
||||||
|
f.Key=k
|
||||||
|
end
|
||||||
|
local frame = _G("DPSMate_"..val["name"])
|
||||||
|
frame.fborder = _G("DPSMate_"..val["name"].."_Border")
|
||||||
|
frame:SetToplevel(true)
|
||||||
|
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total_Name"):SetText(self.L["total"])
|
||||||
|
|
||||||
|
if (val["position"] and val["position"][1]) then
|
||||||
|
frame:ClearAllPoints()
|
||||||
|
frame:SetPoint(val["position"][1], UIParent, val["position"][1], val["position"][2], val["position"][3])
|
||||||
|
end
|
||||||
|
if (val["savsize"] and val["savsize"][1]) then
|
||||||
|
frame:SetWidth(val["savsize"][1])
|
||||||
|
frame:SetHeight(val["savsize"][2])
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Options:ToggleDrewDrop(1, DPSMate.DB:GetOptionsTrue(1, k), frame)
|
||||||
|
DPSMate.Options:ToggleDrewDrop(2, DPSMate.DB:GetOptionsTrue(2, k), frame)
|
||||||
|
|
||||||
|
frame.fborder:SetAlpha(val["borderopacity"] or 0)
|
||||||
|
frame.fborder:SetFrameStrata(DPSMate.Options.stratas[val["borderstrata"] or 1])
|
||||||
|
frame.fborder:SetBackdrop({
|
||||||
|
bgFile = "",
|
||||||
|
edgeFile = DPSMate.Options.bordertextures[val["bordertexture"] or "UI-Tooltip-Border"], tile = true, tileSize = 12, edgeSize = 10,
|
||||||
|
insets = { left = 5, right = 5, top = 3, bottom = 1 }
|
||||||
|
})
|
||||||
|
frame.fborder:SetBackdropBorderColor(val["contentbordercolor"][1], val["contentbordercolor"][2], val["contentbordercolor"][3])
|
||||||
|
|
||||||
|
local head = _G("DPSMate_"..val["name"].."_Head")
|
||||||
|
head.font = _G("DPSMate_"..val["name"].."_Head_Font")
|
||||||
|
head.bg = _G("DPSMate_"..val["name"].."_Head_Background")
|
||||||
|
head.sync = _G("DPSMate_"..val["name"].."_Head_Sync")
|
||||||
|
|
||||||
|
if DPSSettings["sync"] then
|
||||||
|
head.sync:GetNormalTexture():SetVertexColor(0.67,0.83,0.45,1)
|
||||||
|
else
|
||||||
|
head.sync:GetNormalTexture():SetVertexColor(1,0,0,1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if DPSSettings["lock"] then
|
||||||
|
_G("DPSMate_"..val["name"].."_Resize"):Hide()
|
||||||
|
end
|
||||||
|
if not val["titlebar"] then
|
||||||
|
head:Hide()
|
||||||
|
end
|
||||||
|
frame:SetAlpha(val["opacity"])
|
||||||
|
head.font:SetTextColor(val["titlebarfontcolor"][1],val["titlebarfontcolor"][2],val["titlebarfontcolor"][3])
|
||||||
|
head.bg:SetTexture(DPSMate.Options.statusbars[val["titlebartexture"]])
|
||||||
|
head.bg:SetVertexColor(val["titlebarbgcolor"][1], val["titlebarbgcolor"][2], val["titlebarbgcolor"][3])
|
||||||
|
head.bg:SetAlpha(val["titlebaropacity"] or 1)
|
||||||
|
head.font:SetFont(DPSMate.Options.fonts[val["titlebarfont"]], val["titlebarfontsize"], DPSMate.Options.fontflags[val["titlebarfontflag"]])
|
||||||
|
head:SetHeight(val["titlebarheight"])
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Background"):SetTexture(DPSMate.Options.bgtexture[val["contentbgtexture"]])
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Background"):SetVertexColor(val["contentbgcolor"][1], val["contentbgcolor"][2], val["contentbgcolor"][3])
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Background"):SetAlpha(val["bgopacity"] or 1)
|
||||||
|
frame:SetScale(val["scale"])
|
||||||
|
_G("DPSMate_"..val["name"].."_Head_Enable"):SetChecked(DPSSettings["enable"])
|
||||||
|
|
||||||
|
-- Styles // Bars
|
||||||
|
local child = _G("DPSMate_"..val["name"].."_ScrollFrame_Child")
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total"):SetPoint("TOPLEFT", child, "TOPLEFT")
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total"):SetPoint("TOPRIGHT", child, "TOPRIGHT")
|
||||||
|
if DPSSettings["showtotals"] then
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total"):SetHeight(val["barheight"])
|
||||||
|
else
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total"):SetHeight(0.00001)
|
||||||
|
end
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total"):SetStatusBarTexture(DPSMate.Options.statusbars[val["bartexture"]])
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total"):SetStatusBarColor(1,1,1,val["totopacity"] or 1)
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total_BG"):SetTexture(DPSMate.Options.statusbars[val["bartexture"]])
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total_BG"):SetAlpha(val["totopacity"] or 1)
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total_Name"):SetFont(DPSMate.Options.fonts[val["barfont"]], val["barfontsize"], DPSMate.Options.fontflags[val["barfontflag"]])
|
||||||
|
_G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total_Value"):SetFont(DPSMate.Options.fonts[val["barfont"]], val["barfontsize"], DPSMate.Options.fontflags[val["barfontflag"]])
|
||||||
|
for i=1, 40 do
|
||||||
|
local bar = _G("DPSMate_"..val["name"].."_ScrollFrame_Child_StatusBar"..i)
|
||||||
|
bar.name = _G("DPSMate_"..val["name"].."_ScrollFrame_Child_StatusBar"..i.."_Name")
|
||||||
|
bar.value = _G("DPSMate_"..val["name"].."_ScrollFrame_Child_StatusBar"..i.."_Value")
|
||||||
|
bar.icon = _G("DPSMate_"..val["name"].."_ScrollFrame_Child_StatusBar"..i.."_Icon")
|
||||||
|
bar.bg = _G("DPSMate_"..val["name"].."_ScrollFrame_Child_StatusBar"..i.."_BG")
|
||||||
|
|
||||||
|
-- Postition
|
||||||
|
bar:SetPoint("TOPLEFT", child, "TOPLEFT")
|
||||||
|
bar:SetPoint("TOPRIGHT", child, "TOPRIGHT")
|
||||||
|
if i>1 then
|
||||||
|
bar:SetPoint("TOPLEFT", _G("DPSMate_"..val["name"].."_ScrollFrame_Child_StatusBar"..(i-1)), "BOTTOMLEFT", 0, -1*val["barspacing"])
|
||||||
|
else
|
||||||
|
if DPSSettings["showtotals"] then
|
||||||
|
bar:SetPoint("TOPLEFT", _G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total"), "BOTTOMLEFT", 0, -1*val["barspacing"])
|
||||||
|
else
|
||||||
|
bar:SetPoint("TOPLEFT", _G("DPSMate_"..val["name"].."_ScrollFrame_Child_Total"), "BOTTOMLEFT", 0, -1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if val["classicons"] then
|
||||||
|
bar.name:ClearAllPoints()
|
||||||
|
bar.name:SetPoint("TOPLEFT", bar, "TOPLEFT", val["barheight"], 0)
|
||||||
|
bar.name:SetPoint("BOTTOMRIGHT", bar, "BOTTOMRIGHT")
|
||||||
|
bar.icon:SetWidth(val["barheight"])
|
||||||
|
bar.icon:SetHeight(val["barheight"])
|
||||||
|
bar.icon:Show()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Styles
|
||||||
|
bar.name:SetFont(DPSMate.Options.fonts[val["barfont"]], val["barfontsize"], DPSMate.Options.fontflags[val["barfontflag"]])
|
||||||
|
bar.name:SetTextColor(val["barfontcolor"][1],val["barfontcolor"][2],val["barfontcolor"][3])
|
||||||
|
bar.value:SetFont(DPSMate.Options.fonts[val["barfont"]], val["barfontsize"], DPSMate.Options.fontflags[val["barfontflag"]])
|
||||||
|
bar.value:SetTextColor(val["barfontcolor"][1],val["barfontcolor"][2],val["barfontcolor"][3])
|
||||||
|
bar:SetStatusBarTexture(DPSMate.Options.statusbars[val["bartexture"]])
|
||||||
|
bar.bg:SetTexture(DPSMate.Options.statusbars[val["bartexture"]])
|
||||||
|
bar:SetHeight(val["barheight"])
|
||||||
|
if val["barbg"] then
|
||||||
|
bar.bg:SetVertexColor(val["bgbarcolor"][1],val["bgbarcolor"][2],val["bgbarcolor"][3], 0)
|
||||||
|
else
|
||||||
|
bar.bg:SetVertexColor(val["bgbarcolor"][1],val["bgbarcolor"][2],val["bgbarcolor"][3], 0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
DPSMate.Options:SelectRealtime(frame, val["realtime"])
|
||||||
|
|
||||||
|
if (val["hidden"] == true) then
|
||||||
|
frame:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
DPSMate.Options:ToggleTitleBarButtonState()
|
||||||
|
DPSMate.Options:HideWhenSolo()
|
||||||
|
if not DPSSettings["enable"] then
|
||||||
|
self:Disable()
|
||||||
|
else
|
||||||
|
self:Enable()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Report delay button
|
||||||
|
DPSMate_Report_Delay:SetChecked(DPSSettings["reportdelay"])
|
||||||
|
|
||||||
|
DPSMate_MiniMap:SetToplevel(true)
|
||||||
|
DPSMate_PopUp:SetToplevel(true)
|
||||||
|
DPSMate_Vote:SetToplevel(true)
|
||||||
|
DPSMate_Logout:SetToplevel(true)
|
||||||
|
DPSMate_Report:SetToplevel(true)
|
||||||
|
DPSMate_ConfigMenu:SetToplevel(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:ProbZero(val)
|
||||||
|
if (val==0) then
|
||||||
|
return 1;
|
||||||
|
end
|
||||||
|
return val;
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:TMax(t)
|
||||||
|
local max = 0
|
||||||
|
for _,val in pairs(t) do
|
||||||
|
if val>max then
|
||||||
|
max=val
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return max
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:TableLength(t)
|
||||||
|
local count = 0
|
||||||
|
if (t) then
|
||||||
|
count = getn(t)
|
||||||
|
if count<=1 then
|
||||||
|
count = 0
|
||||||
|
for _,_ in pairs(t) do
|
||||||
|
count = count + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return count
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:TContains(t, value)
|
||||||
|
if (t) then
|
||||||
|
for cat, val in pairs(t) do
|
||||||
|
if val == value or cat==value then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetKeyByVal(t, value)
|
||||||
|
for cat, val in pairs(t) do
|
||||||
|
if val == value then
|
||||||
|
return cat
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetKeyByValInTT(t, x, y)
|
||||||
|
for cat, val in pairs(t) do
|
||||||
|
if (type(val) == "table") then
|
||||||
|
if (x==val[y]) then
|
||||||
|
return cat
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:InvertTable(t)
|
||||||
|
local s={}
|
||||||
|
for cat, val in pairs(t) do
|
||||||
|
s[val]=cat
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:CopyTable(t)
|
||||||
|
local s={}
|
||||||
|
for cat, val in pairs(t) do
|
||||||
|
if type(val) == "table" then
|
||||||
|
s[cat] = self:CopyTable(val)
|
||||||
|
else
|
||||||
|
s[cat] = val
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:CopyTableStripInstant(t, depth)
|
||||||
|
local s={}
|
||||||
|
depth = depth or 0
|
||||||
|
for cat, val in pairs(t) do
|
||||||
|
if depth >= 2 and cat == "i" then
|
||||||
|
-- Skip ["i"] instant-damage dictionaries at ability level
|
||||||
|
elseif type(val) == "table" then
|
||||||
|
s[cat] = self:CopyTableStripInstant(val, depth + 1)
|
||||||
|
else
|
||||||
|
s[cat] = val
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:PruneStaleUsers()
|
||||||
|
-- Collect all user IDs referenced in active metric data and history
|
||||||
|
local activeIds = {}
|
||||||
|
local metrics = {DPSMateDamageDone, DPSMateDamageTaken, DPSMateEDD, DPSMateEDT, DPSMateTHealing, DPSMateEHealing, DPSMateOverhealing, DPSMateHealingTaken, DPSMateEHealingTaken, DPSMateOverhealingTaken, DPSMateAbsorbs, DPSMateDispels, DPSMateDeaths, DPSMateInterrupts, DPSMateAurasGained, DPSMateThreat, DPSMateFails, DPSMateCCBreaker}
|
||||||
|
-- Check active data (mode [1] and [2])
|
||||||
|
for _, metric in pairs(metrics) do
|
||||||
|
if metric then
|
||||||
|
for mode = 1, 2 do
|
||||||
|
if metric[mode] then
|
||||||
|
for uid, _ in pairs(metric[mode]) do
|
||||||
|
activeIds[uid] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Check history segments
|
||||||
|
for cat, segments in pairs(DPSMateHistory) do
|
||||||
|
if cat ~= "names" and type(segments) == "table" then
|
||||||
|
for _, segment in pairs(segments) do
|
||||||
|
if type(segment) == "table" then
|
||||||
|
for uid, _ in pairs(segment) do
|
||||||
|
activeIds[uid] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Remove users whose IDs aren't referenced anywhere
|
||||||
|
local removed = 0
|
||||||
|
for name, data in pairs(DPSMateUser) do
|
||||||
|
if data[1] and not activeIds[data[1]] then
|
||||||
|
DPSMateUser[name] = nil
|
||||||
|
removed = removed + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if removed > 0 then
|
||||||
|
self.UserId = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Strip ["i"] sub-tables from all modes of all metrics that use them.
|
||||||
|
-- Covers damage/healing/threat (per-second time buckets) as well as dispels,
|
||||||
|
-- interrupts, and absorbs (event log arrays stored under ["i"]).
|
||||||
|
-- Called on login and on logout to keep SavedVariables compact.
|
||||||
|
--
|
||||||
|
-- A recursive walk is used: wherever ["i"] is a table it is cleared to {}.
|
||||||
|
-- Numbers stored under ["i"] are left untouched.
|
||||||
|
-- Using {} rather than nil keeps combat event writers safe.
|
||||||
|
local function stripInstantRecursive(t)
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if k == "i" and type(v) == "table" then
|
||||||
|
t[k] = {}
|
||||||
|
elseif k ~= "i" and type(v) == "table" then
|
||||||
|
stripInstantRecursive(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:StripInstantFromMode1()
|
||||||
|
local metrics = {DPSMateDamageDone, DPSMateDamageTaken, DPSMateEDD, DPSMateEDT,
|
||||||
|
DPSMateTHealing, DPSMateEHealing, DPSMateOverhealing, DPSMateHealingTaken,
|
||||||
|
DPSMateEHealingTaken, DPSMateOverhealingTaken, DPSMateThreat,
|
||||||
|
DPSMateDispels, DPSMateInterrupts, DPSMateAbsorbs}
|
||||||
|
for _, metric in pairs(metrics) do
|
||||||
|
if metric then
|
||||||
|
if metric[1] then stripInstantRecursive(metric[1]) end
|
||||||
|
if metric[2] then stripInstantRecursive(metric[2]) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Collapse AurasGained timestamp arrays in Mode [1] and [2] into compact uptime totals.
|
||||||
|
-- path[1] (gain times) and path[2] (loss times) grow unboundedly with each buff
|
||||||
|
-- application. The pre-computed total is stored in path[7] so EvalTable can still
|
||||||
|
-- display accurate uptime percentages across sessions.
|
||||||
|
function DPSMate:CollapseAuraTimestamps()
|
||||||
|
if not DPSMateAurasGained then return end
|
||||||
|
for mode = 1, 2 do
|
||||||
|
local modeData = DPSMateAurasGained[mode]
|
||||||
|
if modeData then
|
||||||
|
for uid, abilities in pairs(modeData) do
|
||||||
|
for abilityId, path in pairs(abilities) do
|
||||||
|
if type(path) == "table" and type(path[1]) == "table" then
|
||||||
|
local total = path[7] or 0
|
||||||
|
for i, gainTime in pairs(path[1]) do
|
||||||
|
if path[2] and path[2][i] then
|
||||||
|
total = total + (path[2][i] - gainTime)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
path[7] = total
|
||||||
|
path[1] = {}
|
||||||
|
path[2] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function DPSMate:GetUserById(id)
|
||||||
|
if not self.UserId or not self.UserId[id] then
|
||||||
|
self.UserId = {}
|
||||||
|
for cat, val in DPSMateUser do
|
||||||
|
self.UserId[val[1]] = cat
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self.UserId[id]
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetPetsByOwner(arr)
|
||||||
|
local lookup = {}
|
||||||
|
for cat, _ in pairs(arr) do
|
||||||
|
local name = self:GetUserById(cat)
|
||||||
|
if name and DPSMateUser[name] and DPSMateUser[name][4] and DPSMateUser[name][6] then
|
||||||
|
local oid = DPSMateUser[name][6]
|
||||||
|
if not lookup[oid] then
|
||||||
|
lookup[oid] = {}
|
||||||
|
end
|
||||||
|
table.insert(lookup[oid], cat)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return lookup
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetAbilityById(id)
|
||||||
|
if not self.AbilityId or not self.AbilityId[id] then
|
||||||
|
self.AbilityId = {}
|
||||||
|
for cat, val in DPSMateAbility do
|
||||||
|
self.AbilityId[val[1]] = cat
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self.AbilityId[id]
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetMaxValue(arr, key)
|
||||||
|
local max = 0
|
||||||
|
for _, val in arr do
|
||||||
|
if val[key]>max then
|
||||||
|
max=val[key]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return max
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetMinValue(arr, key)
|
||||||
|
local min
|
||||||
|
for _, val in arr do
|
||||||
|
if not min or val[key]<min then
|
||||||
|
min = val[key]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return min or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:ScaleDown(arr, start)
|
||||||
|
local t = {}
|
||||||
|
for cat, val in arr do
|
||||||
|
t[cat] = {(val[1]-start+1), val[2]}
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:RefreshFonts()
|
||||||
|
if not DPSSettings["windows"][1] then return end
|
||||||
|
if not savedFontSettings then return end
|
||||||
|
local fonts = self.Options.fonts
|
||||||
|
local flags = self.Options.fontflags
|
||||||
|
for k, c in pairs(DPSSettings["windows"]) do
|
||||||
|
local saved = savedFontSettings[k]
|
||||||
|
if saved then
|
||||||
|
-- Restore user's saved font settings into the live table
|
||||||
|
c["barfont"] = saved.barfont
|
||||||
|
c["barfontsize"] = saved.barfontsize
|
||||||
|
c["barfontflag"] = saved.barfontflag
|
||||||
|
c["titlebarfont"] = saved.titlebarfont
|
||||||
|
c["titlebarfontsize"] = saved.titlebarfontsize
|
||||||
|
c["titlebarfontflag"] = saved.titlebarfontflag
|
||||||
|
end
|
||||||
|
local barFont = fonts[c["barfont"]]
|
||||||
|
local barSize = c["barfontsize"]
|
||||||
|
local barFlag = flags[c["barfontflag"]]
|
||||||
|
local titleFont = fonts[c["titlebarfont"]]
|
||||||
|
local titleSize = c["titlebarfontsize"]
|
||||||
|
local titleFlag = flags[c["titlebarfontflag"]]
|
||||||
|
local name = c["name"]
|
||||||
|
_G("DPSMate_"..name.."_Head_Font"):SetFont(titleFont, titleSize, titleFlag)
|
||||||
|
_G("DPSMate_"..name.."_ScrollFrame_Child_Total_Name"):SetFont(barFont, barSize, barFlag)
|
||||||
|
_G("DPSMate_"..name.."_ScrollFrame_Child_Total_Value"):SetFont(barFont, barSize, barFlag)
|
||||||
|
for i=1, 40 do
|
||||||
|
_G("DPSMate_"..name.."_ScrollFrame_Child_StatusBar"..i.."_Name"):SetFont(barFont, barSize, barFlag)
|
||||||
|
_G("DPSMate_"..name.."_ScrollFrame_Child_StatusBar"..i.."_Value"):SetFont(barFont, barSize, barFlag)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
savedFontSettings = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local framePointerCache = {}
|
||||||
|
function DPSMate:InvalidateFrameCache()
|
||||||
|
framePointerCache = {}
|
||||||
|
end
|
||||||
|
function DPSMate:SetStatusBarValue()
|
||||||
|
|
||||||
|
if not DPSSettings["windows"][1] or self.Options.TestMode then return end
|
||||||
|
|
||||||
|
-- Deferred font refresh: wait ~1s after load for skinning addons to finish,
|
||||||
|
-- then re-apply saved font settings once.
|
||||||
|
if fontRefreshAt and GT() >= fontRefreshAt then
|
||||||
|
fontRefreshAt = nil
|
||||||
|
self:RefreshFonts()
|
||||||
|
end
|
||||||
|
local arr, cbt, ecbt, user, val, perc, strt, statusbar, r, g, b, img, len
|
||||||
|
for k,c in pairs(DPSSettings.windows) do
|
||||||
|
arr, cbt, ecbt = self:GetMode(k)
|
||||||
|
user, val, perc, strt = self:GetSettingValues(arr,cbt,k,ecbt)
|
||||||
|
|
||||||
|
-- Caching the global lookups
|
||||||
|
if not framePointerCache[k] then
|
||||||
|
framePointerCache[k] = {}
|
||||||
|
framePointerCache[k][1] = _G("DPSMate_"..c["name"].."_ScrollFrame_Child_Total_Value")
|
||||||
|
framePointerCache[k][2] = _G("DPSMate_"..c["name"].."_Head_Font")
|
||||||
|
framePointerCache[k][3] = _G("DPSMate_"..c["name"].."_ScrollFrame_Child")
|
||||||
|
framePointerCache[k][4] = _G("DPSMate_"..c["name"].."_ScrollFrame_Child_Total")
|
||||||
|
for i=1, 40 do
|
||||||
|
framePointerCache[k][4+i] = {}
|
||||||
|
framePointerCache[k][4+i][1] = _G("DPSMate_"..c["name"].."_ScrollFrame_Child_StatusBar"..i)
|
||||||
|
framePointerCache[k][4+i][2] = _G("DPSMate_"..c["name"].."_ScrollFrame_Child_StatusBar"..i.."_Name")
|
||||||
|
framePointerCache[k][4+i][3] = _G("DPSMate_"..c["name"].."_ScrollFrame_Child_StatusBar"..i.."_Value")
|
||||||
|
framePointerCache[k][4+i][4] = _G("DPSMate_"..c["name"].."_ScrollFrame_Child_StatusBar"..i.."_Icon")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local FPC = framePointerCache[k];
|
||||||
|
|
||||||
|
if DPSSettings["showtotals"] then
|
||||||
|
FPC[1]:SetText(strt[1]..strt[2])
|
||||||
|
end
|
||||||
|
if not c["cbtdisplay"] then
|
||||||
|
FPC[2]:SetText(self.Options.Options[1]["args"][c["CurMode"]].name.." ["..self.Options:FormatTime(cbt).."]")
|
||||||
|
end
|
||||||
|
len = 0
|
||||||
|
for i=1, 40 do
|
||||||
|
statusbar = FPC[4+i][1]
|
||||||
|
if user[i] then
|
||||||
|
r,g,b,img = self:GetClassColor(user[i])
|
||||||
|
statusbar:SetStatusBarColor(r,g,b, 1)
|
||||||
|
|
||||||
|
local displayName = user[i]
|
||||||
|
if not DPSMateSettings["mergepets"] and DPSMateUser[user[i]] and DPSMateUser[user[i]][4] then
|
||||||
|
local ownerID = DPSMateUser[user[i]][6]
|
||||||
|
if ownerID then
|
||||||
|
local ownerName = self:GetUserById(ownerID)
|
||||||
|
if ownerName then displayName = user[i].." ("..ownerName..")" end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if c["ranks"] then
|
||||||
|
FPC[4+i][2]:SetText(i..". "..displayName)
|
||||||
|
else
|
||||||
|
FPC[4+i][2]:SetText(displayName)
|
||||||
|
end
|
||||||
|
FPC[4+i][3]:SetText(val[i])
|
||||||
|
FPC[4+i][4]:SetTexture("Interface\\AddOns\\DPSMate\\images\\class\\"..img)
|
||||||
|
statusbar:SetValue(perc[i])
|
||||||
|
|
||||||
|
statusbar.user = user[i]
|
||||||
|
statusbar:Show()
|
||||||
|
len = len + 1
|
||||||
|
else
|
||||||
|
statusbar:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
FPC[3]:SetHeight((len+1)*(c["barheight"]+c["barspacing"]))
|
||||||
|
FPC[4]:Show()
|
||||||
|
if len == 0 then
|
||||||
|
FPC[4]:Hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:strrev(str)
|
||||||
|
local res, len = {}, strlen(str)
|
||||||
|
for i=1, len do
|
||||||
|
res[i] = strsub(str, len-i+1, len-i+1)
|
||||||
|
end
|
||||||
|
return tconcat(res);
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:Commas(n,k)
|
||||||
|
if DPSSettings["windows"][k]["numberformat"] == 3 then
|
||||||
|
n = strformat("%.0f", n)
|
||||||
|
for left, num, right in strgfind(n, '([^%d]*%d)(%d+)') do
|
||||||
|
return left and left..self:strrev(strgsub(self:strrev(num), '(%d%d%d)','%1,'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return n;
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:FormatNumbers(dmg,total,sort,k)
|
||||||
|
local oldd, oldt, olds = dmg, total, sort
|
||||||
|
if DPSSettings["windows"][k]["numberformat"] == 2 then
|
||||||
|
if dmg>10000 then
|
||||||
|
dmg = strformat("%.0f", (dmg/1000))
|
||||||
|
end
|
||||||
|
if total>10000 then
|
||||||
|
total = strformat("%.0f", (total/1000))
|
||||||
|
end
|
||||||
|
if sort>10000 then
|
||||||
|
sort = strformat("%.0f", (sort/1000))
|
||||||
|
end
|
||||||
|
elseif DPSSettings["windows"][k]["numberformat"] == 4 then
|
||||||
|
if dmg>10000 then
|
||||||
|
dmg = strformat("%.1f", (dmg/1000))
|
||||||
|
end
|
||||||
|
if total>10000 then
|
||||||
|
total = strformat("%.1f", (total/1000))
|
||||||
|
end
|
||||||
|
if sort>10000 then
|
||||||
|
sort = strformat("%.1f", (sort/1000))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return dmg, total, sort, oldd, oldt, olds
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:ApplyFilter(key, name)
|
||||||
|
if not name or not DPSMateUser[name] then return false end
|
||||||
|
if not key then return true end
|
||||||
|
local class = DPSMateUser[name][2] or "warrior"
|
||||||
|
local path = DPSSettings["windows"][key]
|
||||||
|
if path["grouponly"] then
|
||||||
|
if not DPSMate.Parser.TargetParty[name] and next(DPSMate.Parser.TargetParty) ~= nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if path["filterpeople"] and path["filterpeople"] ~= "" then
|
||||||
|
-- Certain people
|
||||||
|
t = {}
|
||||||
|
strgsub(path["filterpeople"]..",", "(.-),", func)
|
||||||
|
for cat, val in pairs(t) do
|
||||||
|
if name == val then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- classes
|
||||||
|
for cat, val in pairs(path["filterclasses"]) do
|
||||||
|
if not val then
|
||||||
|
if cat == class then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetSettingValues(arr, cbt, k, ecbt)
|
||||||
|
k = k or 1
|
||||||
|
return self.RegistredModules[DPSSettings["windows"][k]["CurMode"]]:GetSettingValues(arr, cbt, k, ecbt)
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:EvalTable(k)
|
||||||
|
k = k or 1
|
||||||
|
return self.RegistredModules[DPSSettings["windows"][k]["CurMode"]]:EvalTable(DPSMateUser[UnitName("player")], k)
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetClassColor(class)
|
||||||
|
if not class then
|
||||||
|
class = "warrior"
|
||||||
|
end
|
||||||
|
if DPSMateUser[class] then
|
||||||
|
class = DPSMateUser[class][2] or "warrior"
|
||||||
|
end
|
||||||
|
if classcolor[class] then
|
||||||
|
return classcolor[class].r, classcolor[class].g, classcolor[class].b, class
|
||||||
|
end
|
||||||
|
return classcolor["warrior"].r, classcolor["warrior"].g, classcolor["warrior"].b, "warrior"
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetMode(k)
|
||||||
|
k = k or 1
|
||||||
|
local Handler = DPSMate.RegistredModules[DPSSettings["windows"][k]["CurMode"]]
|
||||||
|
local opts = DPSSettings["windows"][k]["options"][2]
|
||||||
|
-- Check in deterministic order: total first, then currentfight, then segments
|
||||||
|
if opts["total"] then
|
||||||
|
return Handler.DB[1], DPSMateCombatTime["total"], DPSMateCombatTime["effective"][1]
|
||||||
|
end
|
||||||
|
if opts["currentfight"] then
|
||||||
|
return Handler.DB[2], DPSMateCombatTime["current"], DPSMateCombatTime["effective"][2]
|
||||||
|
end
|
||||||
|
local num
|
||||||
|
for cat, val in pairs(opts) do
|
||||||
|
if val and strfind(cat, "segment") then
|
||||||
|
num = tonumber(strsub(cat, 8))
|
||||||
|
if (Handler.Hist) and DPSHist[Handler.Hist] and self:TableLength(DPSHist[Handler.Hist]) >= num then
|
||||||
|
return DPSHist[Handler.Hist][num], DPSMateCombatTime["segments"][num][1], DPSMateCombatTime["segments"][num][2]
|
||||||
|
else
|
||||||
|
return {}, 0, 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Fallback: default to total
|
||||||
|
return Handler.DB[1], DPSMateCombatTime["total"], DPSMateCombatTime["effective"][1]
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetModeByArr(arr, k, Hist)
|
||||||
|
local opts = DPSSettings["windows"][k]["options"][2]
|
||||||
|
-- Check in deterministic order: total first, then currentfight, then segments
|
||||||
|
if opts["total"] then
|
||||||
|
return arr[1], DPSMateCombatTime["total"], DPSMateCombatTime["effective"][1]
|
||||||
|
end
|
||||||
|
if opts["currentfight"] then
|
||||||
|
return arr[2], DPSMateCombatTime["current"], DPSMateCombatTime["effective"][2]
|
||||||
|
end
|
||||||
|
local num
|
||||||
|
for cat, val in pairs(opts) do
|
||||||
|
if val and strfind(cat, "segment") then
|
||||||
|
num = tonumber(strsub(cat, 8))
|
||||||
|
if (Hist or arr.Hist) and DPSHist[Hist or arr.Hist] and self:TableLength(DPSHist[Hist or arr.Hist]) >= num then
|
||||||
|
return DPSHist[Hist or arr.Hist][num], DPSMateCombatTime["segments"][num][1], DPSMateCombatTime["segments"][num][2]
|
||||||
|
else
|
||||||
|
return {}, 0, 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Fallback: default to total
|
||||||
|
return arr[1], DPSMateCombatTime["total"], DPSMateCombatTime["effective"][1]
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:GetModeName(k)
|
||||||
|
k = k or 1
|
||||||
|
local opts = DPSSettings["windows"][k]["options"][2]
|
||||||
|
if opts["total"] then return "Total" end
|
||||||
|
if opts["currentfight"] then return "Current fight" end
|
||||||
|
local num
|
||||||
|
for cat, val in pairs(opts) do
|
||||||
|
if val and strfind(cat, "segment") then
|
||||||
|
num = tonumber(strsub(cat, 8))
|
||||||
|
return DPSHist["names"][num]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return "Total"
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:Disable()
|
||||||
|
if self.Registered then
|
||||||
|
self.Sync:UnregisterEvent("CHAT_MSG_ADDON")
|
||||||
|
for _, event in pairs(self.Events) do
|
||||||
|
self.Parser:UnregisterEvent(event)
|
||||||
|
end
|
||||||
|
self.Registered = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:Enable()
|
||||||
|
if not self.Registered then
|
||||||
|
self.Sync:RegisterEvent("CHAT_MSG_ADDON")
|
||||||
|
for _, val in pairs(self.RegistredModules) do
|
||||||
|
if val.Events then
|
||||||
|
for _, event in pairs(val.Events) do
|
||||||
|
self.Parser:RegisterEvent(event)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.Registered = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:Broadcast(type, who, what, with, value, failtype)
|
||||||
|
if DPSSettings["broadcasting"] then
|
||||||
|
if IsRaidLeader() or IsRaidOfficer() then
|
||||||
|
local ch = "RAID"
|
||||||
|
if DPSSettings["bcrw"] then
|
||||||
|
ch = "RAID_WARNING"
|
||||||
|
end
|
||||||
|
if DPSSettings["bccd"] and type == 1 then
|
||||||
|
SendChatMessage("BULK", "DPSMateChat", self.L["bccdo"](who, what), ch, nil, nil)
|
||||||
|
return
|
||||||
|
elseif DPSSettings["bccd"] and type == 6 then
|
||||||
|
SendChatMessage("BULK", "DPSMateChat", self.L["bccdt"](who, what), ch, nil, nil)
|
||||||
|
return
|
||||||
|
elseif DPSSettings["bcress"] and type == 2 then
|
||||||
|
SendChatMessage("BULK", "DPSMateChat", self.L["bcress"](who, what), ch, nil, nil)
|
||||||
|
return
|
||||||
|
elseif DPSSettings["bckb"] and type == 4 then
|
||||||
|
SendChatMessage("BULK", "DPSMateChat", self.L["bckb"](who, what, with, value), ch, nil, nil)
|
||||||
|
return
|
||||||
|
elseif DPSSettings["bcfail"] and type == 3 then
|
||||||
|
if failtype == 1 then
|
||||||
|
SendChatMessage("BULK", "DPSMateChat", self.L["bcfailo"](what, who, value, with), ch, nil, nil)
|
||||||
|
elseif failtype == 3 then
|
||||||
|
SendChatMessage("BULK", "DPSMateChat", self.L["bcfailt"](who, with), ch, nil, nil)
|
||||||
|
else
|
||||||
|
SendChatMessage("BULK", "DPSMateChat", self.L["bcfailth"](who, value, with, what), ch, nil, nil)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:SendMessage(msg)
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage("|cFFFF8080"..self.L["name"].."|r: "..msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate:Register(prefix, table, name)
|
||||||
|
self.ModuleNames[name] = prefix
|
||||||
|
self.RegistredModules[prefix] = table
|
||||||
|
end
|
||||||
@@ -0,0 +1,259 @@
|
|||||||
|
## Interface: 11200
|
||||||
|
## Title: DPSMate |cFFFF8080-Enhanced-|r
|
||||||
|
## Notes: DPSMate is an advanced combat analyzation tool, providing helpful graphs and statistics to evaluate the fight.
|
||||||
|
## Notes-deDE: DPSMate ist ein Analysewerkzeug, das hilfreiche Graphen und Statistiken bereitstellt, um den Kampf zu evaluieren.
|
||||||
|
## Notes-ruRU: DPSMate это продвинутый инструмент анализа боя, предоставляет полезные графики и статистики для оценки боя.
|
||||||
|
## Author: Shino <Synced> - Kronos, Torio
|
||||||
|
## OptionalDeps: KLHThreatMeter
|
||||||
|
## SavedVariables: DPSMateSettings
|
||||||
|
|
||||||
|
libs\AceLibrary\AceLibrary.lua
|
||||||
|
libs\Dewdrop-2.0\Dewdrop-2.0.lua
|
||||||
|
libs\GraphLib\Graph-1.0\Graph-1.0.lua
|
||||||
|
libs\ChatThrottleLib.lua
|
||||||
|
enUS\Babble-Spell-2.3.lua
|
||||||
|
enUS\Babble-Boss-2.3.lua
|
||||||
|
enUS\NPCDB-1.0.lua
|
||||||
|
|
||||||
|
DPSMate.lua
|
||||||
|
DPSMate_CombatPatterns.lua
|
||||||
|
|
||||||
|
enUS\enUS.lua
|
||||||
|
|
||||||
|
DPSMate_Parser.lua
|
||||||
|
enUS\DPSMate_ParserENUS.lua
|
||||||
|
|
||||||
|
locales\Babble-Spell-2.3_deDE.lua
|
||||||
|
locales\Babble-Boss-2.3_deDE.lua
|
||||||
|
locales\NPCDB-1.0_deDE.lua
|
||||||
|
locales\deDE.lua
|
||||||
|
locales\DPSMate_ParserDEDE.lua
|
||||||
|
|
||||||
|
locales\Babble-Spell-2.3_frFR.lua
|
||||||
|
locales\Babble-Boss-2.3_frFR.lua
|
||||||
|
locales\NPCDB-1.0_frFR.lua
|
||||||
|
locales\frFR.lua
|
||||||
|
locales\DPSMate_ParserFRFR.lua
|
||||||
|
|
||||||
|
locales\Babble-Spell-2.3_koKR.lua
|
||||||
|
locales\Babble-Boss-2.3_koKR.lua
|
||||||
|
locales\NPCDB-1.0_koKR.lua
|
||||||
|
locales\koKR.lua
|
||||||
|
locales\DPSMate_ParserKRKR.lua
|
||||||
|
|
||||||
|
locales\Babble-Spell-2.3_ruRU.lua
|
||||||
|
locales\Babble-Boss-2.3_ruRU.lua
|
||||||
|
locales\NPCDB-1.0_ruRU.lua
|
||||||
|
locales\ruRU.lua
|
||||||
|
locales\DPSMate_ParserRURU.lua
|
||||||
|
|
||||||
|
locales\Babble-Spell-2.3_zhCN.lua
|
||||||
|
locales\Babble-Boss-2.3_zhCN.lua
|
||||||
|
locales\NPCDB-1.0_zhCN.lua
|
||||||
|
locales\zhCN.lua
|
||||||
|
locales\DPSMate_ParserZHCN.lua
|
||||||
|
|
||||||
|
DPSMate_Options.lua
|
||||||
|
DPSMate_Sync.lua
|
||||||
|
DPSMate_DataBuilder.lua
|
||||||
|
|
||||||
|
Damage\DPSMate_DPS.lua
|
||||||
|
Damage\DPSMate_Damage.lua
|
||||||
|
Damage\DPSMate_Details_Damage.lua
|
||||||
|
Damage\DPSMate_Details_Damage.xml
|
||||||
|
Damage\DPSMate_Details_DamageTotal.lua
|
||||||
|
Damage\DPSMate_Details_DamageTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Absorbs.lua
|
||||||
|
modules\DPSMate_Details_Absorbs.lua
|
||||||
|
modules\DPSMate_Details_Absorbs.xml
|
||||||
|
modules\DPSMate_Details_AbsorbsTotal.lua
|
||||||
|
modules\DPSMate_Details_AbsorbsTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_AbsorbsTaken.lua
|
||||||
|
modules\DPSMate_Details_AbsorbsTaken.lua
|
||||||
|
modules\DPSMate_Details_AbsorbsTaken.xml
|
||||||
|
modules\DPSMate_Details_AbsorbsTakenTotal.lua
|
||||||
|
modules\DPSMate_Details_AbsorbsTakenTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Activity.lua
|
||||||
|
|
||||||
|
modules\DPSMate_AurasGained.lua
|
||||||
|
modules\DPSMate_AurasLost.lua
|
||||||
|
modules\DPSMate_AuraUptimers.lua
|
||||||
|
modules\DPSMate_Details_Auras.lua
|
||||||
|
modules\DPSMate_Details_Auras.xml
|
||||||
|
modules\DPSMate_Details_AurasTotal.lua
|
||||||
|
modules\DPSMate_Details_AurasTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Casts.lua
|
||||||
|
modules\DPSMate_Details_Casts.lua
|
||||||
|
modules\DPSMate_Details_Casts.xml
|
||||||
|
modules\DPSMate_Details_CastsTotal.lua
|
||||||
|
modules\DPSMate_Details_CastsTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_CCBreaker.lua
|
||||||
|
modules\DPSMate_Details_CCBreaker.lua
|
||||||
|
modules\DPSMate_Details_CCBreaker.xml
|
||||||
|
modules\DPSMate_Details_CCBreakerTotal.lua
|
||||||
|
modules\DPSMate_Details_CCBreakerTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_CureDisease.lua
|
||||||
|
modules\DPSMate_CureDiseaseReceived.lua
|
||||||
|
modules\DPSMate_Details_CureDisease.lua
|
||||||
|
modules\DPSMate_Details_CureDisease.xml
|
||||||
|
modules\DPSMate_Details_CureDiseaseReceived.lua
|
||||||
|
modules\DPSMate_Details_CureDiseaseReceived.xml
|
||||||
|
modules\DPSMate_Details_CureDiseaseTotal.lua
|
||||||
|
modules\DPSMate_Details_CureDiseaseTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_CurePoison.lua
|
||||||
|
modules\DPSMate_CurePoisonReceived.lua
|
||||||
|
modules\DPSMate_Details_CurePoison.lua
|
||||||
|
modules\DPSMate_Details_CurePoison.xml
|
||||||
|
modules\DPSMate_Details_CurePoisonReceived.lua
|
||||||
|
modules\DPSMate_Details_CurePoisonReceived.xml
|
||||||
|
modules\DPSMate_Details_CurePoisonTotal.lua
|
||||||
|
modules\DPSMate_Details_CurePoisonTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_DamageTaken.lua
|
||||||
|
modules\DPSMate_DTPS.lua
|
||||||
|
modules\DPSMate_Details_DamageTaken.lua
|
||||||
|
modules\DPSMate_Details_DamageTaken.xml
|
||||||
|
modules\DPSMate_Details_DamageTakenTotal.lua
|
||||||
|
modules\DPSMate_Details_DamageTakenTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Deaths.lua
|
||||||
|
modules\DPSMate_Details_Deaths.lua
|
||||||
|
modules\DPSMate_Details_Deaths.xml
|
||||||
|
modules\DPSMate_Details_DeathsTotal.lua
|
||||||
|
modules\DPSMate_Details_DeathsTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Debug.lua
|
||||||
|
|
||||||
|
modules\DPSMate_Decurses.lua
|
||||||
|
modules\DPSMate_DecursesReceived.lua
|
||||||
|
modules\DPSMate_Details_Decurses.lua
|
||||||
|
modules\DPSMate_Details_Decurses.xml
|
||||||
|
modules\DPSMate_Details_DecursesReceived.lua
|
||||||
|
modules\DPSMate_Details_DecursesReceived.xml
|
||||||
|
modules\DPSMate_Details_DecursesTotal.lua
|
||||||
|
modules\DPSMate_Details_DecursesTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Dispels.lua
|
||||||
|
modules\DPSMate_DispelsReceived.lua
|
||||||
|
modules\DPSMate_Details_Dispels.lua
|
||||||
|
modules\DPSMate_Details_Dispels.xml
|
||||||
|
modules\DPSMate_Details_DispelsReceived.lua
|
||||||
|
modules\DPSMate_Details_DispelsReceived.xml
|
||||||
|
modules\DPSMate_Details_DispelsTotal.lua
|
||||||
|
modules\DPSMate_Details_DispelsTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_EDD.lua
|
||||||
|
modules\DPSMate_Details_EDD.lua
|
||||||
|
modules\DPSMate_Details_EDD.xml
|
||||||
|
modules\DPSMate_Details_EDDTotal.lua
|
||||||
|
modules\DPSMate_Details_EDDTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_EDT.lua
|
||||||
|
modules\DPSMate_Details_EDT.lua
|
||||||
|
modules\DPSMate_Details_EDT.xml
|
||||||
|
modules\DPSMate_Details_EDTTotal.lua
|
||||||
|
modules\DPSMate_Details_EDTTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_EffectiveHealing.lua
|
||||||
|
modules\DPSMate_EffectiveHPS.lua
|
||||||
|
modules\DPSMate_Details_EHealing.lua
|
||||||
|
modules\DPSMate_Details_EHealing.xml
|
||||||
|
modules\DPSMate_Details_EHealingTotal.lua
|
||||||
|
modules\DPSMate_Details_EHealingTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_EffectiveHealingTaken.lua
|
||||||
|
modules\DPSMate_Details_EHealingTaken.lua
|
||||||
|
modules\DPSMate_Details_EHealingTaken.xml
|
||||||
|
modules\DPSMate_Details_EHealingTakenTotal.lua
|
||||||
|
modules\DPSMate_Details_EHealingTakenTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Fails.lua
|
||||||
|
modules\DPSMate_Details_Fails.lua
|
||||||
|
modules\DPSMate_Details_Fails.xml
|
||||||
|
modules\DPSMate_Details_FailsTotal.lua
|
||||||
|
modules\DPSMate_Details_FailsTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_FriendlyFire.lua
|
||||||
|
modules\DPSMate_Details_FriendlyFire.lua
|
||||||
|
modules\DPSMate_Details_FriendlyFire.xml
|
||||||
|
modules\DPSMate_Details_FriendlyFireTotal.lua
|
||||||
|
modules\DPSMate_Details_FriendlyFireTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_FriendlyFireTaken.lua
|
||||||
|
modules\DPSMate_Details_FriendlyFireTaken.lua
|
||||||
|
modules\DPSMate_Details_FriendlyFireTaken.xml
|
||||||
|
modules\DPSMate_Details_FriendlyFireTakenTotal.lua
|
||||||
|
modules\DPSMate_Details_FriendlyFireTakenTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Healing.lua
|
||||||
|
modules\DPSMate_HPS.lua
|
||||||
|
modules\DPSMate_Details_Healing.lua
|
||||||
|
modules\DPSMate_Details_Healing.xml
|
||||||
|
modules\DPSMate_Details_HealingTotal.lua
|
||||||
|
modules\DPSMate_Details_HealingTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_HealingAndAbsorbs.lua
|
||||||
|
modules\DPSMate_Details_HealingAndAbsorbs.lua
|
||||||
|
modules\DPSMate_Details_HealingAndAbsorbs.xml
|
||||||
|
modules\DPSMate_Details_HealingAndAbsorbsTotal.lua
|
||||||
|
modules\DPSMate_Details_HealingAndAbsorbsTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_HealingTaken.lua
|
||||||
|
modules\DPSMate_Details_HealingTaken.lua
|
||||||
|
modules\DPSMate_Details_HealingTaken.xml
|
||||||
|
modules\DPSMate_Details_HealingTakenTotal.lua
|
||||||
|
modules\DPSMate_Details_HealingTakenTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Interrupts.lua
|
||||||
|
modules\DPSMate_Details_Interrupts.lua
|
||||||
|
modules\DPSMate_Details_Interrupts.xml
|
||||||
|
modules\DPSMate_Details_InterruptsTotal.lua
|
||||||
|
modules\DPSMate_Details_InterruptsTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_LiftMagic.lua
|
||||||
|
modules\DPSMate_LiftMagicReceived.lua
|
||||||
|
modules\DPSMate_Details_LiftMagic.lua
|
||||||
|
modules\DPSMate_Details_LiftMagic.xml
|
||||||
|
modules\DPSMate_Details_LiftMagicReceived.lua
|
||||||
|
modules\DPSMate_Details_LiftMagicReceived.xml
|
||||||
|
modules\DPSMate_Details_LiftMagicTotal.lua
|
||||||
|
modules\DPSMate_Details_LiftMagicTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_OHealingTaken.lua
|
||||||
|
modules\DPSMate_Details_OHealingTaken.lua
|
||||||
|
modules\DPSMate_Details_OHealingTaken.xml
|
||||||
|
modules\DPSMate_Details_OverhealingTakenTotal.lua
|
||||||
|
modules\DPSMate_Details_OverhealingTakenTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Overhealing.lua
|
||||||
|
modules\DPSMate_OHPS.lua
|
||||||
|
modules\DPSMate_Details_Overhealing.lua
|
||||||
|
modules\DPSMate_Details_Overhealing.xml
|
||||||
|
modules\DPSMate_Details_OverhealingTotal.lua
|
||||||
|
modules\DPSMate_Details_OverhealingTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Procs.lua
|
||||||
|
modules\DPSMate_Details_Procs.lua
|
||||||
|
modules\DPSMate_Details_Procs.xml
|
||||||
|
modules\DPSMate_Details_ProcsTotal.lua
|
||||||
|
modules\DPSMate_Details_ProcsTotal.xml
|
||||||
|
|
||||||
|
modules\DPSMate_Threat.lua
|
||||||
|
modules\DPSMate_TPS.lua
|
||||||
|
modules\DPSMate_Details_Threat.lua
|
||||||
|
modules\DPSMate_Details_Threat.xml
|
||||||
|
modules\DPSMate_Details_ThreatTotal.lua
|
||||||
|
modules\DPSMate_Details_ThreatTotal.xml
|
||||||
|
|
||||||
|
DPSMate_Frame.xml
|
||||||
|
DPSMate_Options.xml
|
||||||
|
Bindings.xml
|
||||||
|
|
||||||
|
DPSMate_CLEUAdapter.lua
|
||||||
@@ -0,0 +1,588 @@
|
|||||||
|
-- DPSMate CLEU Adapter
|
||||||
|
-- Replaces the string-parsing CHAT_MSG_* event system with structured COMBAT_LOG_EVENT
|
||||||
|
-- data from the DPSLog module. Registers for COMBAT_LOG_EVENT and calls DPSMate.DB
|
||||||
|
-- functions directly with extracted values.
|
||||||
|
--
|
||||||
|
-- Toggle: /dpscleu (switches between CLEU adapter and original string parser)
|
||||||
|
-- Requires: DPSLog module (provides COMBAT_LOG_EVENT + GetSpellInfo)
|
||||||
|
|
||||||
|
if not DPSMate or not DPSMate.DB then return end
|
||||||
|
|
||||||
|
local DB = DPSMate.DB
|
||||||
|
local Parser = DPSMate.Parser
|
||||||
|
local GT = GetTime
|
||||||
|
local AAttack = DPSMate.L and DPSMate.L["autoattack"] or "Attack"
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Chat event list (original parser registers these)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
local chatEvents = {
|
||||||
|
"CHAT_MSG_COMBAT_PET_HITS", "CHAT_MSG_COMBAT_PET_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_PET_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_SELF_HITS", "CHAT_MSG_COMBAT_SELF_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_PARTY_HITS", "CHAT_MSG_SPELL_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_PARTY_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_SELF_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_PARTY_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF",
|
||||||
|
"CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS",
|
||||||
|
"CHAT_MSG_SPELL_BREAK_AURA",
|
||||||
|
"CHAT_MSG_SPELL_AURA_GONE_SELF",
|
||||||
|
"CHAT_MSG_SPELL_AURA_GONE_OTHER",
|
||||||
|
"CHAT_MSG_SPELL_AURA_GONE_PARTY",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLY_DEATH",
|
||||||
|
"CHAT_MSG_COMBAT_HOSTILE_DEATH",
|
||||||
|
}
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Toggle state
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
local cleuActive = false
|
||||||
|
local cleuFrame = CreateFrame("Frame")
|
||||||
|
|
||||||
|
local function enableCLEU()
|
||||||
|
-- Disable string parser
|
||||||
|
for _, ev in ipairs(chatEvents) do
|
||||||
|
Parser:UnregisterEvent(ev)
|
||||||
|
end
|
||||||
|
-- Enable CLEU
|
||||||
|
cleuFrame:RegisterEvent("COMBAT_LOG_EVENT")
|
||||||
|
cleuActive = true
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00DPSMate CLEU Adapter|r: |cff00ff00ON|r (structured events)")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function enableOriginal()
|
||||||
|
-- Disable CLEU
|
||||||
|
cleuFrame:UnregisterEvent("COMBAT_LOG_EVENT")
|
||||||
|
-- Re-enable string parser
|
||||||
|
for _, ev in ipairs(chatEvents) do
|
||||||
|
Parser:RegisterEvent(ev)
|
||||||
|
end
|
||||||
|
cleuActive = false
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00DPSMate CLEU Adapter|r: |cffff4444OFF|r (string parser)")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function toggle()
|
||||||
|
if cleuActive then
|
||||||
|
enableOriginal()
|
||||||
|
else
|
||||||
|
enableCLEU()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SLASH_DPSCLEU1 = "/dpscleu"
|
||||||
|
SlashCmdList["DPSCLEU"] = function(msg)
|
||||||
|
if msg == "on" then
|
||||||
|
if not cleuActive then enableCLEU() end
|
||||||
|
elseif msg == "off" then
|
||||||
|
if cleuActive then enableOriginal() end
|
||||||
|
elseif msg == "status" then
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00DPSMate CLEU Adapter|r: " .. (cleuActive and "|cff00ff00ON|r" or "|cffff4444OFF|r"))
|
||||||
|
else
|
||||||
|
toggle()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Helper
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
local function isGroupMember(name)
|
||||||
|
if not name or name == "" then return false end
|
||||||
|
if name == UnitName("player") then return true end
|
||||||
|
for i = 1, GetNumRaidMembers() do
|
||||||
|
if name == UnitName("raid" .. i) then return true end
|
||||||
|
end
|
||||||
|
for i = 1, GetNumPartyMembers() do
|
||||||
|
if name == UnitName("party" .. i) then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- CLEU event handler
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
cleuFrame:SetScript("OnEvent", function()
|
||||||
|
local sub = arg1
|
||||||
|
if not sub then return end
|
||||||
|
|
||||||
|
local srcGUID = arg2
|
||||||
|
local srcName = arg3
|
||||||
|
local dstGUID = arg4
|
||||||
|
local dstName = arg5
|
||||||
|
|
||||||
|
if not srcName or srcName == "" then srcName = "Unknown" end
|
||||||
|
if not dstName or dstName == "" then dstName = "Unknown" end
|
||||||
|
|
||||||
|
-- ========================================================================
|
||||||
|
-- DAMAGE events
|
||||||
|
-- ========================================================================
|
||||||
|
|
||||||
|
if sub == "SWING_DAMAGE" then
|
||||||
|
local amount = arg6 or 0
|
||||||
|
local critical = arg12 == 1 and 1 or 0
|
||||||
|
local glancing = arg13 == 1 and 1 or 0
|
||||||
|
local crushing = arg14 == 1 and 1 or 0
|
||||||
|
local hit = (critical == 0 and glancing == 0 and crushing == 0) and 1 or 0
|
||||||
|
|
||||||
|
DB:DamageDone(srcName, AAttack, hit, critical, 0, 0, 0, 0, amount, glancing, 0)
|
||||||
|
DB:DamageTaken(dstName, AAttack, hit, critical, 0, 0, 0, 0, amount, srcName, crushing, 0)
|
||||||
|
DB:EnemyDamage(1, DPSMateEDT, dstName, AAttack, hit, critical, 0, 0, 0, 0, amount, srcName, 0, crushing)
|
||||||
|
DB:EnemyDamage(2, DPSMateEDD, srcName, AAttack, hit, critical, 0, 0, 0, 0, amount, dstName, 0, 0)
|
||||||
|
DB:DeathHistory(dstName, srcName, AAttack, amount, hit, critical, "hit", crushing)
|
||||||
|
|
||||||
|
elseif sub == "SWING_MISSED" then
|
||||||
|
local missType = arg6
|
||||||
|
local miss = (missType == "MISS") and 1 or 0
|
||||||
|
local parry = (missType == "PARRY") and 1 or 0
|
||||||
|
local dodge = (missType == "DODGE") and 1 or 0
|
||||||
|
local resist = (missType == "RESIST" or missType == "IMMUNE") and 1 or 0
|
||||||
|
local block = (missType == "BLOCK") and 1 or 0
|
||||||
|
local absorb = (missType == "ABSORB") and 1 or 0
|
||||||
|
|
||||||
|
DB:DamageDone(srcName, AAttack, 0, 0, miss + absorb, parry, dodge, resist, 0, 0, block)
|
||||||
|
DB:DamageTaken(dstName, AAttack, 0, 0, miss + absorb, parry, dodge, resist, 0, srcName, 0, block)
|
||||||
|
|
||||||
|
elseif sub == "SPELL_DAMAGE" or sub == "RANGE_DAMAGE" or sub == "SPELL_PERIODIC_DAMAGE"
|
||||||
|
or sub == "DAMAGE_SHIELD" or sub == "DAMAGE_SPLIT" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local amount = arg9 or 0
|
||||||
|
local school = arg11
|
||||||
|
local critical = arg15 == 1 and 1 or 0
|
||||||
|
local glancing = arg16 == 1 and 1 or 0
|
||||||
|
local crushing = arg17 == 1 and 1 or 0
|
||||||
|
local hit = (critical == 0 and glancing == 0 and crushing == 0) and 1 or 0
|
||||||
|
|
||||||
|
DB:DamageDone(srcName, spellName, hit, critical, 0, 0, 0, 0, amount, glancing, 0)
|
||||||
|
DB:DamageTaken(dstName, spellName, hit, critical, 0, 0, 0, 0, amount, srcName, crushing, 0)
|
||||||
|
DB:EnemyDamage(1, DPSMateEDT, dstName, spellName, hit, critical, 0, 0, 0, 0, amount, srcName, 0, crushing)
|
||||||
|
DB:EnemyDamage(2, DPSMateEDD, srcName, spellName, hit, critical, 0, 0, 0, 0, amount, dstName, 0, 0)
|
||||||
|
DB:DeathHistory(dstName, srcName, spellName, amount, hit, critical, "hit", crushing)
|
||||||
|
if school then DB:AddSpellSchool(spellName, school) end
|
||||||
|
|
||||||
|
elseif sub == "SPELL_MISSED" or sub == "RANGE_MISSED"
|
||||||
|
or sub == "SPELL_PERIODIC_MISSED" or sub == "DAMAGE_SHIELD_MISSED" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local missType = arg9
|
||||||
|
local miss = (missType == "MISS") and 1 or 0
|
||||||
|
local parry = (missType == "PARRY") and 1 or 0
|
||||||
|
local dodge = (missType == "DODGE") and 1 or 0
|
||||||
|
local resist = (missType == "RESIST" or missType == "IMMUNE") and 1 or 0
|
||||||
|
local block = (missType == "BLOCK") and 1 or 0
|
||||||
|
local absorb = (missType == "ABSORB") and 1 or 0
|
||||||
|
|
||||||
|
DB:DamageDone(srcName, spellName, 0, 0, miss + absorb, parry, dodge, resist, 0, 0, block)
|
||||||
|
DB:DamageTaken(dstName, spellName, 0, 0, miss + absorb, parry, dodge, resist, 0, srcName, 0, block)
|
||||||
|
|
||||||
|
elseif sub == "ENVIRONMENTAL_DAMAGE" then
|
||||||
|
local envType = arg6
|
||||||
|
local amount = arg7 or 0
|
||||||
|
DB:DamageTaken(dstName, envType or "Environment", 1, 0, 0, 0, 0, 0, amount, envType or "Environment", 0, 0)
|
||||||
|
DB:DeathHistory(dstName, envType or "Environment", envType or "Environment", amount, 1, 0, "hit", 0)
|
||||||
|
|
||||||
|
-- ========================================================================
|
||||||
|
-- HEAL events
|
||||||
|
-- ========================================================================
|
||||||
|
|
||||||
|
elseif sub == "SPELL_HEAL" or sub == "SPELL_PERIODIC_HEAL" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local amount = arg9 or 0
|
||||||
|
local overheal = arg10 or 0
|
||||||
|
local critical = arg12 == 1 and 1 or 0
|
||||||
|
local hit = critical == 0 and 1 or 0
|
||||||
|
local effective = amount - overheal
|
||||||
|
if effective < 0 then effective = 0 end
|
||||||
|
|
||||||
|
DB:Healing(1, DPSMateHealingTaken, srcName, spellName, hit, critical, effective)
|
||||||
|
DB:Healing(2, DPSMateOverhealing, srcName, spellName, hit, critical, overheal)
|
||||||
|
DB:HealingTaken(1, DPSMateHealingTaken, srcName, spellName, hit, critical, effective, dstName)
|
||||||
|
DB:DeathHistory(dstName, srcName, spellName, effective, hit, critical, "heal", 0)
|
||||||
|
|
||||||
|
-- ========================================================================
|
||||||
|
-- AURA events
|
||||||
|
-- ========================================================================
|
||||||
|
|
||||||
|
elseif sub == "SPELL_AURA_APPLIED" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local auraType = arg9
|
||||||
|
if auraType == "DEBUFF" then
|
||||||
|
DB:BuildBuffs(srcName, dstName, spellName, false)
|
||||||
|
if Parser.CC[spellName] then
|
||||||
|
DB:BuildActiveCC(dstName, spellName)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
DB:BuildBuffs(srcName, dstName, spellName, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif sub == "SPELL_AURA_REMOVED" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
DB:DestroyBuffs(dstName, spellName)
|
||||||
|
local auraType = arg9
|
||||||
|
if auraType == "DEBUFF" then
|
||||||
|
DB:RemoveActiveCC(dstName, spellName)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif sub == "SPELL_AURA_BROKEN_SPELL" or sub == "SPELL_AURA_BROKEN" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
DB:RemoveActiveCC(dstName, spellName)
|
||||||
|
if Parser.CC[spellName] then
|
||||||
|
DB:CCBreaker(dstName, spellName, srcName)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ========================================================================
|
||||||
|
-- CAST events
|
||||||
|
-- ========================================================================
|
||||||
|
|
||||||
|
elseif sub == "SPELL_CAST_SUCCESS" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
if Parser.Kicks and Parser.Kicks[spellName] then
|
||||||
|
DB:RegisterPotentialKick(srcName, spellName, GT())
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ========================================================================
|
||||||
|
-- INTERRUPT / DISPEL events
|
||||||
|
-- ========================================================================
|
||||||
|
|
||||||
|
elseif sub == "SPELL_INTERRUPT" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local extraSpellName = arg10 or "Unknown"
|
||||||
|
DB:Kick(srcName, dstName, spellName, extraSpellName)
|
||||||
|
|
||||||
|
elseif sub == "SPELL_DISPEL" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local extraSpellName = arg10 or "Unknown"
|
||||||
|
if isGroupMember(srcName) then
|
||||||
|
DB:Dispels(srcName, spellName, dstName, extraSpellName)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ========================================================================
|
||||||
|
-- DEATH events
|
||||||
|
-- ========================================================================
|
||||||
|
|
||||||
|
elseif sub == "UNIT_DIED" or sub == "UNIT_DESTROYED" then
|
||||||
|
DB:UnregisterDeath(dstName)
|
||||||
|
|
||||||
|
elseif sub == "SPELL_SUMMON" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
if not Parser.petToOwnerMap then Parser.petToOwnerMap = {} end
|
||||||
|
if not Parser.petToOwnerMap[dstName] then Parser.petToOwnerMap[dstName] = {} end
|
||||||
|
Parser.petToOwnerMap[dstName][srcName] = true
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Performance profiling
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- debugprofilestop() returns ms since last debugprofilestart().
|
||||||
|
-- We call debugprofilestart() once at combat start, then use debugprofilestop()
|
||||||
|
-- as a monotonic clock — taking deltas between before/after each handler call.
|
||||||
|
-- gcinfo() returns KB.
|
||||||
|
|
||||||
|
local profiling = false
|
||||||
|
local profCLEU = { events = 0, totalMs = 0, gcStart = 0 }
|
||||||
|
local profOrig = { events = 0, totalMs = 0, gcStart = 0 }
|
||||||
|
local profCurrent = nil
|
||||||
|
|
||||||
|
-- Hook the parser's OnEvent to measure original mode
|
||||||
|
local origOnEvent = DPSMate.Parser:GetScript("OnEvent")
|
||||||
|
local function measuredOrigOnEvent()
|
||||||
|
if profiling and profCurrent == profOrig then
|
||||||
|
local before = debugprofilestop()
|
||||||
|
origOnEvent()
|
||||||
|
local after = debugprofilestop()
|
||||||
|
profOrig.totalMs = profOrig.totalMs + (after - before)
|
||||||
|
profOrig.events = profOrig.events + 1
|
||||||
|
else
|
||||||
|
origOnEvent()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
DPSMate.Parser:SetScript("OnEvent", measuredOrigOnEvent)
|
||||||
|
|
||||||
|
-- Wrap the CLEU handler similarly
|
||||||
|
local cleuHandler -- forward decl
|
||||||
|
|
||||||
|
local function measuredCLEUHandler()
|
||||||
|
if profiling and profCurrent == profCLEU then
|
||||||
|
local before = debugprofilestop()
|
||||||
|
cleuHandler()
|
||||||
|
local after = debugprofilestop()
|
||||||
|
profCLEU.totalMs = profCLEU.totalMs + (after - before)
|
||||||
|
profCLEU.events = profCLEU.events + 1
|
||||||
|
else
|
||||||
|
cleuHandler()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function profReset(tbl)
|
||||||
|
tbl.events = 0
|
||||||
|
tbl.totalMs = 0
|
||||||
|
tbl.gcStart = gcinfo()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- debugprofilestop() returns microseconds on this client
|
||||||
|
local lastCLEUAvg = nil
|
||||||
|
local lastOrigAvg = nil
|
||||||
|
|
||||||
|
local function profReport(label, tbl)
|
||||||
|
local gcEnd = gcinfo()
|
||||||
|
local gcDelta = gcEnd - tbl.gcStart
|
||||||
|
local totalMs = tbl.totalMs / 1000
|
||||||
|
local avgUs = tbl.events > 0 and (tbl.totalMs / tbl.events) or 0
|
||||||
|
|
||||||
|
-- Store for comparison
|
||||||
|
if label == "CLEU" then
|
||||||
|
lastCLEUAvg = avgUs
|
||||||
|
else
|
||||||
|
lastOrigAvg = avgUs
|
||||||
|
end
|
||||||
|
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
||||||
|
"|cff00ff00[%s]|r %d events, %.1fms total, %.1f us/event, %+.1f KB gc",
|
||||||
|
label, tbl.events, totalMs, avgUs, gcDelta))
|
||||||
|
|
||||||
|
-- If we have both measurements, show comparison
|
||||||
|
if lastCLEUAvg and lastOrigAvg and lastOrigAvg > 0 then
|
||||||
|
local pct = ((lastCLEUAvg - lastOrigAvg) / lastOrigAvg) * 100
|
||||||
|
local sign = pct < 0 and "" or "+"
|
||||||
|
local color = pct < 0 and "|cff00ff00" or "|cffff4444"
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
||||||
|
"%s[CLEU vs ORIGINAL]|r %.1f vs %.1f us/event = %s%.1f%%|r %s",
|
||||||
|
color, lastCLEUAvg, lastOrigAvg, sign, pct,
|
||||||
|
pct < 0 and "(CLEU faster)" or "(ORIGINAL faster)"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- /dpsbench -- enables per-combat A/B profiling. Each combat: measure, report, flip.
|
||||||
|
local benchActive = true
|
||||||
|
|
||||||
|
local benchFrame = CreateFrame("Frame")
|
||||||
|
|
||||||
|
local function benchCombatStart()
|
||||||
|
if not benchActive then return end
|
||||||
|
profCurrent = cleuActive and profCLEU or profOrig
|
||||||
|
profReset(profCurrent)
|
||||||
|
debugprofilestart() -- start the monotonic clock for this combat
|
||||||
|
profiling = true
|
||||||
|
local label = cleuActive and "CLEU" or "ORIGINAL"
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(string.format("|cff00ff00[DPS Bench]|r combat started, measuring %s", label))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function benchCombatEnd()
|
||||||
|
if not benchActive or not profiling then return end
|
||||||
|
profiling = false
|
||||||
|
local label = cleuActive and "CLEU" or "ORIGINAL"
|
||||||
|
profReport(label, profCurrent)
|
||||||
|
toggle()
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
||||||
|
"|cff00ff00[DPS Bench]|r next combat will use: %s", cleuActive and "CLEU" or "ORIGINAL"))
|
||||||
|
end
|
||||||
|
|
||||||
|
benchFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||||
|
benchFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||||
|
benchFrame:SetScript("OnEvent", function()
|
||||||
|
if event == "PLAYER_REGEN_DISABLED" then
|
||||||
|
benchCombatStart()
|
||||||
|
elseif event == "PLAYER_REGEN_ENABLED" then
|
||||||
|
benchCombatEnd()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
SLASH_DPSBENCH1 = "/dpsbench"
|
||||||
|
SlashCmdList["DPSBENCH"] = function()
|
||||||
|
benchActive = not benchActive
|
||||||
|
if benchActive then
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
||||||
|
"|cff00ff00[DPS Bench]|r enabled. Current mode: %s. Enter combat to begin.",
|
||||||
|
cleuActive and "CLEU" or "ORIGINAL"))
|
||||||
|
else
|
||||||
|
profiling = false
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[DPS Bench]|r disabled.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Wire up CLEU handler with measurement
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- Replace the raw SetScript with the measured wrapper
|
||||||
|
cleuFrame:SetScript("OnEvent", function()
|
||||||
|
-- This outer function gets replaced below
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- The actual CLEU handler (extracted so we can call it directly or measured)
|
||||||
|
cleuHandler = function()
|
||||||
|
local sub = arg1
|
||||||
|
if not sub then return end
|
||||||
|
|
||||||
|
local srcGUID = arg2
|
||||||
|
local srcName = arg3
|
||||||
|
local dstGUID = arg4
|
||||||
|
local dstName = arg5
|
||||||
|
|
||||||
|
if not srcName or srcName == "" then srcName = "Unknown" end
|
||||||
|
if not dstName or dstName == "" then dstName = "Unknown" end
|
||||||
|
|
||||||
|
if sub == "SWING_DAMAGE" then
|
||||||
|
local amount = arg6 or 0
|
||||||
|
local critical = arg12 == 1 and 1 or 0
|
||||||
|
local glancing = arg13 == 1 and 1 or 0
|
||||||
|
local crushing = arg14 == 1 and 1 or 0
|
||||||
|
local hit = (critical == 0 and glancing == 0 and crushing == 0) and 1 or 0
|
||||||
|
DB:DamageDone(srcName, AAttack, hit, critical, 0, 0, 0, 0, amount, glancing, 0)
|
||||||
|
DB:DamageTaken(dstName, AAttack, hit, critical, 0, 0, 0, 0, amount, srcName, crushing, 0)
|
||||||
|
DB:EnemyDamage(1, DPSMateEDT, dstName, AAttack, hit, critical, 0, 0, 0, 0, amount, srcName, 0, crushing)
|
||||||
|
DB:EnemyDamage(2, DPSMateEDD, srcName, AAttack, hit, critical, 0, 0, 0, 0, amount, dstName, 0, 0)
|
||||||
|
DB:DeathHistory(dstName, srcName, AAttack, amount, hit, critical, "hit", crushing)
|
||||||
|
|
||||||
|
elseif sub == "SWING_MISSED" then
|
||||||
|
local missType = arg6
|
||||||
|
local miss = (missType == "MISS") and 1 or 0
|
||||||
|
local parry = (missType == "PARRY") and 1 or 0
|
||||||
|
local dodge = (missType == "DODGE") and 1 or 0
|
||||||
|
local resist = (missType == "RESIST" or missType == "IMMUNE") and 1 or 0
|
||||||
|
local block = (missType == "BLOCK") and 1 or 0
|
||||||
|
local absorb = (missType == "ABSORB") and 1 or 0
|
||||||
|
DB:DamageDone(srcName, AAttack, 0, 0, miss + absorb, parry, dodge, resist, 0, 0, block)
|
||||||
|
DB:DamageTaken(dstName, AAttack, 0, 0, miss + absorb, parry, dodge, resist, 0, srcName, 0, block)
|
||||||
|
|
||||||
|
elseif sub == "SPELL_DAMAGE" or sub == "RANGE_DAMAGE" or sub == "SPELL_PERIODIC_DAMAGE"
|
||||||
|
or sub == "DAMAGE_SHIELD" or sub == "DAMAGE_SPLIT" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local amount = arg9 or 0
|
||||||
|
local school = arg11
|
||||||
|
local critical = arg15 == 1 and 1 or 0
|
||||||
|
local glancing = arg16 == 1 and 1 or 0
|
||||||
|
local crushing = arg17 == 1 and 1 or 0
|
||||||
|
local hit = (critical == 0 and glancing == 0 and crushing == 0) and 1 or 0
|
||||||
|
DB:DamageDone(srcName, spellName, hit, critical, 0, 0, 0, 0, amount, glancing, 0)
|
||||||
|
DB:DamageTaken(dstName, spellName, hit, critical, 0, 0, 0, 0, amount, srcName, crushing, 0)
|
||||||
|
DB:EnemyDamage(1, DPSMateEDT, dstName, spellName, hit, critical, 0, 0, 0, 0, amount, srcName, 0, crushing)
|
||||||
|
DB:EnemyDamage(2, DPSMateEDD, srcName, spellName, hit, critical, 0, 0, 0, 0, amount, dstName, 0, 0)
|
||||||
|
DB:DeathHistory(dstName, srcName, spellName, amount, hit, critical, "hit", crushing)
|
||||||
|
if school then DB:AddSpellSchool(spellName, school) end
|
||||||
|
|
||||||
|
elseif sub == "SPELL_MISSED" or sub == "RANGE_MISSED"
|
||||||
|
or sub == "SPELL_PERIODIC_MISSED" or sub == "DAMAGE_SHIELD_MISSED" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local missType = arg9
|
||||||
|
local miss = (missType == "MISS") and 1 or 0
|
||||||
|
local parry = (missType == "PARRY") and 1 or 0
|
||||||
|
local dodge = (missType == "DODGE") and 1 or 0
|
||||||
|
local resist = (missType == "RESIST" or missType == "IMMUNE") and 1 or 0
|
||||||
|
local block = (missType == "BLOCK") and 1 or 0
|
||||||
|
local absorb = (missType == "ABSORB") and 1 or 0
|
||||||
|
DB:DamageDone(srcName, spellName, 0, 0, miss + absorb, parry, dodge, resist, 0, 0, block)
|
||||||
|
DB:DamageTaken(dstName, spellName, 0, 0, miss + absorb, parry, dodge, resist, 0, srcName, 0, block)
|
||||||
|
|
||||||
|
elseif sub == "ENVIRONMENTAL_DAMAGE" then
|
||||||
|
local envType = arg6
|
||||||
|
local amount = arg7 or 0
|
||||||
|
DB:DamageTaken(dstName, envType or "Environment", 1, 0, 0, 0, 0, 0, amount, envType or "Environment", 0, 0)
|
||||||
|
DB:DeathHistory(dstName, envType or "Environment", envType or "Environment", amount, 1, 0, "hit", 0)
|
||||||
|
|
||||||
|
elseif sub == "SPELL_HEAL" or sub == "SPELL_PERIODIC_HEAL" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local amount = arg9 or 0
|
||||||
|
local overheal = arg10 or 0
|
||||||
|
local critical = arg12 == 1 and 1 or 0
|
||||||
|
local hit = critical == 0 and 1 or 0
|
||||||
|
local effective = amount - overheal
|
||||||
|
if effective < 0 then effective = 0 end
|
||||||
|
DB:Healing(1, DPSMateHealingTaken, srcName, spellName, hit, critical, effective)
|
||||||
|
DB:Healing(2, DPSMateOverhealing, srcName, spellName, hit, critical, overheal)
|
||||||
|
DB:HealingTaken(1, DPSMateHealingTaken, srcName, spellName, hit, critical, effective, dstName)
|
||||||
|
DB:DeathHistory(dstName, srcName, spellName, effective, hit, critical, "heal", 0)
|
||||||
|
|
||||||
|
elseif sub == "SPELL_AURA_APPLIED" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local auraType = arg9
|
||||||
|
if auraType == "DEBUFF" then
|
||||||
|
DB:BuildBuffs(srcName, dstName, spellName, false)
|
||||||
|
if Parser.CC[spellName] then
|
||||||
|
DB:BuildActiveCC(dstName, spellName)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
DB:BuildBuffs(srcName, dstName, spellName, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif sub == "SPELL_AURA_REMOVED" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
DB:DestroyBuffs(dstName, spellName)
|
||||||
|
if arg9 == "DEBUFF" then
|
||||||
|
DB:RemoveActiveCC(dstName, spellName)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif sub == "SPELL_AURA_BROKEN_SPELL" or sub == "SPELL_AURA_BROKEN" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
DB:RemoveActiveCC(dstName, spellName)
|
||||||
|
if Parser.CC[spellName] then
|
||||||
|
DB:CCBreaker(dstName, spellName, srcName)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif sub == "SPELL_CAST_SUCCESS" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
if Parser.Kicks and Parser.Kicks[spellName] then
|
||||||
|
DB:RegisterPotentialKick(srcName, spellName, GT())
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif sub == "SPELL_INTERRUPT" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local extraSpellName = arg10 or "Unknown"
|
||||||
|
DB:Kick(srcName, dstName, spellName, extraSpellName)
|
||||||
|
|
||||||
|
elseif sub == "SPELL_DISPEL" then
|
||||||
|
local spellName = arg7 or "Unknown"
|
||||||
|
local extraSpellName = arg10 or "Unknown"
|
||||||
|
if isGroupMember(srcName) then
|
||||||
|
DB:Dispels(srcName, spellName, dstName, extraSpellName)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif sub == "UNIT_DIED" or sub == "UNIT_DESTROYED" then
|
||||||
|
DB:UnregisterDeath(dstName)
|
||||||
|
|
||||||
|
elseif sub == "SPELL_SUMMON" then
|
||||||
|
if not Parser.petToOwnerMap then Parser.petToOwnerMap = {} end
|
||||||
|
if not Parser.petToOwnerMap[dstName] then Parser.petToOwnerMap[dstName] = {} end
|
||||||
|
Parser.petToOwnerMap[dstName][srcName] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set the measured wrapper as the actual handler
|
||||||
|
cleuFrame:SetScript("OnEvent", measuredCLEUHandler)
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Start in CLEU mode by default
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
enableCLEU()
|
||||||
@@ -0,0 +1,367 @@
|
|||||||
|
-- DPSMate_CombatPatterns.lua
|
||||||
|
-- Pattern-based combat log matching using WoW global format strings.
|
||||||
|
-- Automatically adapts to server-specific combat log format changes (e.g., TWoW).
|
||||||
|
-- Field mappings are auto-detected from format string context, not hardcoded.
|
||||||
|
|
||||||
|
DPSMate.CombatPatterns = {}
|
||||||
|
local CP = DPSMate.CombatPatterns
|
||||||
|
|
||||||
|
local strfind = string.find
|
||||||
|
local strsub = string.sub
|
||||||
|
local tonumber = tonumber
|
||||||
|
local tinsert = table.insert
|
||||||
|
|
||||||
|
-- Convert a WoW format string (e.g., "You hit %s for %d.") to a Lua pattern
|
||||||
|
-- e.g., "You hit %s for %d." -> "^You hit (.+) for (%d+)%.$"
|
||||||
|
function CP:Sanitize(str)
|
||||||
|
if not str then return nil end
|
||||||
|
-- Replace format specifiers with placeholders before escaping
|
||||||
|
str = string.gsub(str, "%%s", "\001")
|
||||||
|
str = string.gsub(str, "%%d", "\002")
|
||||||
|
-- Escape Lua pattern magic characters
|
||||||
|
str = string.gsub(str, "([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1")
|
||||||
|
-- Replace placeholders with capture groups
|
||||||
|
str = string.gsub(str, "\001", "(.+)")
|
||||||
|
str = string.gsub(str, "\002", "(%d+)")
|
||||||
|
return "^" .. str .. "$"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Strip combat log trailers: (X absorbed), (blocked), (glancing), (crushing), (X resisted)
|
||||||
|
-- Returns: cleaned_msg, absorbed_amount, blocked(0/1), glancing(bool), crushing(bool)
|
||||||
|
function CP:StripTrailers(msg)
|
||||||
|
local absorbed, blocked, glancing, crushing = 0, 0, false, false
|
||||||
|
local i, j, amt
|
||||||
|
|
||||||
|
i, j, amt = strfind(msg, " %((%d+) absorbed%)")
|
||||||
|
if i then absorbed = tonumber(amt); msg = strsub(msg, 1, i-1) .. strsub(msg, j+1) end
|
||||||
|
|
||||||
|
i, j, amt = strfind(msg, " %((%d+) blocked%)")
|
||||||
|
if i then blocked = 1; msg = strsub(msg, 1, i-1) .. strsub(msg, j+1) end
|
||||||
|
if blocked == 0 then
|
||||||
|
i, j = strfind(msg, " %(blocked%)")
|
||||||
|
if i then blocked = 1; msg = strsub(msg, 1, i-1) .. strsub(msg, j+1) end
|
||||||
|
end
|
||||||
|
|
||||||
|
i, j = strfind(msg, " %(glancing%)")
|
||||||
|
if i then glancing = true; msg = strsub(msg, 1, i-1) .. strsub(msg, j+1) end
|
||||||
|
|
||||||
|
i, j = strfind(msg, " %(crushing%)")
|
||||||
|
if i then crushing = true; msg = strsub(msg, 1, i-1) .. strsub(msg, j+1) end
|
||||||
|
|
||||||
|
-- Strip resisted trailer to prevent pattern mismatch
|
||||||
|
i, j = strfind(msg, " %((%d+) resisted%)")
|
||||||
|
if i then msg = strsub(msg, 1, i-1) .. strsub(msg, j+1) end
|
||||||
|
|
||||||
|
return msg, absorbed, blocked, glancing, crushing
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Try matching a message against a list of pattern entries
|
||||||
|
-- Each entry: {pattern_string, hitType_string, {field=captureIndex, ...}}
|
||||||
|
-- Returns: hitType, result_table (with named fields) on match, or nil
|
||||||
|
function CP:TryMatch(msg, patterns)
|
||||||
|
if not patterns then return nil end
|
||||||
|
for _, entry in ipairs(patterns) do
|
||||||
|
local pattern = entry[1]
|
||||||
|
if pattern then
|
||||||
|
local c = {strfind(msg, pattern)}
|
||||||
|
if c[1] then
|
||||||
|
local result = {}
|
||||||
|
local fields = entry[3]
|
||||||
|
for field, idx in pairs(fields) do
|
||||||
|
result[field] = c[idx + 2] -- +2 to skip start/end positions
|
||||||
|
end
|
||||||
|
if result.amount then result.amount = tonumber(result.amount) end
|
||||||
|
return entry[2], result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Auto-detect field names for each format specifier based on surrounding text context.
|
||||||
|
-- Returns a table mapping field_name -> capture_index, or nil if format is empty/invalid.
|
||||||
|
-- overrides: optional table mapping detected_name -> desired_name (e.g., {target="source"})
|
||||||
|
function CP:DetectFields(fmt, overrides)
|
||||||
|
if not fmt then return nil end
|
||||||
|
|
||||||
|
-- Parse specifiers and the text segments between them
|
||||||
|
local specs = {}
|
||||||
|
local n = 0
|
||||||
|
local pos = 1
|
||||||
|
while true do
|
||||||
|
local i, j, specType = strfind(fmt, "%%([sd])", pos)
|
||||||
|
if not i then break end
|
||||||
|
n = n + 1
|
||||||
|
specs[n] = {
|
||||||
|
type = specType,
|
||||||
|
before = strsub(fmt, pos, i - 1),
|
||||||
|
}
|
||||||
|
pos = j + 1
|
||||||
|
end
|
||||||
|
if n == 0 then return nil end
|
||||||
|
|
||||||
|
-- Set "after" text for each spec (text between this spec and the next, or trailing)
|
||||||
|
for i = 1, n - 1 do
|
||||||
|
specs[i].after = specs[i + 1].before
|
||||||
|
end
|
||||||
|
specs[n].after = strsub(fmt, pos)
|
||||||
|
|
||||||
|
-- Detect field name for each specifier based on surrounding text
|
||||||
|
local fields = {}
|
||||||
|
|
||||||
|
for i = 1, n do
|
||||||
|
local s = specs[i]
|
||||||
|
local field
|
||||||
|
|
||||||
|
if s.type == "d" then
|
||||||
|
field = "amount"
|
||||||
|
else
|
||||||
|
local before = s.before
|
||||||
|
local after = s.after
|
||||||
|
|
||||||
|
-- Rule 1: After "Your/your " -> ability (e.g., "Your %s hits")
|
||||||
|
if strfind(before, "Your ?$") or strfind(before, "your ?$") then
|
||||||
|
field = "ability"
|
||||||
|
-- Rule 2: After "'s " -> ability (e.g., "Source's %s hits")
|
||||||
|
elseif strfind(before, "'s ?$") or strfind(before, "' s ?$") then
|
||||||
|
field = "ability"
|
||||||
|
-- Rule 3: Before "'s" -> source (e.g., "%s's Ability", "%s 's Ability")
|
||||||
|
elseif strfind(after, "^'s") or strfind(after, "^' s") or strfind(after, "^ 's") then
|
||||||
|
field = "source"
|
||||||
|
-- Rule 4: Before " damage" -> school (e.g., "%d %s damage")
|
||||||
|
elseif strfind(after, "^ damage") then
|
||||||
|
field = "school"
|
||||||
|
-- Rule 5: Before " suffers" -> target (e.g., "%s suffers %d")
|
||||||
|
elseif strfind(after, "^ suffers") then
|
||||||
|
field = "target"
|
||||||
|
-- Rule 6: Before action verbs -> source (e.g., "%s hits", "%s critically hits")
|
||||||
|
elseif strfind(after, "^ hits") or strfind(after, "^ crits") or
|
||||||
|
strfind(after, "^ misses") or strfind(after, "^ attacks") or
|
||||||
|
strfind(after, "^ reflects") or strfind(after, "^ critically") then
|
||||||
|
field = "source"
|
||||||
|
-- Rule 7: Before reaction verbs -> target (e.g., "%s parries", "%s is immune")
|
||||||
|
elseif strfind(after, "^ parries") or strfind(after, "^ dodges") or
|
||||||
|
strfind(after, "^ blocks") or strfind(after, "^ absorbs") or
|
||||||
|
strfind(after, "^ is immune") then
|
||||||
|
field = "target"
|
||||||
|
-- Rule 8: Before " for " -> target (e.g., "hits %s for %d")
|
||||||
|
elseif strfind(after, "^ for ") then
|
||||||
|
field = "target"
|
||||||
|
-- Rule 9: After " to " -> target (e.g., "damage to %s")
|
||||||
|
elseif strfind(before, " to ?$") then
|
||||||
|
field = "target"
|
||||||
|
-- Rule 10: After " by " -> target (e.g., "dodged by %s")
|
||||||
|
elseif strfind(before, " by ?$") then
|
||||||
|
field = "target"
|
||||||
|
-- Rule 11: After " from " -> source (e.g., "damage from %s")
|
||||||
|
elseif strfind(before, " from ?$") then
|
||||||
|
field = "source"
|
||||||
|
-- Rule 12: "You <verb> %s" -> target (e.g., "You miss %s")
|
||||||
|
elseif strfind(before, "^You %a+ ?$") then
|
||||||
|
field = "target"
|
||||||
|
-- Rule 13: End of message -> target (fallback for last %s)
|
||||||
|
elseif strfind(after, "^%.?$") then
|
||||||
|
field = "target"
|
||||||
|
else
|
||||||
|
field = "target"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Apply overrides (e.g., env damage: detected "target" -> call it "source")
|
||||||
|
if overrides and overrides[field] then
|
||||||
|
field = overrides[field]
|
||||||
|
end
|
||||||
|
|
||||||
|
fields[field] = i
|
||||||
|
end
|
||||||
|
|
||||||
|
return fields
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Flag indicating patterns have been built
|
||||||
|
CP.ready = false
|
||||||
|
|
||||||
|
-- Helper: add a pattern entry from a WoW global string name.
|
||||||
|
-- Field mappings are auto-detected from format string content.
|
||||||
|
-- overrides: optional table mapping detected_name -> desired_name
|
||||||
|
local function addP(tbl, globalName, hitType, overrides)
|
||||||
|
local str = getglobal(globalName)
|
||||||
|
if str then
|
||||||
|
local fields = CP:DetectFields(str, overrides)
|
||||||
|
if fields then
|
||||||
|
tinsert(tbl, {CP:Sanitize(str), hitType, fields})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Build all patterns from WoW globals.
|
||||||
|
-- MUST be called AFTER InitParser modifies the globals (adds space before 's).
|
||||||
|
function CP:BuildPatterns()
|
||||||
|
-- =================== SELF MELEE HITS ===================
|
||||||
|
-- "You hit Target for Amount [School damage]."
|
||||||
|
self.selfMeleeHit = {}
|
||||||
|
addP(self.selfMeleeHit, "COMBATHITCRITSCHOOLSELFOTHER", "crit")
|
||||||
|
addP(self.selfMeleeHit, "COMBATHITSCHOOLSELFOTHER", "hit")
|
||||||
|
addP(self.selfMeleeHit, "COMBATHITCRITSELFOTHER", "crit")
|
||||||
|
addP(self.selfMeleeHit, "COMBATHITSELFOTHER", "hit")
|
||||||
|
|
||||||
|
-- =================== OTHER MELEE HITS ===================
|
||||||
|
-- "Source hits Target for Amount [School damage]."
|
||||||
|
self.otherMeleeHit = {}
|
||||||
|
addP(self.otherMeleeHit, "COMBATHITCRITSCHOOLOTHEROTHER", "crit")
|
||||||
|
addP(self.otherMeleeHit, "COMBATHITSCHOOLOTHEROTHER", "hit")
|
||||||
|
addP(self.otherMeleeHit, "COMBATHITCRITOTHEROTHER", "crit")
|
||||||
|
addP(self.otherMeleeHit, "COMBATHITOTHEROTHER", "hit")
|
||||||
|
|
||||||
|
-- =================== SELF SPELL HITS ===================
|
||||||
|
-- "Your Ability hits Target for Amount [School damage]."
|
||||||
|
self.selfSpellHit = {}
|
||||||
|
addP(self.selfSpellHit, "SPELLLOGCRITSCHOOLSELFOTHER", "crit")
|
||||||
|
addP(self.selfSpellHit, "SPELLLOGSCHOOLSELFOTHER", "hit")
|
||||||
|
addP(self.selfSpellHit, "SPELLLOGCRITSELFOTHER", "crit")
|
||||||
|
addP(self.selfSpellHit, "SPELLLOGSELFOTHER", "hit")
|
||||||
|
addP(self.selfSpellHit, "SPELLLOGCRITSCHOOLSELFSELF", "crit")
|
||||||
|
addP(self.selfSpellHit, "SPELLLOGSCHOOLSELFSELF", "hit")
|
||||||
|
addP(self.selfSpellHit, "SPELLLOGCRITSELFSELF", "crit")
|
||||||
|
addP(self.selfSpellHit, "SPELLLOGSELFSELF", "hit")
|
||||||
|
|
||||||
|
-- =================== OTHER SPELL HITS ===================
|
||||||
|
-- "Source's Ability hits Target for Amount [School damage]."
|
||||||
|
self.otherSpellHit = {}
|
||||||
|
addP(self.otherSpellHit, "SPELLLOGCRITSCHOOLOTHEROTHER", "crit")
|
||||||
|
addP(self.otherSpellHit, "SPELLLOGSCHOOLOTHEROTHER", "hit")
|
||||||
|
addP(self.otherSpellHit, "SPELLLOGCRITOTHEROTHER", "crit")
|
||||||
|
addP(self.otherSpellHit, "SPELLLOGOTHEROTHER", "hit")
|
||||||
|
|
||||||
|
-- =================== PERIODIC DAMAGE ===================
|
||||||
|
-- "Target suffers Amount School damage from Source's Ability."
|
||||||
|
self.periodicDmg = {}
|
||||||
|
addP(self.periodicDmg, "PERIODICAURADAMAGEOTHEROTHER", "dot")
|
||||||
|
addP(self.periodicDmg, "PERIODICAURADAMAGESELFOTHER", "dot")
|
||||||
|
addP(self.periodicDmg, "PERIODICAURADAMAGEOTHERSELF", "dot")
|
||||||
|
addP(self.periodicDmg, "PERIODICAURADAMAGESELFSELF", "dot")
|
||||||
|
|
||||||
|
-- =================== DAMAGE SHIELDS ===================
|
||||||
|
self.dmgShield = {}
|
||||||
|
addP(self.dmgShield, "DAMAGESHIELDSELFOTHER", "shield")
|
||||||
|
addP(self.dmgShield, "DAMAGESHIELDOTHERSELF", "shield")
|
||||||
|
addP(self.dmgShield, "DAMAGESHIELDOTHEROTHER", "shield")
|
||||||
|
|
||||||
|
-- =================== ENVIRONMENTAL DAMAGE ===================
|
||||||
|
-- Entity "suffering" env damage is called "source" in the data model
|
||||||
|
local envOverride = {target = "source"}
|
||||||
|
|
||||||
|
self.envDmgSelf = {}
|
||||||
|
addP(self.envDmgSelf, "VSENVIRONMENTALDAMAGE_FALLING_SELF", "falling")
|
||||||
|
addP(self.envDmgSelf, "VSENVIRONMENTALDAMAGE_DROWNING_SELF", "drowning")
|
||||||
|
addP(self.envDmgSelf, "VSENVIRONMENTALDAMAGE_LAVA_SELF", "lava")
|
||||||
|
addP(self.envDmgSelf, "VSENVIRONMENTALDAMAGE_SLIME_SELF", "slime")
|
||||||
|
addP(self.envDmgSelf, "VSENVIRONMENTALDAMAGE_FIRE_SELF", "fire")
|
||||||
|
addP(self.envDmgSelf, "VSENVIRONMENTALDAMAGE_FATIGUE_SELF", "fatigue")
|
||||||
|
|
||||||
|
self.envDmgOther = {}
|
||||||
|
addP(self.envDmgOther, "VSENVIRONMENTALDAMAGE_FALLING_OTHER", "falling", envOverride)
|
||||||
|
addP(self.envDmgOther, "VSENVIRONMENTALDAMAGE_DROWNING_OTHER", "drowning", envOverride)
|
||||||
|
addP(self.envDmgOther, "VSENVIRONMENTALDAMAGE_LAVA_OTHER", "lava", envOverride)
|
||||||
|
addP(self.envDmgOther, "VSENVIRONMENTALDAMAGE_SLIME_OTHER", "slime", envOverride)
|
||||||
|
addP(self.envDmgOther, "VSENVIRONMENTALDAMAGE_FIRE_OTHER", "fire", envOverride)
|
||||||
|
addP(self.envDmgOther, "VSENVIRONMENTALDAMAGE_FATIGUE_OTHER", "fatigue", envOverride)
|
||||||
|
|
||||||
|
-- =================== SELF SPELL MISSES ===================
|
||||||
|
self.selfSpellMiss = {}
|
||||||
|
addP(self.selfSpellMiss, "SPELLMISSSELFOTHER", "miss")
|
||||||
|
addP(self.selfSpellMiss, "SPELLRESISTSELFOTHER", "resist")
|
||||||
|
addP(self.selfSpellMiss, "SPELLPARRIEDSELFOTHER", "parry")
|
||||||
|
addP(self.selfSpellMiss, "SPELLDODGEDSELFOTHER", "dodge")
|
||||||
|
addP(self.selfSpellMiss, "SPELLLOGABSORBSELFOTHER", "absorb")
|
||||||
|
addP(self.selfSpellMiss, "SPELLBLOCKEDSELFOTHER", "block")
|
||||||
|
addP(self.selfSpellMiss, "SPELLIMMUNESELFOTHER", "immune")
|
||||||
|
|
||||||
|
-- =================== OTHER SPELL MISSES ===================
|
||||||
|
self.otherSpellMiss = {}
|
||||||
|
addP(self.otherSpellMiss, "SPELLMISSOTHEROTHER", "miss")
|
||||||
|
addP(self.otherSpellMiss, "SPELLRESISTOTHEROTHER", "resist")
|
||||||
|
addP(self.otherSpellMiss, "SPELLPARRIEDOTHEROTHER", "parry")
|
||||||
|
addP(self.otherSpellMiss, "SPELLDODGEDOTHEROTHER", "dodge")
|
||||||
|
addP(self.otherSpellMiss, "SPELLLOGABSORBOTHEROTHER", "absorb")
|
||||||
|
addP(self.otherSpellMiss, "SPELLBLOCKEDOTHEROTHER", "block")
|
||||||
|
addP(self.otherSpellMiss, "SPELLIMMUNEOTHEROTHER", "immune")
|
||||||
|
addP(self.otherSpellMiss, "SPELLEVADEDOTHEROTHER", "evade")
|
||||||
|
|
||||||
|
-- =================== SELF MELEE MISSES ===================
|
||||||
|
self.selfMeleeMiss = {}
|
||||||
|
addP(self.selfMeleeMiss, "MISSEDSELFOTHER", "miss")
|
||||||
|
addP(self.selfMeleeMiss, "VSPARRYSELFOTHER", "parry")
|
||||||
|
addP(self.selfMeleeMiss, "VSDODGESELFOTHER", "dodge")
|
||||||
|
addP(self.selfMeleeMiss, "VSBLOCKSELFOTHER", "block")
|
||||||
|
addP(self.selfMeleeMiss, "VSABSORBSELFOTHER", "absorb")
|
||||||
|
|
||||||
|
-- =================== OTHER MELEE MISSES ===================
|
||||||
|
self.otherMeleeMiss = {}
|
||||||
|
addP(self.otherMeleeMiss, "MISSEDOTHEROTHER", "miss")
|
||||||
|
addP(self.otherMeleeMiss, "VSPARRYOTHEROTHER", "parry")
|
||||||
|
addP(self.otherMeleeMiss, "VSDODGEOTHEROTHER", "dodge")
|
||||||
|
addP(self.otherMeleeMiss, "VSBLOCKOTHEROTHER", "block")
|
||||||
|
addP(self.otherMeleeMiss, "VSABSORBOTHEROTHER", "absorb")
|
||||||
|
|
||||||
|
self.ready = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Debug: dump all detected patterns and their field mappings to chat.
|
||||||
|
-- Usage in-game: /script DPSMate.CombatPatterns:DebugDump()
|
||||||
|
function CP:DebugDump()
|
||||||
|
local function dump(name, tbl)
|
||||||
|
if not tbl or not tbl[1] then return end
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage("|cFF00FF00=== " .. name .. " ===|r")
|
||||||
|
for i, entry in ipairs(tbl) do
|
||||||
|
local hitType = entry[2] or "nil"
|
||||||
|
local fields = entry[3]
|
||||||
|
local fieldStr = ""
|
||||||
|
if fields then
|
||||||
|
for k, v in pairs(fields) do
|
||||||
|
if fieldStr ~= "" then fieldStr = fieldStr .. ", " end
|
||||||
|
fieldStr = fieldStr .. k .. "=" .. v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(" " .. hitType .. ": {" .. fieldStr .. "}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage("|cFFFFFF00--- CombatPatterns Debug Dump ---|r")
|
||||||
|
dump("selfMeleeHit", self.selfMeleeHit)
|
||||||
|
dump("otherMeleeHit", self.otherMeleeHit)
|
||||||
|
dump("selfSpellHit", self.selfSpellHit)
|
||||||
|
dump("otherSpellHit", self.otherSpellHit)
|
||||||
|
dump("periodicDmg", self.periodicDmg)
|
||||||
|
dump("dmgShield", self.dmgShield)
|
||||||
|
dump("envDmgSelf", self.envDmgSelf)
|
||||||
|
dump("envDmgOther", self.envDmgOther)
|
||||||
|
dump("selfSpellMiss", self.selfSpellMiss)
|
||||||
|
dump("otherSpellMiss", self.otherSpellMiss)
|
||||||
|
dump("selfMeleeMiss", self.selfMeleeMiss)
|
||||||
|
dump("otherMeleeMiss", self.otherMeleeMiss)
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage("|cFF00FF00CP.ready = " .. tostring(self.ready) .. "|r")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Debug: test auto-detection on a specific WoW global and show the result.
|
||||||
|
-- Usage: /script DPSMate.CombatPatterns:DebugGlobal("PERIODICAURADAMAGEOTHERSELF")
|
||||||
|
function CP:DebugGlobal(globalName, overrides)
|
||||||
|
local str = getglobal(globalName)
|
||||||
|
if not str then
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage("|cFFFF0000" .. globalName .. " = nil|r")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage("|cFFFFFF00" .. globalName .. "|r = \"" .. str .. "\"")
|
||||||
|
local fields = self:DetectFields(str, overrides)
|
||||||
|
if fields then
|
||||||
|
local fieldStr = ""
|
||||||
|
for k, v in pairs(fields) do
|
||||||
|
if fieldStr ~= "" then fieldStr = fieldStr .. ", " end
|
||||||
|
fieldStr = fieldStr .. k .. "=" .. v
|
||||||
|
end
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(" Fields: {" .. fieldStr .. "}")
|
||||||
|
else
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(" |cFFFF0000No fields detected|r")
|
||||||
|
end
|
||||||
|
DEFAULT_CHAT_FRAME:AddMessage(" Pattern: " .. (self:Sanitize(str) or "nil"))
|
||||||
|
end
|
||||||
@@ -0,0 +1,420 @@
|
|||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||||
|
..\..\..\FrameXML\UI.xsd">
|
||||||
|
|
||||||
|
<StatusBar name="DPSMate_Bar" virtual="true">
|
||||||
|
<Size y="12" />
|
||||||
|
<Layers>
|
||||||
|
<Layer level="ARTWORK">
|
||||||
|
<FontString name="$parent_Name" inherits="TextStatusBarText" justifyH="LEFT">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" />
|
||||||
|
<Anchor point="BOTTOMRIGHT" />
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_Value" inherits="TextStatusBarText" justifyH="RIGHT">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT"/>
|
||||||
|
<Anchor point="BOTTOMRIGHT">
|
||||||
|
<Offset x="-3" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
</Layer>
|
||||||
|
<Layer level="BACKGROUND">
|
||||||
|
<Texture name="$parent_BG">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" />
|
||||||
|
<Anchor point="BOTTOMRIGHT" />
|
||||||
|
</Anchors>
|
||||||
|
<Color r="0" g="0" b="0" />
|
||||||
|
</Texture>
|
||||||
|
</Layer>
|
||||||
|
<Layer level="OVERLAY">
|
||||||
|
<Texture name="$parent_Icon" file="Interface\AddOns\DPSMate\images\class\hunter" hidden="true">
|
||||||
|
<Size x="13" y="13" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="LEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Texture>
|
||||||
|
</Layer>
|
||||||
|
</Layers>
|
||||||
|
</StatusBar>
|
||||||
|
|
||||||
|
<StatusBar name="DPSMate_StatusBar" inherits="DPSMate_Bar" virtual="true">
|
||||||
|
<Scripts>
|
||||||
|
<OnLoad>
|
||||||
|
this:SetMinMaxValues(1,100)
|
||||||
|
this:SetValue(100)
|
||||||
|
getglobal(this:GetName().."_BG"):SetAlpha(0.5)
|
||||||
|
</OnLoad>
|
||||||
|
<OnMouseUp>
|
||||||
|
if arg1 == "LeftButton" then
|
||||||
|
DPSMate.Options:UpdateDetails(this)
|
||||||
|
else
|
||||||
|
DPSMate.Options:InializePlayerDewDrop(this)
|
||||||
|
DPSMate.Options:OpenMenu(4, this)
|
||||||
|
end
|
||||||
|
</OnMouseUp>
|
||||||
|
<OnEnter>
|
||||||
|
DPSMate.Options:ShowTooltip()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
</Scripts>
|
||||||
|
</StatusBar>
|
||||||
|
|
||||||
|
<StatusBar name="DPSMate_StatusBarTotal" inherits="DPSMate_Bar" virtual="true">
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "TOPLEFT")
|
||||||
|
GameTooltip:AddLine(DPSMate.L["leftclickopend"])
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnMouseUp>
|
||||||
|
DPSMate.Options:UpdateTotalDetails(this)
|
||||||
|
</OnMouseUp>
|
||||||
|
</Scripts>
|
||||||
|
</StatusBar>
|
||||||
|
|
||||||
|
<Frame name="DPSMate_Statusframe" parent="UIParent" movable="true" enablemouse="true" resizable="true" frameStrata="low" virtual="true">
|
||||||
|
<Size x="150" y="100" />
|
||||||
|
<ResizeBounds>
|
||||||
|
<minResize x="100" y="100"/>
|
||||||
|
<maxResize x="400" y="600"/>
|
||||||
|
</ResizeBounds>
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="CENTER" />
|
||||||
|
</Anchors>
|
||||||
|
<Scripts>
|
||||||
|
<OnLoad>
|
||||||
|
this:SetClampedToScreen(true)
|
||||||
|
</OnLoad>
|
||||||
|
<OnSizeChanged>
|
||||||
|
if getglobal(this:GetName().."_ScrollFrame") then
|
||||||
|
getglobal(this:GetName().."_ScrollFrame_Child"):SetWidth(this:GetWidth())
|
||||||
|
getglobal(this:GetName().."_ScrollFrame"):SetHeight(this:GetHeight()-16)
|
||||||
|
end
|
||||||
|
</OnSizeChanged>
|
||||||
|
</Scripts>
|
||||||
|
<Frames>
|
||||||
|
<Frame name="$parent_Border" frameStrata="BACKGROUND">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="-4" y="4" />
|
||||||
|
</Anchor>
|
||||||
|
<Anchor point="TOPRIGHT">
|
||||||
|
<Offset x="4" y="4" />
|
||||||
|
</Anchor>
|
||||||
|
<Anchor point="BOTTOMLEFT">
|
||||||
|
<Offset x="-4" y="-4" />
|
||||||
|
</Anchor>
|
||||||
|
<Anchor point="BOTTOMRIGHT">
|
||||||
|
<Offset x="4" y="-4" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Backdrop edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||||||
|
<BackgroundInsets left="5" right="5" top="3" bottom="1" />
|
||||||
|
<TileSize val="12" />
|
||||||
|
<EdgeSize val="4" />
|
||||||
|
<Color r="0.157" g="0.08" b="0.06" a="1" />
|
||||||
|
</Backdrop>
|
||||||
|
</Frame>
|
||||||
|
<Button name="$parent_Resize" frameStrata="HIGH">
|
||||||
|
<Size x="14" y="14" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="BOTTOMRIGHT" relativeTo="$parent" relativePoint="BOTTOMRIGHT" />
|
||||||
|
</Anchors>
|
||||||
|
<Scripts>
|
||||||
|
<OnMouseDown>
|
||||||
|
this:GetParent():StartSizing()
|
||||||
|
</OnMouseDown>
|
||||||
|
<OnMouseUp>
|
||||||
|
this:GetParent():StopMovingOrSizing()
|
||||||
|
DPSMateSettings["windows"][this:GetParent().Key]["savsize"] = {}
|
||||||
|
DPSMateSettings["windows"][this:GetParent().Key]["savsize"][1] = this:GetParent():GetWidth()
|
||||||
|
DPSMateSettings["windows"][this:GetParent().Key]["savsize"][2] = this:GetParent():GetHeight()
|
||||||
|
</OnMouseUp>
|
||||||
|
</Scripts>
|
||||||
|
<NormalTexture file="Interface\AddOns\DPSMate\images\UI-ChatIM-SizeGrabber-Up"/>
|
||||||
|
<PushedTexture file="Interface\AddOns\DPSMate\images\UI-ChatIM-SizeGrabber-Down"/>
|
||||||
|
<HighlightTexture file="Interface\AddOns\DPSMate\images\UI-ChatIM-SizeGrabber-Highlight" alphaMode="ADD"/>
|
||||||
|
</Button>
|
||||||
|
<Frame name="$parent_Head">
|
||||||
|
<Size y="16" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT"/>
|
||||||
|
<Anchor point="TOPRIGHT"/>
|
||||||
|
</Anchors>
|
||||||
|
<Layers>
|
||||||
|
<Layer level="BACKGROUND">
|
||||||
|
<Texture name="$parent_Background">
|
||||||
|
<Color r="1" g="0.82" b="0"/>
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT"/>
|
||||||
|
<Anchor point="BOTTOMRIGHT"/>
|
||||||
|
</Anchors>
|
||||||
|
</Texture>
|
||||||
|
</Layer>
|
||||||
|
<Layer level="ARTWORK">
|
||||||
|
<FontString name="$parent_Font" inherits="GameFontNormalSmall" justifyH="LEFT">
|
||||||
|
<Size x="200" y="16" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="LEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
</Layer>
|
||||||
|
</Layers>
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "TOPLEFT")
|
||||||
|
GameTooltip:AddLine(DPSMate.L["rcchangemode"])
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnMouseDown>
|
||||||
|
if arg1 == "LeftButton" and not DPSMateSettings.lock then
|
||||||
|
this:GetParent():StartMoving()
|
||||||
|
end
|
||||||
|
</OnMouseDown>
|
||||||
|
<OnMouseUp>
|
||||||
|
if arg1 == "RightButton" then
|
||||||
|
DPSMate.Options:OpenMenu(1, this:GetParent())
|
||||||
|
else
|
||||||
|
this:GetParent():StopMovingOrSizing()
|
||||||
|
local point, _, _, xOfs, yOfs = this:GetParent():GetPoint()
|
||||||
|
DPSMateSettings["windows"][this:GetParent().Key]["position"] = {}
|
||||||
|
DPSMateSettings["windows"][this:GetParent().Key]["position"][1] = point
|
||||||
|
DPSMateSettings["windows"][this:GetParent().Key]["position"][2] = xOfs
|
||||||
|
DPSMateSettings["windows"][this:GetParent().Key]["position"][3] = yOfs
|
||||||
|
end
|
||||||
|
</OnMouseUp>
|
||||||
|
</Scripts>
|
||||||
|
<Frames>
|
||||||
|
<Button name="$parent_Config">
|
||||||
|
<Size x="16" y="16" />
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "TOPLEFT")
|
||||||
|
GameTooltip:AddLine(DPSMate.L["config"])
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnMouseUp>
|
||||||
|
DPSMate.Options:OpenMenu(3, this:GetParent():GetParent())
|
||||||
|
</OnMouseUp>
|
||||||
|
</Scripts>
|
||||||
|
<HighlightTexture file="Interface\AddOns\DPSMate\images\icon-config" alphaMode="ADD"/>
|
||||||
|
<NormalTexture file="Interface\AddOns\DPSMate\images\icon-config"/>
|
||||||
|
<PushedTexture file="Interface\AddOns\DPSMate\images\icon-config"/>
|
||||||
|
</Button>
|
||||||
|
<Button name="$parent_Reset">
|
||||||
|
<Size x="14" y="14" />
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "TOPLEFT")
|
||||||
|
GameTooltip:AddLine(DPSMate.L["reset"])
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnClick>
|
||||||
|
DPSMate_PopUp:Show()
|
||||||
|
</OnClick>
|
||||||
|
</Scripts>
|
||||||
|
<HighlightTexture file="Interface\AddOns\DPSMate\images\icon-reset" alphaMode="ADD"/>
|
||||||
|
<NormalTexture file="Interface\AddOns\DPSMate\images\icon-reset"/>
|
||||||
|
<PushedTexture file="Interface\AddOns\DPSMate\images\icon-reset"/>
|
||||||
|
</Button>
|
||||||
|
<Button name="$parent_Segments">
|
||||||
|
<Size x="14" y="14" />
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "TOPLEFT")
|
||||||
|
GameTooltip:AddLine(DPSMate.L["segment"])
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnMouseUp>
|
||||||
|
DPSMate.Options:OpenMenu(2, this:GetParent():GetParent())
|
||||||
|
</OnMouseUp>
|
||||||
|
</Scripts>
|
||||||
|
<HighlightTexture file="Interface\AddOns\DPSMate\images\UI-GuildButton-PublicNote-Up" alphaMode="ADD"/>
|
||||||
|
<NormalTexture file="Interface\AddOns\DPSMate\images\UI-GuildButton-PublicNote-Up"/>
|
||||||
|
<PushedTexture file="Interface\AddOns\DPSMate\images\UI-GuildButton-PublicNote-Up"/>
|
||||||
|
</Button>
|
||||||
|
<Button name="$parent_Filter">
|
||||||
|
<Size x="14" y="14" />
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "TOPLEFT")
|
||||||
|
GameTooltip:AddLine(DPSMate.L["filter"])
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnMouseUp>
|
||||||
|
DPSMate.Options:OpenMenu(5, this:GetParent():GetParent())
|
||||||
|
</OnMouseUp>
|
||||||
|
</Scripts>
|
||||||
|
<HighlightTexture file="Interface\AddOns\DPSMate\images\UI-GuildButton-PublicNote-Up" alphaMode="ADD"/>
|
||||||
|
<NormalTexture file="Interface\AddOns\DPSMate\images\UI-GuildButton-PublicNote-Up"/>
|
||||||
|
<PushedTexture file="Interface\AddOns\DPSMate\images\UI-GuildButton-PublicNote-Up"/>
|
||||||
|
</Button>
|
||||||
|
<Button name="$parent_Report">
|
||||||
|
<Size x="14" y="14" />
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "TOPLEFT")
|
||||||
|
GameTooltip:AddLine(DPSMate.L["report"])
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnClick>
|
||||||
|
DPSMate_Report.PaKey=this:GetParent():GetParent().Key
|
||||||
|
DPSMate_Report:Show()
|
||||||
|
</OnClick>
|
||||||
|
</Scripts>
|
||||||
|
<HighlightTexture file="Interface\AddOns\DPSMate\images\UI-GuildButton-MOTD-Up" alphaMode="ADD"/>
|
||||||
|
<NormalTexture file="Interface\AddOns\DPSMate\images\UI-GuildButton-MOTD-Up"/>
|
||||||
|
<PushedTexture file="Interface\AddOns\DPSMate\images\UI-GuildButton-MOTD-Up"/>
|
||||||
|
</Button>
|
||||||
|
<Button name="$parent_Sync">
|
||||||
|
<Size x="14" y="14" />
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "TOPLEFT")
|
||||||
|
GameTooltip:AddLine(DPSMate.L["sync"])
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnClick>
|
||||||
|
DPSMate.Options:ToggleSync()
|
||||||
|
</OnClick>
|
||||||
|
</Scripts>
|
||||||
|
<HighlightTexture file="Interface\AddOns\DPSMate\images\sync" alphaMode="ADD"/>
|
||||||
|
<NormalTexture file="Interface\AddOns\DPSMate\images\sync"/>
|
||||||
|
<PushedTexture file="Interface\AddOns\DPSMate\images\sync"/>
|
||||||
|
</Button>
|
||||||
|
<Checkbutton name="$parent_Enable" inherits="UICheckButtonTemplate">
|
||||||
|
<Size x="18" y="18" />
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "TOPLEFT")
|
||||||
|
GameTooltip:AddLine(DPSMate.L["enabledisable"])
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnClick>
|
||||||
|
DPSMate.Options:ToggleState()
|
||||||
|
</OnClick>
|
||||||
|
</Scripts>
|
||||||
|
</Checkbutton>
|
||||||
|
</Frames>
|
||||||
|
</Frame>
|
||||||
|
<ScrollFrame name="$parent_ScrollFrame">
|
||||||
|
<Size y="84" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_Head" relativePoint="BOTTOMLEFT">
|
||||||
|
<Offset x="0.5" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
<Anchor point="TOPRIGHT" relativeTo="$parent_Head" relativePoint="BOTTOMRIGHT" />
|
||||||
|
</Anchors>
|
||||||
|
<Layers>
|
||||||
|
<Layer leve="BACKGROUND">
|
||||||
|
<Texture name="$parent_Background" file="Interface\Tooltips\UI-Tooltip-Background">
|
||||||
|
<Color r="1" g="1" b="1"/>
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT"/>
|
||||||
|
<Anchor point="BOTTOMRIGHT"/>
|
||||||
|
</Anchors>
|
||||||
|
</Texture>
|
||||||
|
</Layer>
|
||||||
|
</Layers>
|
||||||
|
<Scripts>
|
||||||
|
<OnLoad>
|
||||||
|
this:SetVerticalScroll(0)
|
||||||
|
</OnLoad>
|
||||||
|
<OnMouseWheel>
|
||||||
|
DPSMate.Options:OnVerticalScroll(this, arg1)
|
||||||
|
</OnMouseWheel>
|
||||||
|
</Scripts>
|
||||||
|
<ScrollChild>
|
||||||
|
<Frame name="$parent_Child">
|
||||||
|
<Size x="400" />
|
||||||
|
<Frames>
|
||||||
|
<StatusBar name="$parent_Total" inherits="DPSMate_StatusBarTotal" />
|
||||||
|
<StatusBar name="$parent_StatusBar1" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar2" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar3" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar4" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar5" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar6" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar7" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar8" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar9" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar10" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar11" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar12" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar13" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar14" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar15" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar16" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar17" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar18" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar19" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar20" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar21" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar22" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar23" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar24" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar25" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar26" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar27" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar28" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar29" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar30" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar31" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar32" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar33" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar34" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar35" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar36" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar37" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar38" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar39" inherits="DPSMate_StatusBar" />
|
||||||
|
<StatusBar name="$parent_StatusBar40" inherits="DPSMate_StatusBar" />
|
||||||
|
</Frames>
|
||||||
|
</Frame>
|
||||||
|
</ScrollChild>
|
||||||
|
</ScrollFrame>
|
||||||
|
</Frames>
|
||||||
|
</Frame>
|
||||||
|
|
||||||
|
<GameTooltip name="DPSMate_Tooltip" frameStrata="TOOLTIP" hidden="false" parent="UIParent" inherits="GameTooltipTemplate">
|
||||||
|
<Scripts>
|
||||||
|
<Onload>
|
||||||
|
this:SetOwner(WorldFrame, "ANCHOR_NONE")
|
||||||
|
</Onload>
|
||||||
|
</Scripts>
|
||||||
|
</GameTooltip>
|
||||||
|
</Ui>
|
||||||
@@ -0,0 +1,819 @@
|
|||||||
|
-- Events
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_PET_HITS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_PET_MISSES")
|
||||||
|
--DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PET_BUFF")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PET_DAMAGE")
|
||||||
|
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_SELF_HITS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_SELF_MISSES")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_SELF_DAMAGE")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE") --
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE") --
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_PARTY_HITS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PARTY_DAMAGE")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_PARTY_MISSES")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES")
|
||||||
|
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES")
|
||||||
|
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE")
|
||||||
|
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PARTY_BUFF")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS")
|
||||||
|
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_BREAK_AURA")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_SELF")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_OTHER")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_PARTY")
|
||||||
|
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLY_DEATH")
|
||||||
|
DPSMate.Parser:RegisterEvent("CHAT_MSG_COMBAT_HOSTILE_DEATH")
|
||||||
|
DPSMate.Parser:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||||
|
|
||||||
|
DPSMate.Parser:RegisterEvent("PLAYER_LOGOUT")
|
||||||
|
DPSMate.Parser:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
|
|
||||||
|
BINDING_HEADER_DPSMATE = "DPSMate"
|
||||||
|
BINDING_NAME_DPSMATE_REPORT = DPSMate.L["togglereportframe"]
|
||||||
|
BINDING_NAME_DPSMATE_TOGGLE = DPSMate.L["toggleframes"]
|
||||||
|
BINDING_NAME_DPSMATE_RESET = DPSMate.L["resetdpsmate"]
|
||||||
|
|
||||||
|
-- Global Variables
|
||||||
|
DPSMate.Parser.procs = {
|
||||||
|
-- General
|
||||||
|
["Earthstrike"] = true,
|
||||||
|
["Juju Flurry"] = true,
|
||||||
|
["Holy Strength"] = true,
|
||||||
|
["Ephemeral Power"] = true,
|
||||||
|
["Chromatic Infusion"] = true,
|
||||||
|
["Brittle Armor"] = true,
|
||||||
|
["Unstable Power"] = true,
|
||||||
|
["Zandalarian Hero Medallion"] = true,
|
||||||
|
["Ascendance"] = true,
|
||||||
|
["Essence of Sapphiron"] = true,
|
||||||
|
["Hand of Justice"] = true,
|
||||||
|
["Sword Specialization"] = true,
|
||||||
|
["Bonereaver's Edge"] = true,
|
||||||
|
|
||||||
|
--New
|
||||||
|
["Felstriker"] = true,
|
||||||
|
["Sanctuary"] = true,
|
||||||
|
["Fury of Forgewright"] = true,
|
||||||
|
["Primal Blessing"] = true,
|
||||||
|
["Spinal Reaper"] = true, -- To test
|
||||||
|
["Netherwind Focus"] = true, -- To test
|
||||||
|
["Parry"] = true, -- To test
|
||||||
|
["Untamed Fury"] = true,
|
||||||
|
["The Eye of Diminution"] = true,
|
||||||
|
["Kiss of the Spider"] = true,
|
||||||
|
["Glyph of Deflection"] = true,
|
||||||
|
["The Eye of the Dead"] = true,
|
||||||
|
["Slayer's Crest"] = true,
|
||||||
|
["Badge of the Swarmguard"] = true,
|
||||||
|
["Arcane Shroud"] = true,
|
||||||
|
["Persistent Shield"] = true,
|
||||||
|
["Jom Gabbar"] = true,
|
||||||
|
["The Burrower's Shell"] = true,
|
||||||
|
["Thrash"] = true,
|
||||||
|
["Free Action"] = true,
|
||||||
|
["Living Free Action"] = true,
|
||||||
|
["Restoration"] = true,
|
||||||
|
["Speed"] = true,
|
||||||
|
["Invulnerability"] = true,
|
||||||
|
["Aura of the Blue Dragon"] = true, -- Mana Darkmoon card
|
||||||
|
["Battle Squawk"] = true,
|
||||||
|
["Devilsaur Fury"] = true,
|
||||||
|
["Furious Howl"] = true,
|
||||||
|
["Healing Potion"] = true,
|
||||||
|
["Major Rejuvenation Potion"] = true,
|
||||||
|
["Mana Potion"] = true,
|
||||||
|
["Restore Mana"] = true,
|
||||||
|
["Dreamless Sleep"] = true,
|
||||||
|
|
||||||
|
|
||||||
|
-- Rogue
|
||||||
|
["Slice and Dice"] = true,
|
||||||
|
["Blade Flurry"] = true,
|
||||||
|
["Sprint"] = true,
|
||||||
|
["Adrenaline Rush"] = true,
|
||||||
|
["Vanish"] = true,
|
||||||
|
["Relentless Strikes Effect"] = true,
|
||||||
|
["Ruthlessness"] = true, -- To Test!!!!
|
||||||
|
["Rogue Armor Energize Effect"] = true,
|
||||||
|
["Rogue Armor Energize"] = true,
|
||||||
|
["Invigorate"] = true,
|
||||||
|
["Head Rush"] = true,
|
||||||
|
["Venomous Totem"] = true,
|
||||||
|
["Evasion"] = true,
|
||||||
|
["Restore Energy"] = true,
|
||||||
|
["Remorseless Attacks"] = true,
|
||||||
|
|
||||||
|
-- Mage
|
||||||
|
["Arcane Power"] = true,
|
||||||
|
["Combustion"] = true,
|
||||||
|
["Mind Quickening"] = true,
|
||||||
|
["Enigma Resist Bonus"] = true,
|
||||||
|
["Enigma Blizzard Bonus"] = true,
|
||||||
|
["Adaptive Warding"] = true,
|
||||||
|
["Not There"] = true,
|
||||||
|
["Cold Snap"] = true,
|
||||||
|
["Presence of Mind"] = true,
|
||||||
|
["Ice Block"] = true,
|
||||||
|
["Evocation"] = true,
|
||||||
|
|
||||||
|
-- Priest
|
||||||
|
["Power Infusion"] = true,
|
||||||
|
["Oracle Healing Bonus"] = true,
|
||||||
|
["Epiphany"] = true,
|
||||||
|
["Aegis of Preservation"] = true,
|
||||||
|
["Inspiration"] = true,
|
||||||
|
["Blessed Recovery"] = true,
|
||||||
|
["Focused Casting"] = true,
|
||||||
|
["Spirit Tap"] = true,
|
||||||
|
|
||||||
|
-- Druid
|
||||||
|
["Symbols of Unending Life Finisher Bonus"] = true,
|
||||||
|
["Metamorphosis Rune"] = true,
|
||||||
|
["Clearcasting"] = true,
|
||||||
|
["Nature's Grace"] = true,
|
||||||
|
|
||||||
|
-- Paladin
|
||||||
|
["Battlegear of Eternal Justice"] = true,
|
||||||
|
["Blinding Light"] = true,
|
||||||
|
["Divine Favor"] = true,
|
||||||
|
["Divine Shield"] = true,
|
||||||
|
["Redoubt"] = true,
|
||||||
|
["Holy Shield"] = true,
|
||||||
|
["Vengeance"] = true,
|
||||||
|
["Blessing of Freedom"] = true,
|
||||||
|
["Blessing of Sacrifice"] = true,
|
||||||
|
["Blessing of Protection"] = true,
|
||||||
|
|
||||||
|
-- Shaman
|
||||||
|
["Stormcaller's Wrath"] = true,
|
||||||
|
["Nature Aligned"] = true,
|
||||||
|
["Elemental Mastery"] = true,
|
||||||
|
["Windfury Weapon"] = true,
|
||||||
|
["Windfury Totem"] = true,
|
||||||
|
["Nature's Swiftness"] = true,
|
||||||
|
["Ancestral Healing"] = true,
|
||||||
|
["Reincarnation"] = true,
|
||||||
|
|
||||||
|
-- Warlock
|
||||||
|
["Vampirism"] = true,
|
||||||
|
["Nightfall"] = true,
|
||||||
|
["Soul Link"] = true,
|
||||||
|
["Life Tap"] = true,
|
||||||
|
|
||||||
|
-- Warrior
|
||||||
|
["Cheat Death"] = true,
|
||||||
|
["Gift of Life"] = true,
|
||||||
|
["Bloodrage"] = true,
|
||||||
|
["Flurry"] = true,
|
||||||
|
["Enrage"] = true,
|
||||||
|
["Sweeping Strikes"] = true,
|
||||||
|
["Death Wish"] = true,
|
||||||
|
["Recklessness"] = true,
|
||||||
|
["Mighty Rage"] = true,
|
||||||
|
["Great Rage"] = true,
|
||||||
|
["Rage"] = true,
|
||||||
|
["Berserker Rage"] = true,
|
||||||
|
["Shield Wall"] = true,
|
||||||
|
["Retaliation"] = true,
|
||||||
|
["Diamond Flask"] = true,
|
||||||
|
["Shield Block"] = true,
|
||||||
|
["Last Stand"] = true,
|
||||||
|
|
||||||
|
-- Hunter
|
||||||
|
["Arcane Infused"] = true,
|
||||||
|
["Quick Shots"] = true,
|
||||||
|
["Rapid Fire"] = true,
|
||||||
|
|
||||||
|
-- Boss Spells
|
||||||
|
["Lucifron's Curse"] = true,
|
||||||
|
["Gehennas' Curse"] = true,
|
||||||
|
["Panic"] = true,
|
||||||
|
["Living Bomb"] = true,
|
||||||
|
["Brood Affliction: Bronze"] = true,
|
||||||
|
["Bellowing Roar"] = true,
|
||||||
|
["Fear"] = true,
|
||||||
|
["Entangle"] = true,
|
||||||
|
["Digestive Acid"] = true,
|
||||||
|
["Locust Swarm"] = true,
|
||||||
|
["Web Wrap"] = true,
|
||||||
|
["Mutating Injection"] = true,
|
||||||
|
["Terrifying Roar"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
DPSMate.Parser.BuffExceptions = {
|
||||||
|
["Fury of Forgewright"] = true,
|
||||||
|
["Bloodfang"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
DPSMate.Parser.OtherExceptions = {
|
||||||
|
["Mighty Rage"] = true,
|
||||||
|
["Bloodrage"] = true,
|
||||||
|
["Holy Strength"] = true,
|
||||||
|
["Dreamless Sleep"] = true,
|
||||||
|
["Vampirism"] = true,
|
||||||
|
}
|
||||||
|
DPSMate.Parser.DmgProcs = {
|
||||||
|
-- General
|
||||||
|
["Life Steal"] = true,
|
||||||
|
["Thunderfury"] = true,
|
||||||
|
-- New
|
||||||
|
["Bloodfang"] = true,
|
||||||
|
["Fatal Wound"] = true,
|
||||||
|
["Decapitate"] = true,
|
||||||
|
["Gutgore Ripper"] = true,
|
||||||
|
["Firebolt"] = true,
|
||||||
|
-- Can't add Hand of Ragnaros
|
||||||
|
["Expose Weakness"] = true, -- To Test
|
||||||
|
["Silence"] = true, -- To Test
|
||||||
|
["Chilled"] = true, -- To Test
|
||||||
|
["Glimpse of Madness"] = true, -- To Test
|
||||||
|
["Engulfing Shadows"] = true, -- To Test
|
||||||
|
["Elemental Vulnerability"] = true, -- To Test
|
||||||
|
["Holy Power"] = true, -- To Test
|
||||||
|
["Revealed Flaw"] = true, -- To Test
|
||||||
|
["Totemic Power"] = true, -- To Test
|
||||||
|
["Stygian Grasp"] = true, -- To Test
|
||||||
|
["Electric Discharge"] = true, -- To Test
|
||||||
|
["Flame Lash"] = true, -- To Test
|
||||||
|
["Spell Vulnerability"] = true, -- To Test
|
||||||
|
["Lightning Strike"] = true, -- To Test
|
||||||
|
-- Deathbringer Skipped
|
||||||
|
}
|
||||||
|
DPSMate.Parser.IgnoredDmgSpells = {
|
||||||
|
}
|
||||||
|
DPSMate.Parser.TargetParty = {}
|
||||||
|
DPSMate.Parser.RCD = {
|
||||||
|
["Shield Wall"] = true,
|
||||||
|
["Recklessness"] = true,
|
||||||
|
["Retaliation"] = true,
|
||||||
|
["Last Stand"] = true,
|
||||||
|
["Innervate"] = true,
|
||||||
|
["Divine Shield"] = true,
|
||||||
|
["Blessing of Protection"] = true,
|
||||||
|
["Gift of Life"] = true,
|
||||||
|
["Redemption"] = true,
|
||||||
|
["Rebirth"] = true,
|
||||||
|
["Resurrection"] = true,
|
||||||
|
["Reincarnation"] = true,
|
||||||
|
["Ancestral Spirit"] = true,
|
||||||
|
["Soulstone Resurrection"] = true,
|
||||||
|
}
|
||||||
|
DPSMate.Parser.FailDT = {
|
||||||
|
-- Molten Core
|
||||||
|
["Rain of Fire"] = true,
|
||||||
|
["Cone of Fire"] = true,
|
||||||
|
["Lava Bomb"] = true,
|
||||||
|
["Eruption"] = true,
|
||||||
|
["Earthquake"] = true,
|
||||||
|
["Hand of Ragnaros"] = true,
|
||||||
|
["Wrath of Ragnaros"] = true,
|
||||||
|
["Conflagration"] = true,
|
||||||
|
|
||||||
|
-- Blackwing Lair
|
||||||
|
["War Stomp"] = true,
|
||||||
|
["Incinerate"] = true,
|
||||||
|
["Corrosive Acid"] = true,
|
||||||
|
["Frost Burn"] = true,
|
||||||
|
["Ignite Flesh"] = true,
|
||||||
|
["Time Lapse"] = true,
|
||||||
|
|
||||||
|
-- Zul Gurub
|
||||||
|
["Whirlwind"] = true,
|
||||||
|
["Charge"] = true,
|
||||||
|
["Poison Cloud"] = true,
|
||||||
|
|
||||||
|
-- AQ 20
|
||||||
|
["Arcane Eruption"] = true,
|
||||||
|
["Harsh Winds"] = true,
|
||||||
|
["Sand Trap"] = true,
|
||||||
|
|
||||||
|
-- AQ 40
|
||||||
|
["Toxin Cloud"] = true,
|
||||||
|
["Arcane Burst"] = true,
|
||||||
|
["Eye Beam"] = true,
|
||||||
|
["Dark Glare"] = true,
|
||||||
|
|
||||||
|
-- Naxx
|
||||||
|
["Negative Charge"] = true,
|
||||||
|
["Positive Charge"] = true,
|
||||||
|
["Void Zone"] = true,
|
||||||
|
["Plague Cloud"] = true,
|
||||||
|
["Blizzard"] = true,
|
||||||
|
["Chill"] = true,
|
||||||
|
["Frost Breath"] = true,
|
||||||
|
["Mana Detonation"] = true,
|
||||||
|
["Shadow Fissure"] = true,
|
||||||
|
|
||||||
|
}
|
||||||
|
DPSMate.Parser.FailDB = {
|
||||||
|
-- Molten Core
|
||||||
|
|
||||||
|
-- Blackwing Lair
|
||||||
|
["Suppression Aura"] = true,
|
||||||
|
["Bellowing Roar"] = true,
|
||||||
|
}
|
||||||
|
DPSMate.Parser.CC = {
|
||||||
|
["Sap"] = true,
|
||||||
|
["Gouge"] = true,
|
||||||
|
["Sleep"] = true,
|
||||||
|
["Polymorph"] = true,
|
||||||
|
["Greater Polymorph"] = true,
|
||||||
|
["Polymorph: Chicken"] = true,
|
||||||
|
["Polymorph: Cow"] = true,
|
||||||
|
["Polymorph: Pig"] = true,
|
||||||
|
["Polymorph: Sheep"] = true,
|
||||||
|
["Polymorph: Turtle"] = true,
|
||||||
|
["Blind"] = true,
|
||||||
|
["Freezing Trap Effect"] = true,
|
||||||
|
["Intimidating Shout"] = true,
|
||||||
|
["Magic Dust"] = true,
|
||||||
|
["Scatter Shot"] = true,
|
||||||
|
["Wyvern Sting"] = true,
|
||||||
|
["Seduction"] = true,
|
||||||
|
["Repentance"] = true,
|
||||||
|
["Shackle Undead"] = true,
|
||||||
|
["Reckless Charge"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
DPSMate.Parser.Dispels = {
|
||||||
|
["Remove Curse"] = true,
|
||||||
|
["Cleanse"] = true,
|
||||||
|
["Remove Lesser Curse"] = true,
|
||||||
|
["Purify"] = true,
|
||||||
|
["Dispel Magic"] = true,
|
||||||
|
["Abolish Poison"] = true,
|
||||||
|
["Abolish Disease"] = true,
|
||||||
|
["Devour Magic"] = true,
|
||||||
|
["Cure Disease"] = true,
|
||||||
|
["Poison Cleansing Totem"] = true,
|
||||||
|
["Cure Poison"] = true,
|
||||||
|
["Disease Cleansing Totem"] = true,
|
||||||
|
["Purge"] = true,
|
||||||
|
-- Potion
|
||||||
|
["Powerful Anti-Venom"] = true,
|
||||||
|
["Restoration"] = true,
|
||||||
|
["Purification"] = true,
|
||||||
|
["Purification Potion"] = true,
|
||||||
|
["Restorative Potion"] = true,
|
||||||
|
}
|
||||||
|
DPSMate.Parser.DeCurse = {
|
||||||
|
["Remove Curse"] = true,
|
||||||
|
["Remove Lesser Curse"] = true,
|
||||||
|
["Restoration"] = true,
|
||||||
|
["Purification"] = true,
|
||||||
|
}
|
||||||
|
DPSMate.Parser.DeMagic = {
|
||||||
|
["Dispel Magic"] = true,
|
||||||
|
["Devour Magic"] = true,
|
||||||
|
["Purge"] = true,
|
||||||
|
["Restoration"] = true,
|
||||||
|
}
|
||||||
|
DPSMate.Parser.DeDisease = {
|
||||||
|
["Purify"] = true,
|
||||||
|
["Abolish Disease"] = true,
|
||||||
|
["Cure Disease"] = true,
|
||||||
|
["Disease Cleansing Totem"] = true,
|
||||||
|
["Restoration"] = true,
|
||||||
|
["Purification"] = true,
|
||||||
|
}
|
||||||
|
DPSMate.Parser.DePoison = {
|
||||||
|
["Abolish Poison"] = true,
|
||||||
|
["Purify"] = true,
|
||||||
|
["Poison Cleansing Totem"] = true,
|
||||||
|
["Cure Poison"] = true,
|
||||||
|
["Powerful Anti-Venom"] = true,
|
||||||
|
["Restoration"] = true,
|
||||||
|
["Purification"] = true,
|
||||||
|
}
|
||||||
|
DPSMate.Parser.DebuffTypes = {}
|
||||||
|
DPSMate.Parser.HotDispels = {
|
||||||
|
["Abolish Poison"] = true,
|
||||||
|
["Abolish Disease"] = true,
|
||||||
|
["Restoration"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
DPSMate.Parser.Kicks = {
|
||||||
|
-- Interrupts
|
||||||
|
-- Rogue
|
||||||
|
["Kick"] = true,
|
||||||
|
-- Warrior
|
||||||
|
["Pummel"] = true,
|
||||||
|
["Shield Bash"] = true,
|
||||||
|
|
||||||
|
-- Mage
|
||||||
|
["Counterspell"] = true,
|
||||||
|
|
||||||
|
-- Shaman
|
||||||
|
["Earth Shock"] = true,
|
||||||
|
|
||||||
|
-- Priest
|
||||||
|
["Silence"] = true,
|
||||||
|
|
||||||
|
-- Stuns
|
||||||
|
-- Rogue
|
||||||
|
["Gouge"] = true,
|
||||||
|
["Kidney Shot"] = true,
|
||||||
|
["Cheap Shot"] = true,
|
||||||
|
|
||||||
|
-- Hunter
|
||||||
|
["Scatter Shot"] = true,
|
||||||
|
["Improved Concussive Shot"] = true,
|
||||||
|
["Wyvern Sting"] = true,
|
||||||
|
["Intimidation"] = true,
|
||||||
|
|
||||||
|
-- Warrior
|
||||||
|
["Charge Stun"] = true,
|
||||||
|
["Intercept Stun"] = true,
|
||||||
|
["Concussion Blow"] = true,
|
||||||
|
|
||||||
|
-- Druid
|
||||||
|
["Feral Charge"] = true,
|
||||||
|
["Feral Charge Effect"] = true,
|
||||||
|
["Bash"] = true,
|
||||||
|
["Pounce"] = true,
|
||||||
|
|
||||||
|
-- Mage
|
||||||
|
["Impact"] = true,
|
||||||
|
|
||||||
|
-- Paladin
|
||||||
|
["Repentance"] = true,
|
||||||
|
["Hammer of Justice"] = true,
|
||||||
|
|
||||||
|
-- Warlock
|
||||||
|
["Pyroclasm"] = true,
|
||||||
|
["Death Coil"] = true,
|
||||||
|
|
||||||
|
-- Priest
|
||||||
|
["Blackout"] = true,
|
||||||
|
|
||||||
|
-- General
|
||||||
|
["Tidal Charm"] = true,
|
||||||
|
["Reckless Charge"] = true,
|
||||||
|
}
|
||||||
|
DPSMate.Parser.player = UnitName("player")
|
||||||
|
DPSMate.Parser.playerclass = nil
|
||||||
|
|
||||||
|
-- Local Variables
|
||||||
|
local playerclassLoc,playerclass = UnitClass("player")
|
||||||
|
local fac = UnitFactionGroup("player")
|
||||||
|
local UL = UnitLevel
|
||||||
|
|
||||||
|
local DPSTool = {}
|
||||||
|
local DPSToolTextLeft1 = {}
|
||||||
|
local GetPlayerBuff = GetPlayerBuff
|
||||||
|
|
||||||
|
-- Begin Functions
|
||||||
|
|
||||||
|
function DPSMate.Parser:OnLoad()
|
||||||
|
self.player, self.realm = UnitName("player")
|
||||||
|
DPSMate.DB:BuildUser(self.player, strlower(playerclass))
|
||||||
|
if DPSMateUser[self.player] then
|
||||||
|
DPSMateUser[self.player][2] = strlower(playerclass)
|
||||||
|
DPSMateUser[self.player][8] = UL("player")
|
||||||
|
end
|
||||||
|
-- Prevent this addon from causing issues
|
||||||
|
if SW_FixLogStrings then
|
||||||
|
DPSMate:SendMessage("Please disable SW_StatsFixLogStrings and SW_Stats. Those addons cause issues.")
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSTool = DPSMate_Tooltip
|
||||||
|
DPSToolTextLeft1 = DPSMate_TooltipTextLeft1
|
||||||
|
|
||||||
|
if self.InitParser then
|
||||||
|
self:InitParser()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local UnitName = UnitName
|
||||||
|
function DPSMate.Parser:GetUnitByName(target)
|
||||||
|
local unit = self.TargetParty[target]
|
||||||
|
if not unit then
|
||||||
|
if target==UnitName("player") then
|
||||||
|
unit="player"
|
||||||
|
elseif target==UnitName("target") then
|
||||||
|
unit="target"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return unit
|
||||||
|
end
|
||||||
|
|
||||||
|
local UnitHealthMax = UnitHealthMax
|
||||||
|
local UnitHealth = UnitHealth
|
||||||
|
function DPSMate.Parser:GetOverhealByName(amount, target)
|
||||||
|
local result, unit = 0, self:GetUnitByName(target)
|
||||||
|
if not amount then
|
||||||
|
return 0;
|
||||||
|
end
|
||||||
|
if unit then result = amount-(UnitHealthMax(unit)-UnitHealth(unit)) end
|
||||||
|
if result<0 then return 0 else return result end
|
||||||
|
end
|
||||||
|
|
||||||
|
local UnitClass = UnitClass
|
||||||
|
local UnitName = UnitName
|
||||||
|
local GetNumPartyMembers = GetNumPartyMembers
|
||||||
|
local GetNumRaidMembers = GetNumRaidMembers
|
||||||
|
local GetRaidRosterInfo = GetRaidRosterInfo
|
||||||
|
local subGRP, PSGRP, c
|
||||||
|
function DPSMate.Parser:AssociateShaman(name, old, update)
|
||||||
|
if not subGRP or not PSGRP[name] or update then
|
||||||
|
local tnum = GetNumPartyMembers()
|
||||||
|
subGRP, PSGRP = {}, {}
|
||||||
|
if tnum <= 0 then
|
||||||
|
tnum=GetNumRaidMembers()
|
||||||
|
for i=1, tnum do
|
||||||
|
_, _, c = GetRaidRosterInfo(i)
|
||||||
|
if UnitClass("raid"..i)==DPSMate.L["shaman"] then
|
||||||
|
subGRP[c] = UnitName("raid"..i)
|
||||||
|
end
|
||||||
|
PSGRP[UnitName("raid"..i)] = c
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for i=1, tnum do
|
||||||
|
if UnitClass("party"..i)==DPSMate.L["shaman"] then
|
||||||
|
subGRP[1] = UnitName("party"..i)
|
||||||
|
end
|
||||||
|
PSGRP[UnitName("party"..i)] = 1
|
||||||
|
end
|
||||||
|
PSGRP[name] = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if PSGRP[name] and subGRP[PSGRP[name]] then
|
||||||
|
return subGRP[PSGRP[name]]
|
||||||
|
end
|
||||||
|
return old
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Qualify a pet/totem source name with its owner for disambiguation.
|
||||||
|
-- When _petOwner is set (PET_ events), use the player as owner.
|
||||||
|
-- Otherwise, look up the petToOwnerMap for single-owner pets.
|
||||||
|
function DPSMate.Parser:QualifyPetSource(source)
|
||||||
|
if self._petOwner then
|
||||||
|
return source .. " (" .. self._petOwner .. ")"
|
||||||
|
end
|
||||||
|
if self.petToOwnerMap and self.petToOwnerMap[source] then
|
||||||
|
local count, singleOwner = 0, nil
|
||||||
|
for o, _ in pairs(self.petToOwnerMap[source]) do
|
||||||
|
count = count + 1
|
||||||
|
singleOwner = o
|
||||||
|
end
|
||||||
|
if count == 1 then
|
||||||
|
return source .. " (" .. singleOwner .. ")"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return source
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The totem aura just reports a removed event in the chat.
|
||||||
|
-- Maybe we can guess here?
|
||||||
|
local UnitDebuff = UnitDebuff
|
||||||
|
DPSMate.Parser.PLAYER_AURAS_CHANGED = function(unit)
|
||||||
|
local aura, debuffDispelType
|
||||||
|
if DPSTool.SetPlayerBuff then
|
||||||
|
for i=1, 4 do
|
||||||
|
DPSTool:SetPlayerBuff(GetPlayerBuff(i, "HARMFUL"))
|
||||||
|
aura = DPSToolTextLeft1:GetText()
|
||||||
|
DPSTool:Hide()
|
||||||
|
if not aura then break end
|
||||||
|
_, _, debuffDispelType = UnitDebuff("player", i);
|
||||||
|
if debuffDispelType and DPSMateAbility[aura] then
|
||||||
|
DPSMateAbility[aura][2] = debuffDispelType
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_HOSTILE_DEATH = function(arg1)
|
||||||
|
this:CombatHostileDeaths(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_FRIENDLY_DEATH = function(arg1)
|
||||||
|
this:CombatFriendlyDeath(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_BREAK_AURA = function(arg1)
|
||||||
|
this:SpellBreakAura(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_AURA_GONE_PARTY = function(arg1)
|
||||||
|
this:SpellAuraGoneParty(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_AURA_GONE_OTHER = function(arg1)
|
||||||
|
this:SpellAuraGoneOther(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_AURA_GONE_SELF = function(arg1)
|
||||||
|
this:SpellAuraGoneSelf(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS = function(arg1)
|
||||||
|
this:SpellPeriodicFriendlyPlayerBuffs(arg1)
|
||||||
|
this:SpellPeriodicFriendlyPlayerBuffsAbsorb(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PARTY_BUFF = function(arg1)
|
||||||
|
this:SpellHostilePlayerBuff(arg1)
|
||||||
|
this:SpellHostilePlayerBuffDispels(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS = function(arg1)
|
||||||
|
this:SpellPeriodicFriendlyPlayerBuffs(arg1)
|
||||||
|
this:SpellPeriodicFriendlyPlayerBuffsAbsorb(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF = function(arg1)
|
||||||
|
this:SpellHostilePlayerBuff(arg1)
|
||||||
|
this:SpellHostilePlayerBuffDispels(arg1)
|
||||||
|
this:HostilePlayerSpellDamageInterrupts(arg1)
|
||||||
|
this:SpellPeriodicFriendlyPlayerBuffsAbsorb(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS = function(arg1)
|
||||||
|
this:SpellPeriodicFriendlyPlayerBuffs(arg1)
|
||||||
|
this:SpellPeriodicFriendlyPlayerBuffsAbsorb(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF = function(arg1)
|
||||||
|
this:SpellHostilePlayerBuff(arg1)
|
||||||
|
this:SpellHostilePlayerBuffDispels(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS = function(arg1)
|
||||||
|
this:SpellPeriodicSelfBuff(arg1)
|
||||||
|
this:SpellPeriodicSelfBuffAbsorb(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_SELF_BUFF = function(arg1)
|
||||||
|
this:SpellSelfBuff(arg1)
|
||||||
|
this:SpellSelfBuffDispels(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE = function(arg1)
|
||||||
|
this:SpellPeriodicDamageTaken(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE = function(arg1)
|
||||||
|
this:CreatureVsCreatureSpellDamage(arg1)
|
||||||
|
this:CreatureVsCreatureSpellDamageAbsorb(arg1)
|
||||||
|
this:CreatureVsCreatureSpellDamageInterrupts(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES = function(arg1)
|
||||||
|
this:CreatureVsCreatureMisses(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS = function(arg1)
|
||||||
|
this:CreatureVsCreatureHits(arg1)
|
||||||
|
this:CreatureVsCreatureHitsAbsorb(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE = function(arg1)
|
||||||
|
this:CreatureVsCreatureSpellDamage(arg1)
|
||||||
|
this:CreatureVsCreatureSpellDamageAbsorb(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE = function(arg1)
|
||||||
|
this:SpellPeriodicDamageTaken(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES = function(arg1)
|
||||||
|
this:CreatureVsCreatureMisses(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS = function(arg1)
|
||||||
|
this:CreatureVsCreatureHits(arg1)
|
||||||
|
this:CreatureVsCreatureHitsAbsorb(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE = function(arg1)
|
||||||
|
this:PeriodicSelfDamage(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE = function(arg1)
|
||||||
|
this:CreatureVsSelfSpellDamage(arg1)
|
||||||
|
this:CreatureVsSelfSpellDamageAbsorb(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES = function(arg1)
|
||||||
|
this:CreatureVsSelfMisses(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS = function(arg1)
|
||||||
|
this:CreatureVsSelfHits(arg1)
|
||||||
|
this:CreatureVsSelfHitsAbsorb(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS = function(arg1)
|
||||||
|
this:SpellDamageShieldsOnOthers(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF = function(arg1)
|
||||||
|
this:SpellDamageShieldsOnSelf(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES = function(arg1)
|
||||||
|
this:FriendlyPlayerMisses(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES = function(arg1)
|
||||||
|
this:FriendlyPlayerMisses(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS = function(arg1)
|
||||||
|
this:FriendlyPlayerHits(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS = function(arg1)
|
||||||
|
this:FriendlyPlayerHits(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE = function(arg1)
|
||||||
|
this:FriendlyPlayerDamage(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PARTY_DAMAGE = function(arg1)
|
||||||
|
this:FriendlyPlayerDamage(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_PARTY_MISSES = function(arg1)
|
||||||
|
this:FriendlyPlayerMisses(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_PARTY_HITS = function(arg1)
|
||||||
|
this:FriendlyPlayerHits(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE = function(arg1)
|
||||||
|
this:PeriodicDamage(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE = function(arg1)
|
||||||
|
this:FriendlyPlayerDamage(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE = function(arg1)
|
||||||
|
this:PeriodicDamage(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_SELF_DAMAGE = function(arg1)
|
||||||
|
this:SelfSpellDMG(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_SELF_MISSES = function(arg1)
|
||||||
|
this:SelfMisses(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_SELF_HITS = function(arg1)
|
||||||
|
this:SelfHits(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_PET_HITS = function(arg1)
|
||||||
|
this:PetHits(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_COMBAT_PET_MISSES = function(arg1)
|
||||||
|
this:PetMisses(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser.CHAT_MSG_SPELL_PET_DAMAGE = function(arg1)
|
||||||
|
this:PetSpellDamage(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.Parser:SetScript("OnEvent", function()
|
||||||
|
if this[event] then
|
||||||
|
local msg = arg1
|
||||||
|
if msg and strfind(event, "CHAT_MSG_", 1, true) and not strfind(msg, " 's ", 1, true) and strfind(msg, "'s ", 1, true) then
|
||||||
|
msg = string.gsub(msg, "'s ", " 's ", 1)
|
||||||
|
end
|
||||||
|
this[event](msg)
|
||||||
|
end
|
||||||
|
end)
|
||||||
@@ -0,0 +1,301 @@
|
|||||||
|
-- Global Variables
|
||||||
|
DPSMate.Modules.DPS = {}
|
||||||
|
DPSMate.Modules.DPS.Hist = "DMGDone"
|
||||||
|
DPSMate.Options.Options[1]["args"]["dps"] = {
|
||||||
|
order = 10,
|
||||||
|
type = 'toggle',
|
||||||
|
name = DPSMate.L["dps"],
|
||||||
|
desc = DPSMate.L["show"].." "..DPSMate.L["dps"]..".",
|
||||||
|
get = function() return DPSMateSettings["windows"][DPSMate.Options.Dewdrop:GetOpenedParent().Key]["options"][1]["dps"] end, -- Addons might conflicting here with dewdrop
|
||||||
|
set = function() DPSMate.Options:ToggleDrewDrop(1, "dps", DPSMate.Options.Dewdrop:GetOpenedParent()) end,
|
||||||
|
}
|
||||||
|
DPSMate.Modules.DPS.Events = {
|
||||||
|
"CHAT_MSG_COMBAT_SELF_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_SELF_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_PARTY_HITS",
|
||||||
|
"CHAT_MSG_SPELL_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_PARTY_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
|
||||||
|
-- Pet Damage
|
||||||
|
"CHAT_MSG_COMBAT_PET_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_PET_MISSES",
|
||||||
|
--"CHAT_MSG_SPELL_PET_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PET_DAMAGE",
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Register the moodule
|
||||||
|
DPSMate:Register("dps", DPSMate.Modules.DPS, DPSMate.L["dps"])
|
||||||
|
|
||||||
|
local tinsert = table.insert
|
||||||
|
local strformat = string.format
|
||||||
|
|
||||||
|
function DPSMate.Modules.DPS:GetSortedTable(arr,k)
|
||||||
|
local b, a, total = {}, {}, 0
|
||||||
|
if arr then
|
||||||
|
local petsByOwner = DPSMateSettings["mergepets"] and DPSMate:GetPetsByOwner(arr) or {}
|
||||||
|
local processedOwners = {}
|
||||||
|
for cat, val in pairs(arr) do
|
||||||
|
local name = DPSMate:GetUserById(cat)
|
||||||
|
if not name or not DPSMateUser[name] then
|
||||||
|
-- skip unknown users
|
||||||
|
elseif (not DPSMateUser[name][4] or (DPSMateUser[name][4] and not DPSMateSettings["mergepets"])) then
|
||||||
|
if DPSMate:ApplyFilter(k, name) then
|
||||||
|
local CV = val["i"]
|
||||||
|
if DPSMateSettings["mergepets"] and petsByOwner[cat] then
|
||||||
|
processedOwners[cat] = true
|
||||||
|
for _, petCat in pairs(petsByOwner[cat]) do
|
||||||
|
if arr[petCat] then
|
||||||
|
CV = CV + arr[petCat]["i"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local i = 1
|
||||||
|
while true do
|
||||||
|
if (not b[i]) then
|
||||||
|
tinsert(b, i, CV)
|
||||||
|
tinsert(a, i, name)
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if b[i] < CV then
|
||||||
|
tinsert(b, i, CV)
|
||||||
|
tinsert(a, i, name)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
total = total + CV
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Handle owners with no personal damage but with pets that have damage
|
||||||
|
if DPSMateSettings["mergepets"] then
|
||||||
|
for oid, petList in pairs(petsByOwner) do
|
||||||
|
if not processedOwners[oid] and not arr[oid] then
|
||||||
|
local name = DPSMate:GetUserById(oid)
|
||||||
|
if name and DPSMateUser[name] and not DPSMateUser[name][4] and DPSMate:ApplyFilter(k, name) then
|
||||||
|
local CV = 0
|
||||||
|
for _, petCat in pairs(petList) do
|
||||||
|
if arr[petCat] then
|
||||||
|
CV = CV + arr[petCat]["i"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if CV > 0 then
|
||||||
|
local i = 1
|
||||||
|
while true do
|
||||||
|
if (not b[i]) then
|
||||||
|
tinsert(b, i, CV)
|
||||||
|
tinsert(a, i, name)
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if b[i] < CV then
|
||||||
|
tinsert(b, i, CV)
|
||||||
|
tinsert(a, i, name)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
total = total + CV
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return b, total, a
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DPS:EvalTable(user, k, cbt)
|
||||||
|
if not user then return end
|
||||||
|
local a, u, p, d, total, pet = {}, {}, {}, {}, 0, false
|
||||||
|
local arr, cbet = DPSMate:GetMode(k)
|
||||||
|
cbt = cbt or cbet
|
||||||
|
if not cbt or cbt <= 0 then cbt = 1 end
|
||||||
|
u = {user[1]}
|
||||||
|
if DPSMateSettings["mergepets"] then
|
||||||
|
local petsByOwner = DPSMate:GetPetsByOwner(arr)
|
||||||
|
if petsByOwner[user[1]] then
|
||||||
|
for _, petCat in pairs(petsByOwner[user[1]]) do
|
||||||
|
tinsert(u, petCat)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not arr[user[1]] and getn(u) <= 1 then return end
|
||||||
|
for _, v in pairs(u) do
|
||||||
|
if arr[v] then
|
||||||
|
for cat, val in pairs(arr[v]) do
|
||||||
|
if (type(val) == "table" and cat~="i") then
|
||||||
|
if val[13] and val[13]~=0 and cat~="" then
|
||||||
|
local vname = DPSMate:GetUserById(v)
|
||||||
|
if vname and DPSMateUser[vname] and DPSMateUser[vname][4] then pet=vname; else pet=false; end
|
||||||
|
local i = 1
|
||||||
|
while true do
|
||||||
|
if (not d[i]) then
|
||||||
|
tinsert(a, i, cat)
|
||||||
|
tinsert(d, i, {val[13]/cbt, pet})
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if (d[i][1] < val[13]/cbt) then
|
||||||
|
tinsert(a, i, cat)
|
||||||
|
tinsert(d, i, {val[13]/cbt, pet})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
total=total+(arr[v]["i"] or 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return a, total/(cbt or 1), d
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DPS:GetSettingValues(arr, cbt, k, ecbt)
|
||||||
|
local pt = ""
|
||||||
|
local name, value, perc, sortedTable, total, a, p, strt = {}, {}, {}, {}, 0, 0, "", {[1]="",[2]=""}
|
||||||
|
if DPSMateSettings["windows"][k]["numberformat"] == 2 or DPSMateSettings["windows"][k]["numberformat"] == 4 then p = "K"; pt = "K" end
|
||||||
|
sortedTable, total, a = DPSMate.Modules.DPS:GetSortedTable(arr,k)
|
||||||
|
local validCbt = cbt and cbt > 0.001
|
||||||
|
for cat, val in pairs(sortedTable) do
|
||||||
|
local dmg, tot, sort, dmgr, totr, sortr = DPSMate:FormatNumbers(val, total, sortedTable[1], k)
|
||||||
|
if dmgr==0 then break end; if totr <= 10000 then pt = "" end; if dmgr<=10000 then p = "" end
|
||||||
|
local str = {[1]="",[2]="",[3]="",[4]=""}
|
||||||
|
local pname = a[cat]
|
||||||
|
if DPSMateSettings["columnsdps"][1] then str[1] = "("..DPSMate:Commas(dmg, k)..p..")"; strt[1] = "("..DPSMate:Commas(tot, k)..pt..")" end
|
||||||
|
if DPSMateSettings["columnsdps"][2] and validCbt then str[2] = " "..strformat("%.1f", (dmg/cbt))..p; strt[2] = " "..strformat("%.1f", (tot/cbt))..pt end
|
||||||
|
if DPSMateSettings["columnsdps"][3] then str[3] = " ("..strformat("%.1f", 100*dmgr/totr).."%)" end
|
||||||
|
if DPSMateSettings["columnsdps"][4] then local ev = ecbt[pname] or cbt; if ev and ev > 0.001 then str[4] = " ("..strformat("%.1f", (dmg/ev))..p..")" end end
|
||||||
|
tinsert(name, a[cat])
|
||||||
|
tinsert(value, str[1]..str[2]..str[4]..str[3])
|
||||||
|
tinsert(perc, 100*(dmgr/sortr))
|
||||||
|
end
|
||||||
|
return name, value, perc, strt
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DPS:ShowTooltip(user,k)
|
||||||
|
if DPSMateSettings["informativetooltips"] then
|
||||||
|
if not DPSMateUser[user] then return end
|
||||||
|
local a,b,c = DPSMate.Modules.DPS:EvalTable(DPSMateUser[user], k)
|
||||||
|
local db, cbt = DPSMate:GetModeByArr(DPSMateEDT, k, "EDTaken")
|
||||||
|
local i, p = 1, 0
|
||||||
|
local pet = 0
|
||||||
|
local edtaken, edtakenPet = {}, {}
|
||||||
|
|
||||||
|
-- Find all pet IDs for this owner
|
||||||
|
local ownerId = DPSMateUser[user][1]
|
||||||
|
local petIds = {}
|
||||||
|
local petNames = {}
|
||||||
|
for pname, pdata in pairs(DPSMateUser) do
|
||||||
|
if pdata[4] and pdata[6] == ownerId then
|
||||||
|
tinsert(petIds, pdata[1])
|
||||||
|
tinsert(petNames, pname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Getting the value of the pet
|
||||||
|
while a and a[i] do
|
||||||
|
if c[i][2] then
|
||||||
|
pet = pet + c[i][1]
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Getting edt values
|
||||||
|
for cat, val in pairs(db) do
|
||||||
|
if val[ownerId] and val[ownerId]["i"] then
|
||||||
|
if val[ownerId]["i"]>0 then
|
||||||
|
i = 1
|
||||||
|
while true do
|
||||||
|
if (not edtaken[i]) then
|
||||||
|
tinsert(edtaken, i, {cat, val[ownerId]["i"]})
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if (edtaken[i][2] < val[ownerId]["i"]) then
|
||||||
|
tinsert(edtaken, i, {cat, val[ownerId]["i"]})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Aggregate EDT from all pets for this enemy
|
||||||
|
local petTotal = 0
|
||||||
|
for _, pid in pairs(petIds) do
|
||||||
|
if val[pid] and val[pid]["i"] > 0 then
|
||||||
|
petTotal = petTotal + val[pid]["i"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if petTotal > 0 then
|
||||||
|
i = 1
|
||||||
|
while true do
|
||||||
|
if (not edtakenPet[i]) then
|
||||||
|
tinsert(edtakenPet, i, {cat, petTotal})
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if (edtakenPet[i][2] < petTotal) then
|
||||||
|
tinsert(edtakenPet, i, {cat, petTotal})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttdamage"]..DPSMate.L["ttabilities"])
|
||||||
|
for i=1, DPSMateSettings["subviewrows"] do
|
||||||
|
if not a[i] then break end
|
||||||
|
if not c[i][2] then
|
||||||
|
local div = (b-pet) ~= 0 and (b-pet) or 1
|
||||||
|
GameTooltip:AddDoubleLine(i..". "..DPSMate:GetAbilityById(a[i]),strformat("%.2f", c[i][1]).." ("..strformat("%.2f", 100*c[i][1]/div).."%)",1,1,1,1,1,1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttattacked"])
|
||||||
|
for i=1, DPSMateSettings["subviewrows"] do
|
||||||
|
if not edtaken[i] then break end
|
||||||
|
local ediv = (b-pet) ~= 0 and (b-pet) or 1
|
||||||
|
GameTooltip:AddDoubleLine(i..". "..DPSMate:GetUserById(edtaken[i][1]), strformat("%.2f", edtaken[i][2]/cbt).." ("..strformat("%.2f", (100*edtaken[i][2]/cbt)/ediv).."%)", 1,1,1,1,1,1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if pet~=0 and getn(petIds) > 0 then
|
||||||
|
local petDisplay = table.concat(petNames, ", ")
|
||||||
|
GameTooltip:AddLine(" ")
|
||||||
|
GameTooltip:AddDoubleLine(DPSMate.L["ttpet2"],petDisplay.."<"..user.."> ("..strformat("%.2f", 100*pet/b).."%)",1,0.82,0,1,1,1)
|
||||||
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttpet"]..DPSMate.L["ttdamage"]..DPSMate.L["ttabilities"])
|
||||||
|
i, p = 1,1
|
||||||
|
while DPSMateSettings["subviewrows"]>=p do
|
||||||
|
if not a[i] then break end
|
||||||
|
if c[i][2] then
|
||||||
|
GameTooltip:AddDoubleLine(p..". "..DPSMate:GetAbilityById(a[i]),strformat("%.2f", c[i][1]).." ("..strformat("%.2f", 100*c[i][1]/pet).."%)",1,1,1,1,1,1)
|
||||||
|
p = p + 1
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttpet"]..DPSMate.L["ttattacked"])
|
||||||
|
for i=1, DPSMateSettings["subviewrows"] do
|
||||||
|
if not edtakenPet[i] then break end
|
||||||
|
GameTooltip:AddDoubleLine(i..". "..DPSMate:GetUserById(edtakenPet[i][1]), strformat("%.2f", edtakenPet[i][2]/cbt).." ("..strformat("%.2f", (100*edtakenPet[i][2]/cbt)/pet).."%)", 1,1,1,1,1,1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DPS:OpenDetails(obj, key, bool)
|
||||||
|
if bool then
|
||||||
|
DPSMate.Modules.DetailsDamage:UpdateCompare(obj, key, bool)
|
||||||
|
else
|
||||||
|
DPSMate.Modules.DetailsDamage:UpdateDetails(obj, key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DPS:OpenTotalDetails(obj, key)
|
||||||
|
DPSMate.Modules.DetailsDamageTotal:UpdateDetails(obj, key)
|
||||||
|
end
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
-- Global Variables
|
||||||
|
DPSMate.Modules.Damage = {}
|
||||||
|
DPSMate.Modules.Damage.Hist = "DMGDone"
|
||||||
|
DPSMate.Options.Options[1]["args"]["damage"] = {
|
||||||
|
order = 20,
|
||||||
|
type = 'toggle',
|
||||||
|
name = DPSMate.L["damage"],
|
||||||
|
desc = DPSMate.L["show"].." "..DPSMate.L["damage"]..".",
|
||||||
|
get = function() return DPSMateSettings["windows"][DPSMate.Options.Dewdrop:GetOpenedParent().Key]["options"][1]["damage"] end,
|
||||||
|
set = function() DPSMate.Options:ToggleDrewDrop(1, "damage", DPSMate.Options.Dewdrop:GetOpenedParent()) end,
|
||||||
|
}
|
||||||
|
DPSMate.Modules.Damage.Events = {
|
||||||
|
"CHAT_MSG_COMBAT_SELF_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_SELF_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_PARTY_HITS",
|
||||||
|
"CHAT_MSG_SPELL_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_PARTY_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
|
||||||
|
"CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
|
||||||
|
-- Pet Damage
|
||||||
|
"CHAT_MSG_COMBAT_PET_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_PET_MISSES",
|
||||||
|
--"CHAT_MSG_SPELL_PET_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PET_DAMAGE",
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Register the moodule
|
||||||
|
DPSMate:Register("damage", DPSMate.Modules.Damage, DPSMate.L["damage"])
|
||||||
|
|
||||||
|
local tinsert = table.insert
|
||||||
|
local strformat = string.format
|
||||||
|
local pairs = pairs
|
||||||
|
|
||||||
|
function DPSMate.Modules.Damage:GetSortedTable(arr, k)
|
||||||
|
local b, a, total, CV, i, name = {}, {}, 0
|
||||||
|
local petsByOwner = DPSMateSettings["mergepets"] and DPSMate:GetPetsByOwner(arr) or {}
|
||||||
|
local processedOwners = {}
|
||||||
|
for cat, val in pairs(arr) do
|
||||||
|
name = DPSMate:GetUserById(cat)
|
||||||
|
if not name or not DPSMateUser[name] then
|
||||||
|
-- skip unknown users
|
||||||
|
elseif (not DPSMateUser[name][4] or (DPSMateUser[name][4] and not DPSMateSettings["mergepets"])) then
|
||||||
|
if DPSMate:ApplyFilter(k, name) then
|
||||||
|
CV = val["i"] or 0
|
||||||
|
if DPSMateSettings["mergepets"] and petsByOwner[cat] then
|
||||||
|
processedOwners[cat] = true
|
||||||
|
for _, petCat in pairs(petsByOwner[cat]) do
|
||||||
|
if arr[petCat] then
|
||||||
|
CV = CV + (arr[petCat]["i"] or 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i = 1
|
||||||
|
while true do
|
||||||
|
if (not b[i]) then
|
||||||
|
tinsert(b, i, CV)
|
||||||
|
tinsert(a, i, name)
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if b[i] < CV then
|
||||||
|
tinsert(b, i, CV)
|
||||||
|
tinsert(a, i, name)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
total = total + CV
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Handle owners with no personal damage but with pets that have damage
|
||||||
|
if DPSMateSettings["mergepets"] then
|
||||||
|
for oid, petList in pairs(petsByOwner) do
|
||||||
|
if not processedOwners[oid] and not arr[oid] then
|
||||||
|
name = DPSMate:GetUserById(oid)
|
||||||
|
if name and DPSMateUser[name] and not DPSMateUser[name][4] and DPSMate:ApplyFilter(k, name) then
|
||||||
|
CV = 0
|
||||||
|
for _, petCat in pairs(petList) do
|
||||||
|
if arr[petCat] then
|
||||||
|
CV = CV + (arr[petCat]["i"] or 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if CV > 0 then
|
||||||
|
i = 1
|
||||||
|
while true do
|
||||||
|
if (not b[i]) then
|
||||||
|
tinsert(b, i, CV)
|
||||||
|
tinsert(a, i, name)
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if b[i] < CV then
|
||||||
|
tinsert(b, i, CV)
|
||||||
|
tinsert(a, i, name)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
total = total + CV
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return b, total, a
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.Damage:EvalTable(user, k)
|
||||||
|
if not user then return end
|
||||||
|
local a, u, p, d, total, pet = {}, {}, {}, {}, 0, false
|
||||||
|
local arr = DPSMate:GetMode(k)
|
||||||
|
u = {user[1]}
|
||||||
|
if DPSMateSettings["mergepets"] then
|
||||||
|
local petsByOwner = DPSMate:GetPetsByOwner(arr)
|
||||||
|
if petsByOwner[user[1]] then
|
||||||
|
for _, petCat in pairs(petsByOwner[user[1]]) do
|
||||||
|
tinsert(u, petCat)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not arr[user[1]] and getn(u) <= 1 then return end
|
||||||
|
for _, v in pairs(u) do
|
||||||
|
if arr[v] then
|
||||||
|
for cat, val in pairs(arr[v]) do
|
||||||
|
if (type(val) == "table" and cat~="i") then
|
||||||
|
if val[13] and val[13]~=0 and cat~="" then
|
||||||
|
local vname = DPSMate:GetUserById(v)
|
||||||
|
if vname and DPSMateUser[vname] and DPSMateUser[vname][4] then pet=vname; else pet=false; end
|
||||||
|
local i = 1
|
||||||
|
while true do
|
||||||
|
if (not d[i]) then
|
||||||
|
tinsert(a, i, cat)
|
||||||
|
tinsert(d, i, {val[13], pet})
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if (d[i][1] < val[13]) then
|
||||||
|
tinsert(a, i, cat)
|
||||||
|
tinsert(d, i, {val[13], pet})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
total=total+(arr[v]["i"] or 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return a, total, d
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.Damage:GetSettingValues(arr, cbt, k,ecbt)
|
||||||
|
local pt = ""
|
||||||
|
local name, value, perc, sortedTable, total, a, p, strt = {}, {}, {}, {}, 0, 0, "", {[1]="",[2]=""}
|
||||||
|
if DPSMateSettings["windows"][k]["numberformat"] == 2 or DPSMateSettings["windows"][k]["numberformat"] == 4 then p = "K"; pt = "K" end
|
||||||
|
sortedTable, total, a = DPSMate.Modules.Damage:GetSortedTable(arr, k)
|
||||||
|
local validCbt = cbt and cbt > 0.001
|
||||||
|
for cat, val in pairs(sortedTable) do
|
||||||
|
local dmg, tot, sort, dmgr, totr, sortr = DPSMate:FormatNumbers(val, total, sortedTable[1], k)
|
||||||
|
if dmgr==0 then break end; if totr <= 10000 then pt = "" end; if dmgr<=10000 then p = "" end
|
||||||
|
local str = {[1]="",[2]="",[3]="",[4]=""}
|
||||||
|
local pname = a[cat]
|
||||||
|
if DPSMateSettings["columnsdmg"][1] then str[1] = " "..DPSMate:Commas(dmg, k)..p; strt[2] = DPSMate:Commas(tot, k)..pt end
|
||||||
|
if DPSMateSettings["columnsdmg"][2] and validCbt then str[2] = "("..strformat("%.1f", (dmg/cbt))..p..")"; strt[1] = "("..strformat("%.1f", (tot/cbt))..pt..") " end
|
||||||
|
if DPSMateSettings["columnsdmg"][3] then str[3] = " ("..strformat("%.1f", 100*dmgr/totr).."%)" end
|
||||||
|
if DPSMateSettings["columnsdmg"][4] then local ev = (type(ecbt)=="table" and ecbt[pname]) or cbt; if ev and ev > 0.001 then str[4] = " ("..strformat("%.1f", dmg/ev)..p..")" end end
|
||||||
|
tinsert(name, a[cat])
|
||||||
|
tinsert(value, str[2]..str[1]..str[4]..str[3])
|
||||||
|
tinsert(perc, 100*(dmgr/sortr))
|
||||||
|
end
|
||||||
|
return name, value, perc, strt
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.Damage:ShowTooltip(user,k)
|
||||||
|
if DPSMateSettings["informativetooltips"] then
|
||||||
|
if not DPSMateUser[user] then return end
|
||||||
|
local a,b,c = DPSMate.Modules.Damage:EvalTable(DPSMateUser[user], k)
|
||||||
|
local db = DPSMate:GetModeByArr(DPSMateEDT, k, "EDTaken")
|
||||||
|
local i, p = 1, 0
|
||||||
|
local pet = 0
|
||||||
|
local edtaken, edtakenPet = {}, {}
|
||||||
|
|
||||||
|
-- Find all pet IDs for this owner
|
||||||
|
local ownerId = DPSMateUser[user][1]
|
||||||
|
local petIds = {}
|
||||||
|
local petNames = {}
|
||||||
|
for pname, pdata in pairs(DPSMateUser) do
|
||||||
|
if pdata[4] and pdata[6] == ownerId then
|
||||||
|
tinsert(petIds, pdata[1])
|
||||||
|
tinsert(petNames, pname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Getting the value of the pet
|
||||||
|
while a and a[i] do
|
||||||
|
if c[i][2] then
|
||||||
|
pet = pet + c[i][1]
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Getting edt values
|
||||||
|
for cat, val in pairs(db) do
|
||||||
|
if val[ownerId] then
|
||||||
|
if val[ownerId]["i"] and val[ownerId]["i"]>0 then
|
||||||
|
i = 1
|
||||||
|
while true do
|
||||||
|
if (not edtaken[i]) then
|
||||||
|
tinsert(edtaken, i, {cat, val[ownerId]["i"]})
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if (edtaken[i][2] < val[ownerId]["i"]) then
|
||||||
|
tinsert(edtaken, i, {cat, val[ownerId]["i"]})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Aggregate EDT from all pets for this enemy
|
||||||
|
local petTotal = 0
|
||||||
|
for _, pid in pairs(petIds) do
|
||||||
|
if val[pid] and (val[pid]["i"] or 0) > 0 then
|
||||||
|
petTotal = petTotal + (val[pid]["i"] or 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if petTotal > 0 then
|
||||||
|
i = 1
|
||||||
|
while true do
|
||||||
|
if (not edtakenPet[i]) then
|
||||||
|
tinsert(edtakenPet, i, {cat, petTotal})
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if (edtakenPet[i][2] < petTotal) then
|
||||||
|
tinsert(edtakenPet, i, {cat, petTotal})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttdamage"]..DPSMate.L["ttabilities"])
|
||||||
|
for i=1, DPSMateSettings["subviewrows"] do
|
||||||
|
if not a[i] then break end
|
||||||
|
if not c[i][2] then
|
||||||
|
local div = (b-pet) ~= 0 and (b-pet) or 1
|
||||||
|
GameTooltip:AddDoubleLine(i..". "..DPSMate:GetAbilityById(a[i]),c[i][1].." ("..strformat("%.2f", 100*c[i][1]/div).."%)",1,1,1,1,1,1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttattacked"])
|
||||||
|
for i=1, DPSMateSettings["subviewrows"] do
|
||||||
|
if not edtaken[i] then break end
|
||||||
|
local ediv = (b-pet) ~= 0 and (b-pet) or 1
|
||||||
|
GameTooltip:AddDoubleLine(i..". "..DPSMate:GetUserById(edtaken[i][1]), edtaken[i][2].." ("..strformat("%.2f", 100*edtaken[i][2]/ediv).."%)", 1,1,1,1,1,1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if pet~=0 and getn(petIds) > 0 then
|
||||||
|
local petDisplay = table.concat(petNames, ", ")
|
||||||
|
GameTooltip:AddLine(" ")
|
||||||
|
GameTooltip:AddDoubleLine(DPSMate.L["ttpet2"],petDisplay.."<"..user.."> ("..strformat("%.2f", 100*pet/b).."%)",1,0.82,0,1,1,1)
|
||||||
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttpet"]..DPSMate.L["ttdamage"]..DPSMate.L["ttabilities"])
|
||||||
|
i, p = 1,1
|
||||||
|
while DPSMateSettings["subviewrows"]>=p do
|
||||||
|
if not a[i] then break end
|
||||||
|
if c[i][2] then
|
||||||
|
GameTooltip:AddDoubleLine(p..". "..DPSMate:GetAbilityById(a[i]),c[i][1].." ("..strformat("%.2f", 100*c[i][1]/pet).."%)",1,1,1,1,1,1)
|
||||||
|
p = p + 1
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttpet"]..DPSMate.L["ttattacked"])
|
||||||
|
for i=1, DPSMateSettings["subviewrows"] do
|
||||||
|
if not edtakenPet[i] then break end
|
||||||
|
GameTooltip:AddDoubleLine(i..". "..DPSMate:GetUserById(edtakenPet[i][1]), edtakenPet[i][2].." ("..strformat("%.2f", 100*edtakenPet[i][2]/pet).."%)", 1,1,1,1,1,1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.Damage:OpenDetails(obj, key, bool)
|
||||||
|
if bool then
|
||||||
|
DPSMate.Modules.DetailsDamage:UpdateCompare(obj, key, bool)
|
||||||
|
else
|
||||||
|
DPSMate.Modules.DetailsDamage:UpdateDetails(obj, key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.Damage:OpenTotalDetails(obj, key)
|
||||||
|
DPSMate.Modules.DetailsDamageTotal:UpdateDetails(obj, key)
|
||||||
|
end
|
||||||
@@ -0,0 +1,494 @@
|
|||||||
|
DPSMate.Modules.DetailsDamageTotal = {}
|
||||||
|
|
||||||
|
local g, g2 = nil,nil
|
||||||
|
local curKey = 1
|
||||||
|
local db, cbt = {}, 0
|
||||||
|
local buttons = {}
|
||||||
|
local ColorTable={}
|
||||||
|
local _G = getglobal
|
||||||
|
local tinsert = table.insert
|
||||||
|
local tremove = table.remove
|
||||||
|
local strformat = string.format
|
||||||
|
local toggle = false
|
||||||
|
local totSumTable = {}
|
||||||
|
local totMax = 0
|
||||||
|
local totTime = 0
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:UpdateDetails(obj, key)
|
||||||
|
curKey = key
|
||||||
|
db, cbt = DPSMate:GetMode(key)
|
||||||
|
buttons = {}
|
||||||
|
ColorTable={
|
||||||
|
{0.95,0.90,0.5},
|
||||||
|
{0.0,0.9,0.0},
|
||||||
|
{0.0,0.0,1.0},
|
||||||
|
{1.0,1.0,0.0},
|
||||||
|
{1.0,0.0,1.0},
|
||||||
|
{0.0,1.0,1.0},
|
||||||
|
{1.0,1.0,1.0},
|
||||||
|
{0.5,0.0,0.0},
|
||||||
|
{0.0,0.5,0.0},
|
||||||
|
{0.0,0.0,0.5},
|
||||||
|
{0.5,0.5,0.0},
|
||||||
|
{0.5,0.0,0.5},
|
||||||
|
{0.0,0.5,0.5},
|
||||||
|
{0.5,0.5,0.5},
|
||||||
|
{0.75,0.25,0.25},
|
||||||
|
{0.25,0.75,0.25},
|
||||||
|
{0.25,0.25,0.75},
|
||||||
|
{0.75,0.75,0.25},
|
||||||
|
{0.75,0.25,0.75},
|
||||||
|
{0.25,0.75,0.75},
|
||||||
|
{1.0,0.5,0.0},
|
||||||
|
{0.0,0.5,1.0},
|
||||||
|
{1.0,0.0,0.5},
|
||||||
|
{0.5,1.0,0.0},
|
||||||
|
{0.5,0.0,1.0},
|
||||||
|
{0.0,1.0,0.5},
|
||||||
|
{0.0,0.25,0.5},
|
||||||
|
{0.25,0,0.5},
|
||||||
|
{0.5,0.25,0.0},
|
||||||
|
{0.5,0.0,0.25},
|
||||||
|
{0.5,0.75,0.0},
|
||||||
|
{0.5,0.0,0.75},
|
||||||
|
{0.0,0.75,0.5},
|
||||||
|
{0.75,0.0,0.5},
|
||||||
|
}
|
||||||
|
if not g then
|
||||||
|
g=DPSMate.Options.graph:CreateGraphLine("DMGDTLineGraph",DPSMate_Details_DamageTotal_DiagramLine,"CENTER","CENTER",0,0,740,220)
|
||||||
|
g2=DPSMate.Options.graph:CreateStackedGraph("DMGDTStackedGraph",DPSMate_Details_DamageTotal_DiagramLine,"CENTER","CENTER",0,0,850,220)
|
||||||
|
g2:SetGridColor({0.5,0.5,0.5,0.5})
|
||||||
|
g2:SetAxisDrawing(true,true)
|
||||||
|
g2:SetAxisColor({1.0,1.0,1.0,1.0})
|
||||||
|
g2:SetAutoScale(true)
|
||||||
|
g2:SetYLabels(true, false)
|
||||||
|
g2:SetXLabels(true)
|
||||||
|
g2:Hide()
|
||||||
|
DPSMate.Modules.DetailsDamageTotal:CreateGraphTable()
|
||||||
|
end
|
||||||
|
DPSMate_Details_DamageTotal_PlayerList_CB:SetChecked(false)
|
||||||
|
DPSMate_Details_DamageTotal_PlayerList_CB.act = false
|
||||||
|
DPSMate_Details_DamageTotal_Title:SetText(DPSMate.L["dmgdonesum"])
|
||||||
|
self:LoadTable()
|
||||||
|
self:LoadLegendButtons()
|
||||||
|
if toggle then
|
||||||
|
self:UpdateStackedGraph()
|
||||||
|
else
|
||||||
|
self:UpdateLineGraph()
|
||||||
|
end
|
||||||
|
DPSMate_Details_DamageTotal:Show()
|
||||||
|
DPSMate_Details_DamageTotal:SetScale((DPSMateSettings["targetscale"] or 0.58)/UIParent:GetScale())
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:UpdateLineGraph()
|
||||||
|
g:ResetData()
|
||||||
|
g:SetGridColor({0.5,0.5,0.5,0.5})
|
||||||
|
g:SetAxisDrawing(true,true)
|
||||||
|
g:SetAxisColor({1.0,1.0,1.0,1.0})
|
||||||
|
g:SetAutoScale(true)
|
||||||
|
g:SetYLabels(true, false)
|
||||||
|
g:SetXLabels(true)
|
||||||
|
g2:Hide()
|
||||||
|
DPSMate_Details_DamageTotal_DiagramLine:SetWidth(770)
|
||||||
|
DPSMate_Details_DamageTotal_DiagramLegend:Show()
|
||||||
|
g:Show()
|
||||||
|
toggle=false
|
||||||
|
self:AddTotalDataSeries()
|
||||||
|
local Max = totMax
|
||||||
|
for cat, val in pairs(buttons) do
|
||||||
|
g:AddDataSeries(val[3], {val[1], {}}, {})
|
||||||
|
local temp = DPSMate:GetMaxValue(val[3], 2)
|
||||||
|
if temp>Max then
|
||||||
|
Max = temp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
g:SetGridSpacing(totTime/10,Max/7)
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:UpdateStackedGraph()
|
||||||
|
g:Hide()
|
||||||
|
DPSMate_Details_DamageTotal_DiagramLine:SetWidth(870)
|
||||||
|
DPSMate_Details_DamageTotal_DiagramLegend:Hide()
|
||||||
|
|
||||||
|
local Data1 = {}
|
||||||
|
local label = {}
|
||||||
|
local maxX, maxY = 0,0
|
||||||
|
local p = {}
|
||||||
|
for cat, val in db do
|
||||||
|
local temp = {}
|
||||||
|
local user =DPSMate:GetUserById(cat)
|
||||||
|
if DPSMate:ApplyFilter(curKey, user) then
|
||||||
|
for ca, va in val do
|
||||||
|
if ca~="i" then
|
||||||
|
for c,v in va["i"] do
|
||||||
|
local i = 1
|
||||||
|
while true do
|
||||||
|
if not temp[i] then
|
||||||
|
tinsert(temp, i, {c,v})
|
||||||
|
break
|
||||||
|
elseif c<=temp[i][1] then
|
||||||
|
tinsert(temp, i, {c,v})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
if p[c] then
|
||||||
|
p[c] = p[c] + v
|
||||||
|
else
|
||||||
|
p[c] = v
|
||||||
|
end
|
||||||
|
if maxX == 0 or maxX<c then
|
||||||
|
maxX = c
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tinsert(label, 1, user)
|
||||||
|
tinsert(Data1, 1, temp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for cat, val in p do
|
||||||
|
if maxY<val then
|
||||||
|
maxY = val
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
g2:ResetData()
|
||||||
|
g2:SetGridSpacing(maxX/7,(maxY/2)/14)
|
||||||
|
|
||||||
|
g2:AddDataSeries(Data1,{1.0,0.0,0.0,0.8}, {}, label)
|
||||||
|
g2:Show()
|
||||||
|
toggle=true
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:ToggleMode()
|
||||||
|
if toggle then
|
||||||
|
self:UpdateLineGraph()
|
||||||
|
toggle=false
|
||||||
|
else
|
||||||
|
self:UpdateStackedGraph()
|
||||||
|
toggle=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:GetSummarizedTable(arr)
|
||||||
|
return DPSMate.Sync:GetSummarizedTable(arr)
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:CreateGraphTable()
|
||||||
|
local lines = {}
|
||||||
|
for i=1, 8 do
|
||||||
|
-- Horizontal
|
||||||
|
lines[i] = DPSMate.Options.graph:DrawLine(DPSMate_Details_DamageTotal_PlayerList, 10, 270-i*30, 860, 270-i*30, 20, {0.5,0.5,0.5,0.5}, "BACKGROUND")
|
||||||
|
lines[i]:Show()
|
||||||
|
end
|
||||||
|
-- Vertical
|
||||||
|
lines[9] = DPSMate.Options.graph:DrawLine(DPSMate_Details_DamageTotal_PlayerList, 40, 260, 40, 10, 20, {0.5,0.5,0.5,0.5}, "BACKGROUND")
|
||||||
|
lines[9]:Show()
|
||||||
|
|
||||||
|
lines[10] = DPSMate.Options.graph:DrawLine(DPSMate_Details_DamageTotal_PlayerList, 170, 260, 170, 10, 20, {0.5,0.5,0.5,0.5}, "BACKGROUND")
|
||||||
|
lines[10]:Show()
|
||||||
|
|
||||||
|
lines[11] = DPSMate.Options.graph:DrawLine(DPSMate_Details_DamageTotal_PlayerList, 540, 260, 540, 10, 20, {0.5,0.5,0.5,0.5}, "BACKGROUND")
|
||||||
|
lines[11]:Show()
|
||||||
|
|
||||||
|
lines[12] = DPSMate.Options.graph:DrawLine(DPSMate_Details_DamageTotal_PlayerList, 600, 260, 600, 10, 20, {0.5,0.5,0.5,0.5}, "BACKGROUND")
|
||||||
|
lines[12]:Show()
|
||||||
|
|
||||||
|
lines[13] = DPSMate.Options.graph:DrawLine(DPSMate_Details_DamageTotal_PlayerList, 660, 260, 660, 10, 20, {0.5,0.5,0.5,0.5}, "BACKGROUND")
|
||||||
|
lines[13]:Show()
|
||||||
|
|
||||||
|
lines[13] = DPSMate.Options.graph:DrawLine(DPSMate_Details_DamageTotal_PlayerList, 740, 260, 740, 10, 20, {0.5,0.5,0.5,0.5}, "BACKGROUND")
|
||||||
|
lines[13]:Show()
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:AddTotalDataSeries()
|
||||||
|
local sumTable, newArr = {[0]=0}, {}
|
||||||
|
|
||||||
|
local temp = {}
|
||||||
|
for cat, val in db do
|
||||||
|
local user = DPSMate:GetUserById(cat)
|
||||||
|
if DPSMate:ApplyFilter(curKey, user) then
|
||||||
|
temp[user] = true
|
||||||
|
for ca, va in val do
|
||||||
|
if ca~="i" and va["i"] then
|
||||||
|
for c,v in va["i"] do
|
||||||
|
if sumTable[c] then
|
||||||
|
sumTable[c] = sumTable[c] + v
|
||||||
|
else
|
||||||
|
sumTable[c] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local tl = DPSMate:TableLength(temp)
|
||||||
|
tl = ceil(tl-0.3*tl)
|
||||||
|
|
||||||
|
for cat, val in sumTable do
|
||||||
|
local i=1
|
||||||
|
while true do
|
||||||
|
if (not newArr[i]) then
|
||||||
|
tinsert(newArr, i, {cat, val/tl})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if cat<newArr[i][1] then
|
||||||
|
tinsert(newArr, i, {cat, val/tl})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
totSumTable = self:GetSummarizedTable(newArr)
|
||||||
|
|
||||||
|
totMax = DPSMate:GetMaxValue(totSumTable, 2)
|
||||||
|
totTime = DPSMate:GetMaxValue(totSumTable, 1)
|
||||||
|
g:SetXAxis(0,totTime)
|
||||||
|
g:SetYAxis(0,totMax)
|
||||||
|
g:SetGridSpacing(totTime/10,totMax/7)
|
||||||
|
|
||||||
|
g:AddDataSeries(totSumTable,{{1.0,0.0,0.0,0.8}, {1.0,1.0,0.0,0.8}}, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:GetTableValues()
|
||||||
|
local arr, total = {}, 0
|
||||||
|
for cat, val in db do
|
||||||
|
local name = DPSMate:GetUserById(cat)
|
||||||
|
if DPSMate:ApplyFilter(curKey, name) then
|
||||||
|
local crit, totCrit, miss, totMiss, time, last = 0, 0.000001, 0, 0.000001, 0, 0
|
||||||
|
for ca, va in val do
|
||||||
|
if ca~="i" then
|
||||||
|
totCrit=totCrit+va[1]+va[5]+va[9]+va[10]+va[11]+va[12]+va[14]
|
||||||
|
crit=crit+va[5]
|
||||||
|
totMiss=totMiss+va[1]+va[5]+va[9]+va[10]+va[11]+va[12]+va[14]
|
||||||
|
miss=miss+va[9]+va[10]+va[11]+va[12]
|
||||||
|
else
|
||||||
|
time = tonumber(strformat("%.2f", DPSMateCombatTime["effective"][curKey][name] or 0))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tinsert(arr, {name, (val["i"] or 0), crit, miss, time, totCrit, totMiss, cat})
|
||||||
|
total = total + (val["i"] or 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local newArr = {}
|
||||||
|
for cat, val in arr do
|
||||||
|
local i = 1
|
||||||
|
while true do
|
||||||
|
if (not newArr[i]) then
|
||||||
|
tinsert(newArr, i, val)
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if newArr[i][2] < val[2] then
|
||||||
|
tinsert(newArr, i, val)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return newArr, total
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:CheckButtonCheckAll(obj)
|
||||||
|
if obj.act then
|
||||||
|
obj.act = false
|
||||||
|
for i=1, 30 do
|
||||||
|
local ob = _G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..i)
|
||||||
|
if ob.user then
|
||||||
|
self:RemoveLinesButton(ob.user, ob)
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..i.."_CB"):SetChecked(obj.act)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
obj.act = true
|
||||||
|
for i=1, 30 do
|
||||||
|
local ob = _G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..i)
|
||||||
|
if ob.user then
|
||||||
|
self:RemoveLinesButton(ob.user, ob)
|
||||||
|
self:AddLinesButton(ob.user, ob)
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..i.."_CB"):SetChecked(obj.act)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:SortLineTable(uid)
|
||||||
|
local user = DPSMate:GetUserById(uid)
|
||||||
|
local uentry = DPSMateUser[user]
|
||||||
|
if not uentry then return {} end
|
||||||
|
local newArr = {}
|
||||||
|
-- user
|
||||||
|
for cat, val in db[uentry[1]] do
|
||||||
|
if cat~="i" and val["i"] then
|
||||||
|
for c,v in val["i"] do
|
||||||
|
local i = 1
|
||||||
|
while true do
|
||||||
|
if not newArr[i] then
|
||||||
|
tinsert(newArr, i, {c,v})
|
||||||
|
break
|
||||||
|
elseif c<=newArr[i][1] then
|
||||||
|
tinsert(newArr, i, {c,v})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
i = i+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Pet
|
||||||
|
if DPSMateSettings["mergepets"] then
|
||||||
|
for pName, pEntry in pairs(DPSMateUser) do
|
||||||
|
if pEntry[4] and pEntry[6] == uentry[1] and pName ~= user and db[pEntry[1]] then
|
||||||
|
for cat, val in db[pEntry[1]] do
|
||||||
|
if cat~="i" and val["i"] then
|
||||||
|
for c,v in val["i"] do
|
||||||
|
local i = 1
|
||||||
|
while true do
|
||||||
|
if not newArr[i] then
|
||||||
|
tinsert(newArr, i, {c,v})
|
||||||
|
break
|
||||||
|
elseif c<=newArr[i][1] then
|
||||||
|
tinsert(newArr, i, {c,v})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
i = i+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return newArr
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:AddLinesButton(uid, obj)
|
||||||
|
local sumTable = self:SortLineTable(uid)
|
||||||
|
|
||||||
|
sumTable = self:GetSummarizedTable(sumTable)
|
||||||
|
|
||||||
|
local Max = DPSMate:GetMaxValue(sumTable, 2)
|
||||||
|
if Max > totMax then
|
||||||
|
g:SetGridSpacing(totTime/10,Max/7)
|
||||||
|
end
|
||||||
|
|
||||||
|
g:AddDataSeries(sumTable, {ColorTable[1], {}}, {})
|
||||||
|
tinsert(buttons, {ColorTable[1], uid, sumTable})
|
||||||
|
tremove(ColorTable, 1)
|
||||||
|
g2:Hide()
|
||||||
|
DPSMate_Details_DamageTotal_DiagramLine:SetWidth(770)
|
||||||
|
DPSMate_Details_DamageTotal_DiagramLegend:Show()
|
||||||
|
g:Show()
|
||||||
|
toggle=false
|
||||||
|
obj.act = true
|
||||||
|
self:LoadLegendButtons()
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:RemoveLinesButton(uid, obj)
|
||||||
|
obj.act = false
|
||||||
|
g:ResetData()
|
||||||
|
for cat, val in pairs(buttons) do
|
||||||
|
if val[2]==uid then
|
||||||
|
tinsert(ColorTable, 1, val[1])
|
||||||
|
tremove(buttons, cat)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local Max = totMax
|
||||||
|
g:AddDataSeries(totSumTable,{{1.0,0.0,0.0,0.8}, {1.0,1.0,0.0,0.8}}, {})
|
||||||
|
for cat, val in pairs(buttons) do
|
||||||
|
g:AddDataSeries(val[3], {val[1], {}}, {})
|
||||||
|
local temp = DPSMate:GetMaxValue(val[3], 2)
|
||||||
|
if temp>Max then
|
||||||
|
Max = temp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
g:SetGridSpacing(totTime/10,Max/7)
|
||||||
|
g2:Hide()
|
||||||
|
DPSMate_Details_DamageTotal_DiagramLine:SetWidth(770)
|
||||||
|
DPSMate_Details_DamageTotal_DiagramLegend:Show()
|
||||||
|
g:Show()
|
||||||
|
toggle = false
|
||||||
|
self:LoadLegendButtons()
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:LoadLegendButtons()
|
||||||
|
for i=1, 30 do
|
||||||
|
_G("DPSMate_Details_DamageTotal_DiagramLegend_Child_C"..i):Hide()
|
||||||
|
end
|
||||||
|
for cat, val in buttons do
|
||||||
|
local name = DPSMate:GetUserById(val[2])
|
||||||
|
local font = _G("DPSMate_Details_DamageTotal_DiagramLegend_Child_C"..cat.."_Font")
|
||||||
|
font:SetText(name)
|
||||||
|
local uentry = DPSMateUser[name]
|
||||||
|
font:SetTextColor(DPSMate:GetClassColor(uentry and uentry[2]))
|
||||||
|
_G("DPSMate_Details_DamageTotal_DiagramLegend_Child_C"..cat.."_SwatchBg"):SetTexture(val[1][1],val[1][2],val[1][3],1)
|
||||||
|
_G("DPSMate_Details_DamageTotal_DiagramLegend_Child_C"..cat):Show()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:RoundToH(val)
|
||||||
|
if val>100 then
|
||||||
|
return 100
|
||||||
|
end
|
||||||
|
return val
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:CompareVal(x,y)
|
||||||
|
if x>y then
|
||||||
|
return y
|
||||||
|
end
|
||||||
|
return x
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:LoadTable()
|
||||||
|
local arr, total = self:GetTableValues()
|
||||||
|
local i = 0
|
||||||
|
for i=1, 30 do
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..i):Hide()
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..i.."_CB"):SetChecked(false)
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..i.."_CB").act = false
|
||||||
|
end
|
||||||
|
for cat, val in arr do
|
||||||
|
local uentry = DPSMateUser[val[1]]
|
||||||
|
if uentry and uentry[4] then
|
||||||
|
i=i+1
|
||||||
|
else
|
||||||
|
if (cat-i)>30 then break end
|
||||||
|
local r,g,b = DPSMate:GetClassColor(uentry and uentry[2])
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child"):SetHeight((cat-i)*30)
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i).."_Name"):SetText(val[1])
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i).."_Name"):SetTextColor(r,g,b)
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i).."_Amount"):SetText(val[2])
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i).."_StatusBar"):SetValue(100*val[2]/arr[1][2])
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i).."_StatusBar"):SetStatusBarColor(r,g,b, 1)
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i).."_AmountPerc"):SetText(strformat("%.1f", 100*val[2]/total).."%")
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i).."_Crit"):SetText(strformat("%.1f", 100*val[3]/val[6]).."%")
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i).."_Miss"):SetText(strformat("%.1f", 100*val[4]/val[7]).."%")
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i).."_DPS"):SetText(strformat("%.1f", val[2]/cbt))
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i).."_ActiveTime"):SetText(self:CompareVal(ceil(val[5]), ceil(cbt)).."s | "..strformat("%.1f", self:RoundToH(100*val[5]/cbt)).."%")
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i)).user = val[8]
|
||||||
|
_G("DPSMate_Details_DamageTotal_PlayerList_Child_R"..(cat-i)):Show()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function DPSMate.Modules.DetailsDamageTotal:ShowTooltip(user, obj)
|
||||||
|
local name = DPSMate:GetUserById(user)
|
||||||
|
if not DPSMateUser[name] then return end
|
||||||
|
local a,b,c = DPSMate.Modules.Damage:EvalTable(DPSMateUser[name], curKey)
|
||||||
|
local pet = ""
|
||||||
|
GameTooltip:SetOwner(obj, "TOPLEFT")
|
||||||
|
GameTooltip:AddLine(name.."'s "..strlower(DPSMate.L["damagedone"]), 1,1,1)
|
||||||
|
if not a or not b or not c then return end
|
||||||
|
for i=1, DPSMateSettings["subviewrows"] do
|
||||||
|
if not a[i] then break end
|
||||||
|
if c[i][2] then pet="("..c[i][2]..")" else pet="" end
|
||||||
|
GameTooltip:AddDoubleLine(i..". "..DPSMate:GetAbilityById(a[i])..pet,c[i][1].." ("..strformat("%.2f", 100*c[i][1]/b).."%)",1,1,1,1,1,1)
|
||||||
|
end
|
||||||
|
GameTooltip:Show()
|
||||||
|
end
|
||||||
@@ -0,0 +1,761 @@
|
|||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||||
|
..\..\..\FrameXML\UI.xsd">
|
||||||
|
|
||||||
|
<Frame name="DPSMate_Details_DamageTotal_Template_LegendColumn" virtual="true" hidden="true">
|
||||||
|
<Size x="18" y="18" />
|
||||||
|
<Layers>
|
||||||
|
<Layer level="ARTWORK">
|
||||||
|
<FontString name="$parent_Font" inherits="GameFontNormalSmall" text="Average" justifyH="LEFT">
|
||||||
|
<Size x="60" y="18" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="LEFT" relativeTo="$parent" relativePoint="RIGHT">
|
||||||
|
<Offset x="5" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Color r="1" g="1" b="1" />
|
||||||
|
</FontString>
|
||||||
|
</Layer>
|
||||||
|
<Layer level="BACKGROUND">
|
||||||
|
<Texture name="$parent_SwatchBg">
|
||||||
|
<Size x="16" y="16"/>
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="CENTER" />
|
||||||
|
</Anchors>
|
||||||
|
<Color r="1.0" g="0" b="0" a="1"/>
|
||||||
|
</Texture>
|
||||||
|
</Layer>
|
||||||
|
</Layers>
|
||||||
|
</Frame>
|
||||||
|
|
||||||
|
<Frame name="DPSMate_Details_DamageTotal_Template_Row" virtual="true" hidden="true">
|
||||||
|
<Size x="870" y="30" />
|
||||||
|
<Layers>
|
||||||
|
<Layer level="BACKGROUND">
|
||||||
|
<Texture name="$parent_Hover" hidden="true">
|
||||||
|
<Size x="850" y="25"/>
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="CENTER">
|
||||||
|
<Offset x="0" y="-5" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Color r="0.95" g="0.9" b="0.5" a="0.5"/>
|
||||||
|
</Texture>
|
||||||
|
<FontString name="$parent_Name" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER">
|
||||||
|
<Size x="130" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="45" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_Amount" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER">
|
||||||
|
<Size x="100" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="175" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Color r="1" g="1" b="1" />
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_AmountPerc" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER">
|
||||||
|
<Size x="100" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="485" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Color r="1" g="1" b="1" />
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_Crit" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER">
|
||||||
|
<Size x="100" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="545" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Color r="1" g="1" b="1" />
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_Miss" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER">
|
||||||
|
<Size x="100" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="605" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Color r="1" g="1" b="1" />
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_DPS" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER">
|
||||||
|
<Size x="100" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="665" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Color r="1" g="1" b="1" />
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_ActiveTime" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER">
|
||||||
|
<Size x="120" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="745" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Color r="1" g="1" b="1" />
|
||||||
|
</FontString>
|
||||||
|
</Layer>
|
||||||
|
</Layers>
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
getglobal(this:GetName().."_Hover"):Show()
|
||||||
|
DPSMate.Modules.DetailsDamageTotal:ShowTooltip(this.user, this)
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
getglobal(this:GetName().."_Hover"):Hide()
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
</Scripts>
|
||||||
|
<Frames>
|
||||||
|
<CheckButton name="$parent_CB" inherits="UICheckButtonTemplate">
|
||||||
|
<Size x="26" y="26" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="10" y="-9" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Scripts>
|
||||||
|
<OnLoad>
|
||||||
|
this:GetParent().act = false
|
||||||
|
</OnLoad>
|
||||||
|
<OnClick>
|
||||||
|
local uid = this:GetParent().user
|
||||||
|
local act = this:GetParent().act
|
||||||
|
if uid then
|
||||||
|
if act then
|
||||||
|
DPSMate.Modules.DetailsDamageTotal:RemoveLinesButton(uid, this:GetParent())
|
||||||
|
else
|
||||||
|
DPSMate.Modules.DetailsDamageTotal:AddLinesButton(uid, this:GetParent())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
</OnClick>
|
||||||
|
</Scripts>
|
||||||
|
</CheckButton>
|
||||||
|
<StatusBar name="$parent_StatusBar">
|
||||||
|
<Size x="225" y="16" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="255" y="-13" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Scripts>
|
||||||
|
<OnLoad>
|
||||||
|
this:SetMinMaxValues(1,100)
|
||||||
|
this:SetStatusBarTexture("Interface\\AddOns\\DPSMate\\images\\statusbar\\Healbot")
|
||||||
|
this:SetValue(100)
|
||||||
|
</OnLoad>
|
||||||
|
</Scripts>
|
||||||
|
</StatusBar>
|
||||||
|
</Frames>
|
||||||
|
</Frame>
|
||||||
|
|
||||||
|
<Frame name="DPSMate_Details_DamageTotal" parent="UIParent" movable="true" hidden="true">
|
||||||
|
<Size x="900" y="600" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="CENTER" />
|
||||||
|
</Anchors>
|
||||||
|
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||||||
|
<BackgroundInsets left="6" right="6" top="6" bottom="6" />
|
||||||
|
<TileSize val="16" />
|
||||||
|
<EdgeSize val="16" />
|
||||||
|
<Color r="0.157" g="0.08" b="0.06" a="1" />
|
||||||
|
</Backdrop>
|
||||||
|
<Layers>
|
||||||
|
<Layer level="ARTWORK">
|
||||||
|
<FontString name="$parent_Title" inherits="GameFontNormalHuge" justifyH="LEFT" justifyV="CENTER" text="Damage done for Shino">
|
||||||
|
<Size x="900" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="20" y="-10" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
</Layer>
|
||||||
|
</Layers>
|
||||||
|
<Scripts>
|
||||||
|
<OnLoad>
|
||||||
|
this:SetClampedToScreen()
|
||||||
|
getglobal(this:GetName().."_Title"):SetFont(UNIT_NAME_FONT, 24)
|
||||||
|
</OnLoad>
|
||||||
|
<OnMouseDown>
|
||||||
|
this:StartMoving()
|
||||||
|
</OnMouseDown>
|
||||||
|
<OnMouseUp>
|
||||||
|
this:StopMovingOrSizing()
|
||||||
|
</OnMouseUp>
|
||||||
|
</Scripts>
|
||||||
|
<Frames>
|
||||||
|
<Button name="$parent_CloseButton">
|
||||||
|
<Size x="30" y="30" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPRIGHT" relativeTo="$parent" relativePoint="TOPRIGHT">
|
||||||
|
<Offset>
|
||||||
|
<AbsDimension x="0" y="0"/>
|
||||||
|
</Offset>
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
|
||||||
|
GameTooltip:SetText(DPSMate.L["close"], nil, nil, nil, nil, 1)
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnClick>
|
||||||
|
DPSMate_Details_DamageTotal:Hide()
|
||||||
|
PlaySound("igMainMenuOptionCheckBoxOff")
|
||||||
|
</OnClick>
|
||||||
|
</Scripts>
|
||||||
|
<NormalTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Up"/>
|
||||||
|
<PushedTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Down"/>
|
||||||
|
<HighlightTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Highlight" alphaMode="ADD"/>
|
||||||
|
</Button>
|
||||||
|
<Button name="$parent_SwitchGraph">
|
||||||
|
<Size x="22" y="22" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="RIGHT" relativeTo="$parent_CloseButton" relativePoint="LEFT">
|
||||||
|
<Offset>
|
||||||
|
<AbsDimension x="-3" y="-3"/>
|
||||||
|
</Offset>
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Scripts>
|
||||||
|
<OnEnter>
|
||||||
|
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
|
||||||
|
GameTooltip:SetText(DPSMate.L["switchgraphsdesc"], nil, nil, nil, nil, 1)
|
||||||
|
GameTooltip:Show()
|
||||||
|
</OnEnter>
|
||||||
|
<OnLeave>
|
||||||
|
GameTooltip:Hide()
|
||||||
|
</OnLeave>
|
||||||
|
<OnClick>
|
||||||
|
DPSMate.Modules.DetailsDamageTotal:ToggleMode()
|
||||||
|
PlaySound("igMainMenuOptionCheckBoxOff")
|
||||||
|
</OnClick>
|
||||||
|
</Scripts>
|
||||||
|
<NormalTexture file="Interface\Buttons\UI-GroupLoot-Dice-Up"/>
|
||||||
|
<PushedTexture file="Interface\Buttons\UI-GroupLoot-Dice-Down"/>
|
||||||
|
<HighlightTexture file="Interface\Buttons\UI-GroupLoot-Dice-Highlight" alphaMode="ADD"/>
|
||||||
|
</Button>
|
||||||
|
<Frame name="$parent_DiagramLine">
|
||||||
|
<Size x="770" y="250" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="15" y="-65" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||||||
|
<BackgroundInsets left="6" right="6" top="6" bottom="6" />
|
||||||
|
<TileSize val="16" />
|
||||||
|
<EdgeSize val="16" />
|
||||||
|
<Color r="0.157" g="0.08" b="0.06" a="0.5" />
|
||||||
|
</Backdrop>
|
||||||
|
</Frame>
|
||||||
|
<ScrollFrame name="$parent_DiagramLegend">
|
||||||
|
<Size x="100" y="250" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="LEFT" relativeTo="$parent_DiagramLine" relativePoint="RIGHT" />
|
||||||
|
</Anchors>
|
||||||
|
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||||||
|
<BackgroundInsets left="6" right="6" top="6" bottom="6" />
|
||||||
|
<TileSize val="16" />
|
||||||
|
<EdgeSize val="16" />
|
||||||
|
<Color r="0.157" g="0.08" b="0.06" a="0.5" />
|
||||||
|
</Backdrop>
|
||||||
|
<Scripts>
|
||||||
|
<OnLoad>
|
||||||
|
this:SetVerticalScroll(0)
|
||||||
|
</OnLoad>
|
||||||
|
<OnMouseWheel>
|
||||||
|
DPSMate.Options:OnVerticalScroll(this, arg1, 20, true)
|
||||||
|
</OnMouseWheel>
|
||||||
|
</Scripts>
|
||||||
|
<HitRectInsets left="0" right="0" top="5" bottom="5"/>
|
||||||
|
<ScrollChild>
|
||||||
|
<Frame name="$parent_Child">
|
||||||
|
<Size x="100" y="620" />
|
||||||
|
<Frames>
|
||||||
|
<Frame name="$parent_Total" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn" hidden="false">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
|
||||||
|
<Offset x="10" y="-8" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C1" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_Total" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C2" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C1" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C3" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C2" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C4" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C3" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C5" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C4" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C6" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C5" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C7" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C6" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C8" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C7" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C9" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C8" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C10" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C9" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C11" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C10" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C12" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C11" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C13" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C12" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C14" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C13" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C15" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C14" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C16" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C15" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C17" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C16" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C18" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C17" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C19" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C18" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C20" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C19" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C21" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C20" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C22" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C21" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C23" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C22" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C24" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C23" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C25" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C24" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C26" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C25" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C27" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C26" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C28" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C27" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C29" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C28" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_C30" inherits="DPSMate_Details_DamageTotal_Template_LegendColumn">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP" relativeTo="$parent_C29" relativePoint="BOTTOM">
|
||||||
|
<Offset x="0" y="-2" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
</Frames>
|
||||||
|
</Frame>
|
||||||
|
</ScrollChild>
|
||||||
|
</ScrollFrame>
|
||||||
|
<ScrollFrame name="$parent_PlayerList">
|
||||||
|
<Size x="870" y="270" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_DiagramLine" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||||||
|
<BackgroundInsets left="6" right="6" top="6" bottom="6" />
|
||||||
|
<TileSize val="16" />
|
||||||
|
<EdgeSize val="16" />
|
||||||
|
<Color r="0.157" g="0.08" b="0.06" a="0.5" />
|
||||||
|
</Backdrop>
|
||||||
|
<Layers>
|
||||||
|
<Layer level="BACKGROUND">
|
||||||
|
<FontString name="$parent_Name" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER" text="Name">
|
||||||
|
<Size x="100" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="45" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_Amount" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER" text="Amount">
|
||||||
|
<Size x="100" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="329" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_Crit" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER" text="Crit">
|
||||||
|
<Size x="100" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="545" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_Miss" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER" text="Miss">
|
||||||
|
<Size x="100" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="605" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_DPS" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER" text="DPS">
|
||||||
|
<Size x="100" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="665" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
<FontString name="$parent_ActiveTime" inherits="GameFontNormal" justifyH="LEFT" justifyV="CENTER" text="Active Time">
|
||||||
|
<Size x="130" y="40" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="745" y="0" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
</Layer>
|
||||||
|
</Layers>
|
||||||
|
<Scripts>
|
||||||
|
<OnLoad>
|
||||||
|
this:SetVerticalScroll(0)
|
||||||
|
</OnLoad>
|
||||||
|
<OnMouseWheel>
|
||||||
|
DPSMate.Options:OnVerticalScroll(this, arg1, 30, true)
|
||||||
|
</OnMouseWheel>
|
||||||
|
</Scripts>
|
||||||
|
<HitRectInsets left="0" right="0" top="35" bottom="5"/>
|
||||||
|
<ScrollChild>
|
||||||
|
<Frame name="$parent_Child">
|
||||||
|
<Size x="870" y="270" />
|
||||||
|
<Frames>
|
||||||
|
<Frame name="$parent_R1" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOP">
|
||||||
|
<Offset x="0" y="-25" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R2" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R1" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R3" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R2" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R4" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R3" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R5" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R4" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R6" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R5" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R7" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R6" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R8" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R7" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R9" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R8" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R10" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R9" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R11" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R10" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R12" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R11" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R13" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R12" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R14" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R13" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R15" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R14" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R16" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R15" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R17" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R16" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R18" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R17" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R19" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R18" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R20" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R19" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R21" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R20" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R22" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R21" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R23" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R22" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R24" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R23" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R25" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R24" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R26" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R25" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R27" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R26" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R28" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R27" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R29" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R28" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
<Frame name="$parent_R30" inherits="DPSMate_Details_DamageTotal_Template_Row">
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT" relativeTo="$parent_R29" relativePoint="BOTTOMLEFT" />
|
||||||
|
</Anchors>
|
||||||
|
</Frame>
|
||||||
|
</Frames>
|
||||||
|
</Frame>
|
||||||
|
</ScrollChild>
|
||||||
|
<Frames>
|
||||||
|
<CheckButton name="$parent_CB" inherits="UICheckButtonTemplate">
|
||||||
|
<Size x="26" y="26" />
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="TOPLEFT">
|
||||||
|
<Offset x="10" y="-4.5" />
|
||||||
|
</Anchor>
|
||||||
|
</Anchors>
|
||||||
|
<Scripts>
|
||||||
|
<OnClick>
|
||||||
|
DPSMate.Modules.DetailsDamageTotal:CheckButtonCheckAll(this)
|
||||||
|
</OnClick>
|
||||||
|
</Scripts>
|
||||||
|
</CheckButton>
|
||||||
|
</Frames>
|
||||||
|
</ScrollFrame>
|
||||||
|
</Frames>
|
||||||
|
</Frame>
|
||||||
|
|
||||||
|
</Ui>
|
||||||
@@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
{one line to give the program's name and a brief idea of what it does.}
|
||||||
|
Copyright (C) {year} {name of author}
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
{project} Copyright (C) {year} {fullname}
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
# DPSMate
|
||||||
|
|
||||||
|
A combat analysis addon for World of Warcraft 1.12 (Classic). Parses combat log messages in real-time to track ~40 metrics and presents them in customizable UI windows.
|
||||||
|
|
||||||
|
Originally by Shino <Synced> - Kronos. This fork targets TWoW/Kronos private servers.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Download and extract into `Interface/AddOns/` so the folder is named `DPSMate` (not `DPSMate-master`).
|
||||||
|
2. Increase addon memory to at least 150 MB.
|
||||||
|
3. If upgrading from a previous version, delete the old SavedVariables while logged out:
|
||||||
|
- `WTF/Account/<ACCOUNT>/SavedVariables/DPSMate.lua` (account-wide settings)
|
||||||
|
- `WTF/Account/<ACCOUNT>/<SERVER>/<CHARACTER>/SavedVariables/DPSMate.lua` (per-character data)
|
||||||
|
4. Add these lines to `WTF/config.wtf` for full combat log range:
|
||||||
|
```
|
||||||
|
SET CombatLogRangeParty "150"
|
||||||
|
SET CombatLogRangePartyPet "150"
|
||||||
|
SET CombatLogRangeFriendlyPlayers "150"
|
||||||
|
SET CombatLogRangeFriendlyPlayersPets "150"
|
||||||
|
SET CombatLogRangeHostilePlayers "150"
|
||||||
|
SET CombatLogRangeHostilePlayersPets "150"
|
||||||
|
SET CombatLogRangeCreature "150"
|
||||||
|
```
|
||||||
|
5. Log in and `/reload` to load the addon.
|
||||||
|
|
||||||
|
## Slash Commands
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `/dps` | Show help and available commands |
|
||||||
|
| `/dps config` | Open configuration window |
|
||||||
|
| `/dps lock` | Lock all frames |
|
||||||
|
| `/dps unlock` | Unlock all frames |
|
||||||
|
| `/dps show {name}` | Show a specific window |
|
||||||
|
| `/dps hide {name}` | Hide a specific window |
|
||||||
|
| `/dps showAll` | Show all windows |
|
||||||
|
| `/dps hideAll` | Hide all windows |
|
||||||
|
| `/dps reset` | Reset all saved data (players, abilities, history, metrics) |
|
||||||
|
| `/dps testmode` | Toggle test mode for UI testing |
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Tracking Modes (~40)
|
||||||
|
|
||||||
|
- Damage done / DPS / damage taken / DTPS
|
||||||
|
- Enemy damage done / taken
|
||||||
|
- Healing (total, effective, overhealing) / HPS / EHPS / OHPS
|
||||||
|
- Healing taken (total, effective, overhealing)
|
||||||
|
- Healing and absorbs combined
|
||||||
|
- Absorbs done / taken
|
||||||
|
- Threat / TPS (requires KLHThreatMeter)
|
||||||
|
- Deaths with full death recap
|
||||||
|
- Interrupts (including stuns and silences)
|
||||||
|
- Dispels / decurses / cure disease / cure poison / lift magic (done and received)
|
||||||
|
- CC breakers
|
||||||
|
- Friendly fire (done and taken)
|
||||||
|
- Auras (gained, lost, uptime)
|
||||||
|
- Buffs/debuffs and procs
|
||||||
|
- Casts
|
||||||
|
- Fails
|
||||||
|
|
||||||
|
### UI
|
||||||
|
|
||||||
|
- Multiple independent windows showing different modes simultaneously
|
||||||
|
- Resizable and movable frames
|
||||||
|
- Per-window customization of fonts, colors, textures, bar height, spacing, columns
|
||||||
|
- Configurable display refresh rate (0.016s to 2.0s)
|
||||||
|
- Up to 40 status bars per window
|
||||||
|
- Compare mode for player-vs-player analysis
|
||||||
|
- Detail views with graphs for every mode
|
||||||
|
|
||||||
|
### Data Management
|
||||||
|
|
||||||
|
- Configurable segment history (1-20 fight segments)
|
||||||
|
- Boss-only fight filtering
|
||||||
|
- Automatic stale player pruning between fights
|
||||||
|
- Raid data synchronization via addon channel
|
||||||
|
- Report function for chat output
|
||||||
|
|
||||||
|
## Supported Locales
|
||||||
|
|
||||||
|
enUS, deDE, frFR, ruRU, koKR, zhCN
|
||||||
|
|
||||||
|
## Optional Dependencies
|
||||||
|
|
||||||
|
- **KLHThreatMeter** -- enables threat/TPS tracking
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**SavedVariables getting too large?**
|
||||||
|
- Use `/dps reset` to wipe all accumulated data.
|
||||||
|
- Reduce the number of stored segments in General Options.
|
||||||
|
- History segments automatically strip per-tick graph data to save space.
|
||||||
|
|
||||||
|
**Missing group members?**
|
||||||
|
- Ensure combat log range settings are applied in `config.wtf` (see Installation step 4).
|
||||||
|
- Verify all raid members have the addon loaded for sync to work.
|
||||||
@@ -0,0 +1,474 @@
|
|||||||
|
--[[
|
||||||
|
Name: Babble-Boss-2.3
|
||||||
|
Revision: $Rev: 20300 $
|
||||||
|
Author(s): ckknight (ckknight@gmail.com)
|
||||||
|
Website: http://ckknight.wowinterface.com/
|
||||||
|
Documentation: http://wiki.wowace.com/index.php/Babble-Boss-2.2
|
||||||
|
SVN: http://svn.wowace.com/root/trunk/Babble-2.2/Babble-Boss-2.2
|
||||||
|
Description: A library to provide localizations for bosses.
|
||||||
|
Dependencies: AceLibrary, AceLocale-2.2
|
||||||
|
|
||||||
|
Rewritten a little and added some "bosses" by Shino
|
||||||
|
]]
|
||||||
|
|
||||||
|
local bosses = {
|
||||||
|
-- Costum bosses
|
||||||
|
["Firesworn"] = true,
|
||||||
|
|
||||||
|
["Avalanchion"] = true,
|
||||||
|
["The Windreaver"] = true,
|
||||||
|
["Baron Charr"] = true,
|
||||||
|
["Princess Tempestria"] = true,
|
||||||
|
["Grethok the Controller"] = true,
|
||||||
|
["Patchwerk"] = true,
|
||||||
|
["Grobbulus"] = true,
|
||||||
|
["Gluth"] = true,
|
||||||
|
["Feugen"] = true,
|
||||||
|
["Stalagg"] = true,
|
||||||
|
["Thaddius"] = true,
|
||||||
|
["Anub'Rekhan"] = true,
|
||||||
|
["Grand Widow Faerlina"] = true,
|
||||||
|
["Maexxna"] = true,
|
||||||
|
["Instructor Razuvious"] = true,
|
||||||
|
--["Deathknight Understudy"] = true,
|
||||||
|
["Gothik the Harvester"] = true,
|
||||||
|
["Highlord Mograine"] = true,
|
||||||
|
["Thane Korth'azz"] = true,
|
||||||
|
["Lady Blaumeux"] = true,
|
||||||
|
["Sir Zeliek"] = true,
|
||||||
|
["The Four Horsemen"] = true,
|
||||||
|
["Noth the Plaguebringer"] = true,
|
||||||
|
["Heigan the Unclean"] = true,
|
||||||
|
["Loatheb"] = true,
|
||||||
|
["Sapphiron"] = true,
|
||||||
|
["Kel'Thuzad"] = true,
|
||||||
|
["Lord Victor Nefarius"] = true,
|
||||||
|
["Nefarian"] = true,
|
||||||
|
["Vaelastrasz the Corrupt"] = true,
|
||||||
|
["Razorgore the Untamed"] = true,
|
||||||
|
["Broodlord Lashlayer"] = true,
|
||||||
|
["Chromaggus"] = true,
|
||||||
|
["Ebonroc"] = true,
|
||||||
|
["Firemaw"] = true,
|
||||||
|
["Flamegor"] = true,
|
||||||
|
["Majordomo Executus"] = true,
|
||||||
|
["Ragnaros"] = true,
|
||||||
|
["Baron Geddon"] = true,
|
||||||
|
["Golemagg the Incinerator"] = true,
|
||||||
|
["Garr"] = true,
|
||||||
|
["Sulfuron Harbinger"] = true,
|
||||||
|
["Shazzrah"] = true,
|
||||||
|
["Lucifron"] = true,
|
||||||
|
["Gehennas"] = true,
|
||||||
|
["Magmadar"] = true,
|
||||||
|
["Onyxia"] = true,
|
||||||
|
["Azuregos"] = true,
|
||||||
|
["Lord Kazzak"] = true,
|
||||||
|
["Ysondre"] = true,
|
||||||
|
["Emeriss"] = true,
|
||||||
|
["Taerar"] = true,
|
||||||
|
["Lethon"] = true,
|
||||||
|
["High Priestess Jeklik"] = true,
|
||||||
|
["High Priest Venoxis"] = true,
|
||||||
|
["High Priest Thekal"] = true,
|
||||||
|
["High Priestess Arlokk"] = true,
|
||||||
|
["High Priestess Mar'li"] = true,
|
||||||
|
["Jin'do the Hexxer"] = true,
|
||||||
|
["Bloodlord Mandokir"] = true,
|
||||||
|
["Gahz'ranka"] = true,
|
||||||
|
["Gri'lek"] = true,
|
||||||
|
["Hazza'rah"] = true,
|
||||||
|
["Renataki"] = true,
|
||||||
|
["Wushoolay"] = true,
|
||||||
|
["Hakkar"] = true,
|
||||||
|
["Ayamiss the Hunter"] = true,
|
||||||
|
["Buru the Gorger"] = true,
|
||||||
|
["General Rajaxx"] = true,
|
||||||
|
["Lieutenant General Andorov"] = true,
|
||||||
|
["Moam"] = true,
|
||||||
|
["Ossirian the Unscarred"] = true,
|
||||||
|
["Lord Kri"] = true,
|
||||||
|
["Princess Yauj"] = true,
|
||||||
|
["Vem"] = true,
|
||||||
|
["The Bug Family"] = true,
|
||||||
|
["Eye of C'Thun"] = true,
|
||||||
|
["C'Thun"] = true,
|
||||||
|
["Fankriss the Unyielding"] = true,
|
||||||
|
["Princess Huhuran"] = true,
|
||||||
|
["Ouro"] = true,
|
||||||
|
["Battleguard Sartura"] = true,
|
||||||
|
["The Prophet Skeram"] = true,
|
||||||
|
["Emperor Vek'lor"] = true,
|
||||||
|
["Emperor Vek'nilash"] = true,
|
||||||
|
["The Twin Emperors"] = true,
|
||||||
|
["Viscidus"] = true,
|
||||||
|
["Alzzin the Wildshaper"] = true,
|
||||||
|
["Ambassador Flamelash"] = true,
|
||||||
|
["Anger'rel"] = true,
|
||||||
|
["Archivist Galford"] = true,
|
||||||
|
["Atal'alarion"] = true,
|
||||||
|
["Avatar of Hakkar"] = true,
|
||||||
|
["Bael'Gar"] = true,
|
||||||
|
["Balnazzar"] = true,
|
||||||
|
["Baroness Anastari"] = true,
|
||||||
|
["Baron Rivendare"] = true,
|
||||||
|
["Cannon Master Willey"] = true,
|
||||||
|
["Captain Kromcrush"] = true,
|
||||||
|
["Celebras the Cursed"] = true,
|
||||||
|
["Crystal Fang"] = true,
|
||||||
|
["Darkmaster Gandling"] = true,
|
||||||
|
["Doctor Theolen Krastinov"] = true,
|
||||||
|
["Doom'rel"] = true,
|
||||||
|
["Dope'rel"] = true,
|
||||||
|
["Dreamscythe"] = true,
|
||||||
|
["Emperor Dagran Thaurissan"] = true,
|
||||||
|
["Fineous Darkvire"] = true,
|
||||||
|
["Gasher"] = true,
|
||||||
|
["General Angerforge"] = true,
|
||||||
|
["General Drakkisath"] = true,
|
||||||
|
["Gloom'rel"] = true,
|
||||||
|
["Golem Lord Argelmach"] = true,
|
||||||
|
["Goraluk Anvilcrack"] = true,
|
||||||
|
["Guard Fengus"] = true,
|
||||||
|
["Guard Mol'dar"] = true,
|
||||||
|
["Guard Slip'kik"] = true,
|
||||||
|
["Gyth"] = true,
|
||||||
|
["Halycon"] = true,
|
||||||
|
["Hate'rel"] = true,
|
||||||
|
["Hazzas"] = true,
|
||||||
|
["Hearthsinger Forresten"] = true,
|
||||||
|
["High Interrogator Gerstahn"] = true,
|
||||||
|
["Highlord Omokk"] = true,
|
||||||
|
["Hukku"] = true,
|
||||||
|
["Hurley Blackbreath"] = true,
|
||||||
|
["Hydrospawn"] = true,
|
||||||
|
["Illyanna Ravenoak"] = true,
|
||||||
|
["Immol'thar"] = true,
|
||||||
|
["Instructor Malicia"] = true,
|
||||||
|
["Jammal'an the Prophet"] = true,
|
||||||
|
["Jandice Barov"] = true,
|
||||||
|
["King Gordok"] = true,
|
||||||
|
["Kirtonos the Herald"] = true,
|
||||||
|
["Lady Illucia Barov"] = true,
|
||||||
|
["Landslide"] = true,
|
||||||
|
["Lethtendris"] = true,
|
||||||
|
["Lord Alexei Barov"] = true,
|
||||||
|
["Lord Incendius"] = true,
|
||||||
|
["Lord Vyletongue"] = true,
|
||||||
|
["Lorekeeper Polkelt"] = true,
|
||||||
|
["Loro"] = true,
|
||||||
|
["Magister Kalendris"] = true,
|
||||||
|
["Magistrate Barthilas"] = true,
|
||||||
|
["Magmus"] = true,
|
||||||
|
["Maleki the Pallid"] = true,
|
||||||
|
["Marduk Blackpool"] = true,
|
||||||
|
["Meshlok the Harvester"] = true,
|
||||||
|
["Mijan"] = true,
|
||||||
|
["Morphaz"] = true,
|
||||||
|
["Mother Smolderweb"] = true,
|
||||||
|
["Nerub'enkan"] = true,
|
||||||
|
["Noxxion"] = true,
|
||||||
|
["Ogom the Wretched"] = true,
|
||||||
|
["Overlord Wyrmthalak"] = true,
|
||||||
|
["Phalanx"] = true,
|
||||||
|
["Plugger Spazzring"] = true,
|
||||||
|
["Postmaster Malown"] = true,
|
||||||
|
["Princess Moira Bronzebeard"] = true,
|
||||||
|
["Princess Theradras"] = true,
|
||||||
|
["Prince Tortheldrin"] = true,
|
||||||
|
["Pusillin"] = true,
|
||||||
|
["Pyroguard Emberseer"] = true,
|
||||||
|
["Ramstein the Gorger"] = true,
|
||||||
|
["Ras Frostwhisper"] = true,
|
||||||
|
["Rattlegore"] = true,
|
||||||
|
["Razorlash"] = true,
|
||||||
|
["Warchief Rend Blackhand"] = true,
|
||||||
|
["Ribbly Screwspigot"] = true,
|
||||||
|
["Rotgrip"] = true,
|
||||||
|
["Seeth'rel"] = true,
|
||||||
|
["Shade of Eranikus"] = true,
|
||||||
|
["Shadow Hunter Vosh'gajin"] = true,
|
||||||
|
["Solakar Flamewreath"] = true,
|
||||||
|
["Stomper Kreeg"] = true,
|
||||||
|
["Tendris Warpwood"] = true,
|
||||||
|
["The Beast"] = true,
|
||||||
|
["The Ravenian"] = true,
|
||||||
|
["Timmy the Cruel"] = true,
|
||||||
|
["Tinkerer Gizlock"] = true,
|
||||||
|
["Tsu'zee"] = true,
|
||||||
|
["Vectus"] = true,
|
||||||
|
["Vile'rel"] = true,
|
||||||
|
["War Master Voone"] = true,
|
||||||
|
["Weaver"] = true,
|
||||||
|
["Zevrim Thornhoof"] = true,
|
||||||
|
["Zolo"] = true,
|
||||||
|
["Zul'Lor"] = true,
|
||||||
|
|
||||||
|
-- From Mendeleev
|
||||||
|
["Cho'Rush the Observer"] = true,
|
||||||
|
["Lord Hel'nurath"] = true,
|
||||||
|
["Pimgib"] = true,
|
||||||
|
["Knot Thimblejack's Cache"] = true,
|
||||||
|
["Cannonmaster Willey"] = true,
|
||||||
|
["Emperor Dagran Thaurissian"] = true,
|
||||||
|
["Archmage Arugal"] = true,
|
||||||
|
["Archmage Arugal's Voidwalker"] = true,
|
||||||
|
["Baron Silverlaine"] = true,
|
||||||
|
["Commander Springvale"] = true,
|
||||||
|
["Prelate Ironmane"] = true,
|
||||||
|
["Deathsworn Captain"] = true,
|
||||||
|
["Fenrus the Devourer"] = true,
|
||||||
|
["Odo the Blindwatcher"] = true,
|
||||||
|
["Razorclaw the Butcher"] = true,
|
||||||
|
["Wolf Master Nandos"] = true,
|
||||||
|
["Rend Blackhand"] = true,
|
||||||
|
["Kurinnaxx"] = true,
|
||||||
|
|
||||||
|
-- From Zae for Kara 40
|
||||||
|
["Keeper Gnarlmoon"] = true,
|
||||||
|
["Ley-Watcher Incantagos"] = true,
|
||||||
|
["Anomalus"] = true,
|
||||||
|
["Echo of Medivh"] = true,
|
||||||
|
["King"] = true,
|
||||||
|
["Queen"] = true,
|
||||||
|
["Bishop"] = true,
|
||||||
|
["Rook"] = true,
|
||||||
|
["Ima'ghaol, Herald of Desolation"] = true,
|
||||||
|
["Sanv Tas'dal"] = true,
|
||||||
|
["Rupturan the Broken"] = true,
|
||||||
|
["Kruul"] = true,
|
||||||
|
["Mephistroth"] = true,
|
||||||
|
["Master Blacksmith Rolfen"] = true, -- Lower Kara
|
||||||
|
["Brood Queen Araxxna"] = true,
|
||||||
|
["Grizikil"] = true,
|
||||||
|
["Clawlord Howlfang"] = true,
|
||||||
|
["Lord Blackwald II"] = true,
|
||||||
|
["Moroes"] = true,
|
||||||
|
["Incindis"] = true, -- MC Update
|
||||||
|
["Basalthar"] = true,
|
||||||
|
["Smoldaris"] = true,
|
||||||
|
["Sorcerer-Thane Thaurissan"] = true,
|
||||||
|
["Solnius"] = true,
|
||||||
|
["Erennius"] = true,
|
||||||
|
|
||||||
|
-- Emerald Sanctum
|
||||||
|
["Sanctum Dragonkin"] = true,
|
||||||
|
["Sanctum Dreamer"] = true,
|
||||||
|
["Sanctum Supressor"] = true,
|
||||||
|
["Sanctum Wyrmkin"] = true,
|
||||||
|
["Sanctum Wyrm"] = true,
|
||||||
|
|
||||||
|
-- Black Morass
|
||||||
|
["Rotmaw"] = true,
|
||||||
|
["Antnormi"] = true,
|
||||||
|
["Mossheart"] = true,
|
||||||
|
["Time-Lord Epochronos"] = true,
|
||||||
|
["Drifting Avatar of Sand"] = true,
|
||||||
|
["Epidamu"] = true,
|
||||||
|
["Chronar"] = true,
|
||||||
|
|
||||||
|
-- TWoW world bosses
|
||||||
|
["Nerubian Overseer"] = true,
|
||||||
|
["Dark Reaver of Karazhan"] = true,
|
||||||
|
["Ostarius"] = true,
|
||||||
|
["Cla'ckora"] = true,
|
||||||
|
["Father Lycan"] = true,
|
||||||
|
["Snowball"] = true,
|
||||||
|
|
||||||
|
-- Low level dungeons
|
||||||
|
["Maur Grimtotem"] = true,
|
||||||
|
["Oggleflint"] = true,
|
||||||
|
["Taragaman the Hungerer"] = true,
|
||||||
|
["Jergosh the Invoker"] = true,
|
||||||
|
["Bazzalan"] = true,
|
||||||
|
["Disciple of Naralex"] = true,
|
||||||
|
["Lord Cobrahn"] = true,
|
||||||
|
["Lady Anacondra"] = true,
|
||||||
|
["Kresh"] = true,
|
||||||
|
["Lord Pythas"] = true,
|
||||||
|
["Skum"] = true,
|
||||||
|
["Lord Serpentis"] = true,
|
||||||
|
["Verdan the Everliving"] = true,
|
||||||
|
["Zandara Windhoof"] = true,
|
||||||
|
["Vangros"] = true,
|
||||||
|
["Mutanus the Devourer"] = true,
|
||||||
|
["Naralex"] = true,
|
||||||
|
["Deviate Faerie Dragon"] = true,
|
||||||
|
["Ghamoo-ra"] = true,
|
||||||
|
["Lady Sarevess"] = true,
|
||||||
|
["Gelihast"] = true,
|
||||||
|
["Lorgus Jett"] = true,
|
||||||
|
["Baron Aquanis"] = true,
|
||||||
|
["Velthelaxx the Defiler"] = true,
|
||||||
|
["Twilight Lord Kelris"] = true,
|
||||||
|
["Old Serra'kis"] = true,
|
||||||
|
["Aku'mai"] = true,
|
||||||
|
["Roogug"] = true,
|
||||||
|
["Aggem Thorncurse"] = true,
|
||||||
|
["Death Speaker Jargba"] = true,
|
||||||
|
["Overlord Ramtusk"] = true,
|
||||||
|
["Agathelos the Raging"] = true,
|
||||||
|
["Blind Hunter"] = true,
|
||||||
|
["Charlga Razorflank"] = true,
|
||||||
|
["Earthcaller Halmgar"] = true,
|
||||||
|
["Rotthorn"] = true,
|
||||||
|
["Tuten'kash"] = true,
|
||||||
|
["Lady Falther'ess"] = true,
|
||||||
|
["Mordresh Fire Eye"] = true,
|
||||||
|
["Glutton"] = true,
|
||||||
|
["Ragglesnout"] = true,
|
||||||
|
["Death Prophet Rakameg"] = true,
|
||||||
|
["Amnennar the Coldbringer"] = true,
|
||||||
|
["Plaguemaw the Rotting"] = true,
|
||||||
|
["Matthias Holtz"] = true,
|
||||||
|
["Packmaster Ragetooth"] = true,
|
||||||
|
["Judge Sutherland"] = true,
|
||||||
|
["Dustivan Blackcowl"] = true,
|
||||||
|
["Marshal Magnus Greystone"] = true,
|
||||||
|
["Horsemaster Levvin"] = true,
|
||||||
|
["Genn Greymane"] = true,
|
||||||
|
["Regent-Lord Mortimer Harlow"] = true,
|
||||||
|
["Antu'sul"] = true,
|
||||||
|
["Dustwraith"] = true,
|
||||||
|
["Zerillis"] = true,
|
||||||
|
["Witch Doctor Zum'rah"] = true,
|
||||||
|
["Shadowpriest Sezz'ziz"] = true,
|
||||||
|
["Gahz'rilla"] = true,
|
||||||
|
["Zel'jeb the Ancient"] = true,
|
||||||
|
["Champion Razjal the Quick"] = true,
|
||||||
|
["Chief Ukorz Sandscalp"] = true,
|
||||||
|
["Ruuzlu"] = true,
|
||||||
|
["Isalien"] = true,
|
||||||
|
["Revanchion"] = true,
|
||||||
|
["High Foreman Bargul Blackhammer"] = true,
|
||||||
|
["Engineer Figgles"] = true,
|
||||||
|
["Corrosis"] = true,
|
||||||
|
["Hatereaver Annihilator"] = true,
|
||||||
|
["Har'gesh Doomcaller"] = true,
|
||||||
|
["Lord Roccor"] = true,
|
||||||
|
["Anub'shiah"] = true,
|
||||||
|
["Eviscerator"] = true,
|
||||||
|
["Gorosh the Dervish"] = true,
|
||||||
|
["Grizzle"] = true,
|
||||||
|
["Hedrum the Creeper"] = true,
|
||||||
|
["Ok'thor the Breaker"] = true,
|
||||||
|
["Houndmaster Grebmar"] = true,
|
||||||
|
["Pyromancer Loregrain"] = true,
|
||||||
|
["Warder Stilgiss"] = true,
|
||||||
|
["Verek"] = true,
|
||||||
|
["Watchman Doomgrip"] = true,
|
||||||
|
["Panzor the Invincible"] = true,
|
||||||
|
["Mor Grayhoof"] = true,
|
||||||
|
["Bannok Grimaxe"] = true,
|
||||||
|
["Urok Doomhowl"] = true,
|
||||||
|
["Quartermaster Zigris"] = true,
|
||||||
|
["Gizrul the Slavener"] = true,
|
||||||
|
["Ghok Bashguud"] = true,
|
||||||
|
["Jed Runewatcher"] = true,
|
||||||
|
["Lord Valthalak"] = true,
|
||||||
|
["Grubbis"] = true,
|
||||||
|
["Chomper"] = true,
|
||||||
|
["Viscous Fallout"] = true,
|
||||||
|
["Electrocutioner 6000"] = true,
|
||||||
|
["Crowd Pummeler 9-60"] = true,
|
||||||
|
["Dark Iron Ambassador"] = true,
|
||||||
|
["Mekgineer Thermaplugg"] = true,
|
||||||
|
["Houndmaster Loksey"] = true,
|
||||||
|
["Brother Wynstan"] = true,
|
||||||
|
["Arcanist Doan"] = true,
|
||||||
|
["Armory Quartermaster Daghelm"] = true,
|
||||||
|
["Herod"] = true,
|
||||||
|
["High Inquisitor Fairbanks"] = true,
|
||||||
|
["Scarlet Commander Mograine"] = true,
|
||||||
|
["High Inquisitor Whitemane"] = true,
|
||||||
|
["Interrogator Vishas"] = true,
|
||||||
|
["Bloodmage Thalnos"] = true,
|
||||||
|
["Ironspine"] = true,
|
||||||
|
["Azshir the Sleepless"] = true,
|
||||||
|
["Fallen Champion"] = true,
|
||||||
|
["Oronok Torn-Heart"] = true,
|
||||||
|
["Dagar the Glutton"] = true,
|
||||||
|
["Duke Balor the IV"] = true,
|
||||||
|
["Librarian Theodorus"] = true,
|
||||||
|
["Chieftain Stormsong"] = true,
|
||||||
|
["Deathlord Tidebane"] = true,
|
||||||
|
["Subjugator Halthas Shadecrest"] = true,
|
||||||
|
["Mycellakos"] = true,
|
||||||
|
["Eldermaw the Primordial"] = true,
|
||||||
|
["Lady Drazare"] = true,
|
||||||
|
["Remains of the Innocent"] = true,
|
||||||
|
["Mergothid"] = true,
|
||||||
|
["Ighal'for"] = true,
|
||||||
|
["Death Knight Darkreaver"] = true,
|
||||||
|
["Kormok"] = true,
|
||||||
|
["Skul"] = true,
|
||||||
|
["Balzaphon"] = true,
|
||||||
|
["Malor the Zealous"] = true,
|
||||||
|
["Sothos"] = true,
|
||||||
|
["Jarien"] = true,
|
||||||
|
["Stonespine"] = true,
|
||||||
|
["Jared Voss"] = true,
|
||||||
|
["Rhahk'Zor"] = true,
|
||||||
|
["Miner Johnson"] = true,
|
||||||
|
["Masterpiece Harvester"] = true,
|
||||||
|
["Sneed"] = true,
|
||||||
|
["Gilnid"] = true,
|
||||||
|
["Captain Greenskin"] = true,
|
||||||
|
["Edwin VanCleef"] = true,
|
||||||
|
["Mr. Smite"] = true,
|
||||||
|
["Cookie"] = true,
|
||||||
|
["Targorr the Dread"] = true,
|
||||||
|
["Kam Deepfury"] = true,
|
||||||
|
["Hamhock"] = true,
|
||||||
|
["Bazil Thredd"] = true,
|
||||||
|
["Dextren Ward"] = true,
|
||||||
|
["Bruegal Ironknuckle"] = true,
|
||||||
|
["Gowlfang"] = true,
|
||||||
|
["Cavernweb Broodmother"] = true,
|
||||||
|
["Web Master Torkon"] = true,
|
||||||
|
["Garlok Flamekeeper"] = true,
|
||||||
|
["Halgan Redbrand"] = true,
|
||||||
|
["Slagfist Destroyer"] = true,
|
||||||
|
["Overlord Blackheart"] = true,
|
||||||
|
["Elder Hollowblood"] = true,
|
||||||
|
["Searistrasz"] = true,
|
||||||
|
["Zuluhed the Whacked"] = true,
|
||||||
|
["Duke Dreadmoore"] = true,
|
||||||
|
["Grovetender Engryss"] = true,
|
||||||
|
["Keeper Ranathos"] = true,
|
||||||
|
["High Priestess A'lathea"] = true,
|
||||||
|
["Fenektis the Deceiver"] = true,
|
||||||
|
["Master Raxxieth"] = true,
|
||||||
|
["Baelog"] = true,
|
||||||
|
["Eric \"The Swift\""] = true,
|
||||||
|
["Olaf"] = true,
|
||||||
|
["Revelosh"] = true,
|
||||||
|
["Ironaya"] = true,
|
||||||
|
["Obsidian Sentinel"] = true,
|
||||||
|
["Ancient Stone Keeper"] = true,
|
||||||
|
["Galgann Firehammer"] = true,
|
||||||
|
["Grimlok"] = true,
|
||||||
|
["Archaedas"] = true,
|
||||||
|
["Sever"] = true,
|
||||||
|
["Scorn"] = true,
|
||||||
|
["Rethilgore"] = true,
|
||||||
|
["Atiesh"] = true,
|
||||||
|
["Marrowspike"] = true,
|
||||||
|
["Hivaxxis"] = true,
|
||||||
|
["Corpsemuncher"] = true,
|
||||||
|
["Guard Captain Gort"] = true,
|
||||||
|
["Archlich Enkhraz"] = true,
|
||||||
|
["Commander Andreon"] = true,
|
||||||
|
["Alarus"] = true,
|
||||||
|
["Aszosh Grimflame"] = true,
|
||||||
|
["Tham'Grarr"] = true,
|
||||||
|
["Black Bride"] = true,
|
||||||
|
["Damian"] = true,
|
||||||
|
["Volkan Cruelblade"] = true,
|
||||||
|
["Arc'tiras"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
BabbleBoss = {}
|
||||||
|
function BabbleBoss:Contains(name)
|
||||||
|
return bosses[name]
|
||||||
|
end
|
||||||
@@ -0,0 +1,536 @@
|
|||||||
|
DPSMate.L["name"] = "DPSMate"
|
||||||
|
DPSMate.L["popup"] = "Do you want to reset DPSMate?"
|
||||||
|
DPSMate.L["memory"] = "DPSMate has collected a lot of data. This will cause screen lag during the data saving process upon logout. Do you want to reset DPSMate first?"
|
||||||
|
DPSMate.L["accept"] = "Accept"
|
||||||
|
DPSMate.L["decline"] = "Decline"
|
||||||
|
DPSMate.L["total"] = "Total"
|
||||||
|
DPSMate.L["current"] = "Current"
|
||||||
|
DPSMate.L["cancel"] = "Cancel"
|
||||||
|
DPSMate.L["report"] = "Report"
|
||||||
|
DPSMate.L["reportfor"] = "Report for "
|
||||||
|
|
||||||
|
-- Abilities
|
||||||
|
DPSMate.L["vanish"] = "Vanish"
|
||||||
|
DPSMate.L["feigndeath"] = "Feign Death"
|
||||||
|
DPSMate.L["divineintervention"] = "Divine Intervention"
|
||||||
|
DPSMate.L["stealth"] = "Stealth"
|
||||||
|
|
||||||
|
-- Evaluation frame
|
||||||
|
DPSMate.L["procs"] = "Procs"
|
||||||
|
DPSMate.L["procstooltip"] = "Select a proc to display it in the LineGraph."
|
||||||
|
DPSMate.L["absorbsby"] = "Absorbs by "
|
||||||
|
DPSMate.L["absorbstakenby"] = "Absorbstaken by "
|
||||||
|
DPSMate.L["aurasof"] = "Auras of "
|
||||||
|
DPSMate.L["BUDEBU"] = {"Buffs", "Debuffs"}
|
||||||
|
DPSMate.L["castsof"] = "Casts of "
|
||||||
|
DPSMate.L["bname"] = "Name"
|
||||||
|
DPSMate.L["count"] = "Count"
|
||||||
|
DPSMate.L["uptime"] = "Uptime"
|
||||||
|
DPSMate.L["chance"] = "Chance"
|
||||||
|
DPSMate.L["ccbreakerof"] = "CCBreaker of "
|
||||||
|
DPSMate.L["time"] = "Time"
|
||||||
|
DPSMate.L["cbt"] = "CBT"
|
||||||
|
DPSMate.L["ability"] = "Ability"
|
||||||
|
DPSMate.L["target"] = "Target"
|
||||||
|
DPSMate.L["diseasecuredby"] = "Disease cured by "
|
||||||
|
DPSMate.L["diseasecuredof"] = "Disease cured of "
|
||||||
|
DPSMate.L["poisoncuredby"] = "Poison cured by "
|
||||||
|
DPSMate.L["poisoncuredof"] = "Poison cured of "
|
||||||
|
DPSMate.L["dmgdoneby"] = "Damage done by "
|
||||||
|
DPSMate.L["dmgtakenby"] = "Damage taken by "
|
||||||
|
DPSMate.L["dmgtakensum"] = "Damage taken summary"
|
||||||
|
DPSMate.L["dmgdonesum"] = "Damage done summary"
|
||||||
|
DPSMate.L["deathsof"] = "Deaths of "
|
||||||
|
DPSMate.L["cause"] = "Cause"
|
||||||
|
DPSMate.L["type"] = "Type"
|
||||||
|
DPSMate.L["healin"] = "Heal In"
|
||||||
|
DPSMate.L["damagein"] = "Damage In"
|
||||||
|
DPSMate.L["decursesby"] = "Decurses by "
|
||||||
|
DPSMate.L["decursesreceivedby"] = "Decurses received of "
|
||||||
|
DPSMate.L["dispelsby"] = "Dispels by "
|
||||||
|
DPSMate.L["dispelsreceivedby"] = "Dispels received of "
|
||||||
|
DPSMate.L["block"] = "Block"
|
||||||
|
DPSMate.L["crush"] = "Crush"
|
||||||
|
DPSMate.L["hit"] = "Hit"
|
||||||
|
DPSMate.L["average"] = "Average"
|
||||||
|
DPSMate.L["min"] = "Min"
|
||||||
|
DPSMate.L["max"] = "Max"
|
||||||
|
DPSMate.L["crit"] = "Crit"
|
||||||
|
DPSMate.L["miss"] = "Miss"
|
||||||
|
DPSMate.L["parry"] = "Parry"
|
||||||
|
DPSMate.L["dodge"] = "Dodge"
|
||||||
|
DPSMate.L["resist"] = "Resist"
|
||||||
|
DPSMate.L["glance"] = "Glance"
|
||||||
|
DPSMate.L["effhealdoneby"] = "Effective healing done by "
|
||||||
|
DPSMate.L["effhealtakenby"] = "Effective healing taken by "
|
||||||
|
DPSMate.L["failsof"] = "Fails of "
|
||||||
|
DPSMate.L["victim"] = "Victim"
|
||||||
|
DPSMate.L["ffby"] = "Friendly fire by "
|
||||||
|
DPSMate.L["healdoneby"] = "Healing done by "
|
||||||
|
DPSMate.L["habby"] = "Healing and Absorbs by "
|
||||||
|
DPSMate.L["healtakenby"] = "Healing taken by "
|
||||||
|
DPSMate.L["interruptsby"] = "Interrupts by "
|
||||||
|
DPSMate.L["magicliftby"] = "Magic lifted by "
|
||||||
|
DPSMate.L["magicliftof"] = "Magic lifted of "
|
||||||
|
DPSMate.L["overhealby"] = "Overhealing done by "
|
||||||
|
DPSMate.L["procsof"] = "Procs of "
|
||||||
|
|
||||||
|
-- Menu
|
||||||
|
DPSMate.L["mdps"] = "Show dps."
|
||||||
|
DPSMate.L["mdmg"] = "Show damage done."
|
||||||
|
DPSMate.L["mdmgtaken"] = "Show damage taken."
|
||||||
|
DPSMate.L["medd"] = "Show the damage done by enemies."
|
||||||
|
DPSMate.L["medt"] = "Show the damage that enemies took."
|
||||||
|
DPSMate.L["mhealing"] = "Show efficient healing."
|
||||||
|
DPSMate.L["mhab"] = "Show efficient healing with absorbs."
|
||||||
|
DPSMate.L["mhealingtaken"] = "Show healing taken."
|
||||||
|
DPSMate.L["moverhealing"] = "Show overhealing done."
|
||||||
|
DPSMate.L["minterrupts"] = "Show interrupts done."
|
||||||
|
DPSMate.L["mdeaths"] = "Show deaths."
|
||||||
|
DPSMate.L["mdispels"] = "Show dispels done."
|
||||||
|
DPSMate.L["totalmode"] = "Set to total mode."
|
||||||
|
DPSMate.L["currentmode"] = "Set to current mode."
|
||||||
|
DPSMate.L["reportsegment"] = "Report this segment."
|
||||||
|
DPSMate.L["resetdesc"] = "Reset DPSMate."
|
||||||
|
DPSMate.L["newsegment"] = "New segment"
|
||||||
|
DPSMate.L["newsegmentdesc"] = "Start a new segment."
|
||||||
|
DPSMate.L["removesegment"] = "Remove segment"
|
||||||
|
DPSMate.L["removesegmentdesc"] = "Remove an segment."
|
||||||
|
DPSMate.L["purgeoldsegments"] = "Delete segments > 24h"
|
||||||
|
DPSMate.L["purgeoldsegmentsdesc"] = "Delete all saved segments older than 24 hours."
|
||||||
|
DPSMate.L["purgeoldsegmentsdone"] = "Segments older than 24 hours have been deleted."
|
||||||
|
DPSMate.L["purgenotimestamp"] = "24h purge unavailable: time() is not exposed on this server."
|
||||||
|
DPSMate.L["lockdesc"] = "Lock the DPSMate frame."
|
||||||
|
DPSMate.L["hidewindowdesc"] = "Hide the DPSMate frame."
|
||||||
|
DPSMate.L["showwindowdesc"] = "Show the DPSMate frame."
|
||||||
|
DPSMate.L["configframe"] = "Open the configuration frame."
|
||||||
|
DPSMate.L["testmodedesc"] = "Toggle the test mode."
|
||||||
|
DPSMate.L["filterdesc"] = "Filter options."
|
||||||
|
DPSMate.L["switchdesc"] = "Switch mode"
|
||||||
|
DPSMate.L["mcurrent"] = "Current fight"
|
||||||
|
DPSMate.L["mrealtime"] = "Create realtime graph"
|
||||||
|
DPSMate.L["mrealtimedesc"] = 'Create a realtime graph. Be aware it takes a lot of ressources.'
|
||||||
|
DPSMate.L["damagedone"] = "Damage done"
|
||||||
|
DPSMate.L["realtimedmgdone"] = 'Select damage done for this frame.'
|
||||||
|
DPSMate.L["realtimedmgtaken"] = 'Select damage taken for this frame.'
|
||||||
|
DPSMate.L["realtimehealing"] = 'Select raw healing for this frame.'
|
||||||
|
DPSMate.L["realtimeehealing"] = 'Select effective healing for this frame.'
|
||||||
|
DPSMate.L["showAll"] = "Show all"
|
||||||
|
DPSMate.L["showAllDesc"] = 'Click to show all frames'
|
||||||
|
DPSMate.L["hideAll"] = "Hide all"
|
||||||
|
DPSMate.L["hideAllDesc"] = 'Click to hide all frames'
|
||||||
|
DPSMate.L["showwindow"] = "Show window"
|
||||||
|
DPSMate.L["hidewindow"] = "Hide window"
|
||||||
|
DPSMate.L["unlock"] = "Unlock windows"
|
||||||
|
DPSMate.L["config"] = "Configure"
|
||||||
|
DPSMate.L["reportdesc"] = "Report details"
|
||||||
|
DPSMate.L["whisper"] = "Whisper"
|
||||||
|
DPSMate.L["whisperdesc"] = "Whisper someone"
|
||||||
|
DPSMate.L["classes"] = "Classes"
|
||||||
|
DPSMate.L["classesdesc"] = "Select classes"
|
||||||
|
DPSMate.L["warrior"] = "Warrior"
|
||||||
|
DPSMate.L["rogue"] = "Rogue"
|
||||||
|
DPSMate.L["warlock"] = "Warlock"
|
||||||
|
DPSMate.L["mage"] = "Mage"
|
||||||
|
DPSMate.L["paladin"] = "Paladin"
|
||||||
|
DPSMate.L["shaman"] = "Shaman"
|
||||||
|
DPSMate.L["priest"] = "Priest"
|
||||||
|
DPSMate.L["druid"] = "Druid"
|
||||||
|
DPSMate.L["hunter"] = "Hunter"
|
||||||
|
DPSMate.L["warriordesc"] = "Show warrior"
|
||||||
|
DPSMate.L["roguedesc"] = "Show rogues"
|
||||||
|
DPSMate.L["warlockdesc"] = "Show warlocks"
|
||||||
|
DPSMate.L["magedesc"] = "Show mages"
|
||||||
|
DPSMate.L["paladindesc"] = "Show paladins"
|
||||||
|
DPSMate.L["shamandesc"] = "Show shaman"
|
||||||
|
DPSMate.L["priestdesc"] = "Show priest"
|
||||||
|
DPSMate.L["druiddesc"] = "Show druids"
|
||||||
|
DPSMate.L["hunterdesc"] = "Show hunter"
|
||||||
|
DPSMate.L["certainnames"] = "Certain names"
|
||||||
|
DPSMate.L["certainnamesdesc"] = 'Split them by "," Ex: Shino,'
|
||||||
|
DPSMate.L["grouponly"] = "Group only"
|
||||||
|
DPSMate.L["grouponlydesc"] = "Only show your group"
|
||||||
|
|
||||||
|
-- Config menu
|
||||||
|
DPSMate.L["slider"] = "Lines"
|
||||||
|
DPSMate.L["slidertooltip"] = "Move this to set the amount of lines that will be reported."
|
||||||
|
DPSMate.L["editboxtitle"] = "Whisper Target"
|
||||||
|
DPSMate.L["editboxtooltip"] = "Enter the name you'd like to report to."
|
||||||
|
DPSMate.L["channel"] = "Channel"
|
||||||
|
DPSMate.L["channeltooltip"] = "Select the channel you'd like to submit your report."
|
||||||
|
DPSMate.L["close"] = "Close"
|
||||||
|
DPSMate.L["minimapleft"] = "LeftClick-Drag to move the icon."
|
||||||
|
DPSMate.L["minimapright"] = "RightClick to open the menu."
|
||||||
|
DPSMate.L["window"] = "Window"
|
||||||
|
DPSMate.L["bars"] = "Bars"
|
||||||
|
DPSMate.L["titlebar"] = "Title bar"
|
||||||
|
DPSMate.L["content"] = "Content"
|
||||||
|
DPSMate.L["modeswitching"] = "Mode switching"
|
||||||
|
DPSMate.L["dataresets"] = "Data resets"
|
||||||
|
DPSMate.L["generaloptions"] = "General options"
|
||||||
|
DPSMate.L["columns"] = "Columns"
|
||||||
|
DPSMate.L["tooltips"] = "Tooltips"
|
||||||
|
DPSMate.L["broadcasting"] = "Broadcasting options"
|
||||||
|
DPSMate.L["about"] = "About"
|
||||||
|
DPSMate.L["createwindow"] = "Create window"
|
||||||
|
DPSMate.L["createwindowtooltip"] = "Enter the name of the window."
|
||||||
|
DPSMate.L["submit"] = "Submit"
|
||||||
|
DPSMate.L["submitTooltip"] = "Click here to create the window."
|
||||||
|
DPSMate.L["availwindows"] = "Available windows"
|
||||||
|
DPSMate.L["availwindowsTooltip"] = "Select a window."
|
||||||
|
DPSMate.L["lock"] = "Lock windows"
|
||||||
|
DPSMate.L["testmode"] = "Test mode"
|
||||||
|
DPSMate.L["barfont"] = "Bar font"
|
||||||
|
DPSMate.L["barfontTooltip"] = "Select a bar font."
|
||||||
|
DPSMate.L["barfontsize"] = "Bar font size"
|
||||||
|
DPSMate.L["barfontsizeTooltip"] = "Move this to change the bar font size."
|
||||||
|
DPSMate.L["barfontflags"] = "Bar font flags"
|
||||||
|
DPSMate.L["barfontflagsTooltip"] = "Select a font flag."
|
||||||
|
DPSMate.L["bartexture"] = "Bar texture"
|
||||||
|
DPSMate.L["bartextureTooltip"] = "Select a bar texture."
|
||||||
|
DPSMate.L["barspacing"] = "Bar spacing"
|
||||||
|
DPSMate.L["barspacingTooltip"] = "Move this to change the spacing between the bars."
|
||||||
|
DPSMate.L["barheight"] = "Bar height"
|
||||||
|
DPSMate.L["barheightTooltip"] = "Move this to change the bar height."
|
||||||
|
DPSMate.L["classicons"] = "Class icons"
|
||||||
|
DPSMate.L["ranks"] = "Ranks"
|
||||||
|
DPSMate.L["mode"] = "Mode"
|
||||||
|
DPSMate.L["modes"] = "Modes"
|
||||||
|
DPSMate.L["reset"] = "Reset"
|
||||||
|
DPSMate.L["sync"] = "Synchronizing"
|
||||||
|
DPSMate.L["bgcolor"] = "Background color"
|
||||||
|
DPSMate.L["fontcolor"] = "Font color"
|
||||||
|
DPSMate.L["fontcolorTooltip"] = "Click to choose a font color."
|
||||||
|
DPSMate.L["bgcolorTooltip"] = "Click to choose a background color."
|
||||||
|
DPSMate.L["scale"] = "Scale"
|
||||||
|
DPSMate.L["scaleTooltip"] = "Move this to change the scale of the frame."
|
||||||
|
DPSMate.L["opacity"] = "Opacity"
|
||||||
|
DPSMate.L["opacityTooltip"] = "Move this to change the opacity of the frame."
|
||||||
|
DPSMate.L["bgtex"] = "Background texture"
|
||||||
|
DPSMate.L["bgtexTooltip"] = "Change the texture of the frame."
|
||||||
|
DPSMate.L["enterworldinstance"] = "World/Instance"
|
||||||
|
DPSMate.L["enterworldinstanceTooltip"] = "Reset on entering world or instance"
|
||||||
|
DPSMate.L["joinparty"] = "Joining a party"
|
||||||
|
DPSMate.L["joinpartyTooltip"] = "Reset on joining a party"
|
||||||
|
DPSMate.L["leavingparty"] = "Leaving a party"
|
||||||
|
DPSMate.L["leavingpartyTooltip"] = "Reset on leaving a party"
|
||||||
|
DPSMate.L["partymemberchanged"] = "Party amount changed"
|
||||||
|
DPSMate.L["partymemberchangedTooltip"] = "Reset on party member amount changed"
|
||||||
|
DPSMate.L["minimap"] = "Show minimap button"
|
||||||
|
DPSMate.L["showtotal"] = "Show totals"
|
||||||
|
DPSMate.L["solo"] = "Hide when solo"
|
||||||
|
DPSMate.L["combat"] = "Hide in combat"
|
||||||
|
DPSMate.L["bossfights"] = "Only keep boss fights"
|
||||||
|
DPSMate.L["pvp"] = "Hide in PVP"
|
||||||
|
DPSMate.L["disable"] = "Disable while hidden"
|
||||||
|
DPSMate.L["mergepets"] = "Merge pets"
|
||||||
|
DPSMate.L["numberformat"] = "Number format"
|
||||||
|
DPSMate.L["numberformatTooltip"] = "Controls how numbers are displayed."
|
||||||
|
DPSMate.L["segments"] = "Data segments to keep"
|
||||||
|
DPSMate.L["segmentsTooltip"] = "Move this to increase the amount of fight segments that are saved. This increases data collection a lot and may cause lag!"
|
||||||
|
DPSMate.L["enable"] = "Enable"
|
||||||
|
DPSMate.L["damage"] = "Damage"
|
||||||
|
DPSMate.L["percent"] = "Percent"
|
||||||
|
DPSMate.L["dps"] = "DPS"
|
||||||
|
DPSMate.L["edps"] = "EDPS"
|
||||||
|
DPSMate.L["dtps"] = "DTPS"
|
||||||
|
DPSMate.L["edtps"] = "EDTPS"
|
||||||
|
DPSMate.L["healing"] = "Healing"
|
||||||
|
DPSMate.L["hps"] = "HPS"
|
||||||
|
DPSMate.L["ehps"] = "EHPS"
|
||||||
|
DPSMate.L["etps"] = "ETPS"
|
||||||
|
DPSMate.L["damagetaken"] = "Damage taken"
|
||||||
|
DPSMate.L["enemydamagedone"] = "Enemy damage done"
|
||||||
|
DPSMate.L["enemydamagetaken"] = "Enemy damage taken"
|
||||||
|
DPSMate.L["healing"] = "Healing"
|
||||||
|
DPSMate.L["absorbs"] = "Absorbs"
|
||||||
|
DPSMate.L["absorbstaken"] = "Absorbs taken"
|
||||||
|
DPSMate.L["amount"] = "Amount"
|
||||||
|
DPSMate.L["dispelsreceived"] = "Dispels received"
|
||||||
|
DPSMate.L["decurses"] = "Decurses"
|
||||||
|
DPSMate.L["decursesreceived"] = "Decurses received"
|
||||||
|
DPSMate.L["curedisease"] = "Diseases cured"
|
||||||
|
DPSMate.L["curepoison"] = "Poisons cured"
|
||||||
|
DPSMate.L["liftmagic"] = "Magic lifted"
|
||||||
|
DPSMate.L["aurasgained"] = "Auras gained"
|
||||||
|
DPSMate.L["auraslost"] = "Auras lost"
|
||||||
|
DPSMate.L["aurauptime"] = "Aura uptime"
|
||||||
|
DPSMate.L["friendlyfire"] = "Friendly fire"
|
||||||
|
DPSMate.L["procs"] = "Procs"
|
||||||
|
DPSMate.L["liftmagicreceived"] = "Magic lift received"
|
||||||
|
DPSMate.L["curepoisonreceived"] = "Poison cure received"
|
||||||
|
DPSMate.L["curediseasereceived"] = "Disease cure received"
|
||||||
|
DPSMate.L["effectivehealing"] = "Effective healing"
|
||||||
|
DPSMate.L["effectivehps"] = "Effective HPS"
|
||||||
|
DPSMate.L["effectivehealingtaken"] = "Effective healing taken"
|
||||||
|
DPSMate.L["healingandabsorbs"] = "Healing and Absorbs"
|
||||||
|
DPSMate.L["healingtaken"] = "Healing taken"
|
||||||
|
DPSMate.L["overhealing"] = "Overhealing"
|
||||||
|
DPSMate.L["interrupts"] = "Interrupts"
|
||||||
|
DPSMate.L["deaths"] = "Deaths"
|
||||||
|
DPSMate.L["dispels"] = "Dispels"
|
||||||
|
DPSMate.L["threat"] = "Threat"
|
||||||
|
DPSMate.L["tps"] = "TPS"
|
||||||
|
DPSMate.L["fails"] = "Fails"
|
||||||
|
DPSMate.L["cat"] = "Category"
|
||||||
|
DPSMate.L["ccbreaker"] = "CCBreaker"
|
||||||
|
DPSMate.L["subviewrows"] = "Subview rows"
|
||||||
|
DPSMate.L["subviewrowsTooltip"] = "Move this to change the amount of rows displayed in the tooltip."
|
||||||
|
DPSMate.L["TooltipPositionDropDown"] = "Tooltip position"
|
||||||
|
DPSMate.L["TooltipPositionDropDownTooltip"] = "Select the position of the tooltip relative to the frame."
|
||||||
|
DPSMate.L["whatisdpsmate"] = "What is DPSMate?"
|
||||||
|
DPSMate.L["whatisdpsmateText"] = "DPSMate is a combat analyzing tool. It provides a lot of functions to review the fight as accurately as possible. By this information gameplay improvements are easy to evaluate."
|
||||||
|
DPSMate.L["whocreateddpsmate"] = "Who created DPSMate?"
|
||||||
|
DPSMate.L["whocreateddpsmateText"] = "DPSMate was created by Shino (Albea) <Synced> who developed the AddOn on Kronos (Twinstar.cz). He is formally known as Geigerkind in the Twinstar community."
|
||||||
|
DPSMate.L["thanksto"] = "Thanks to following supporters:"
|
||||||
|
DPSMate.L["thankstoText"] = "Weasel - For beta testing and providing feedback. \nBambustreppe - For translating DPSMate to german. \nDreamstate - For beta testing DPSMate TBC and providing nice suggestions for features. \nMaus - Huge thanks for the full ruRU translation. \nITTranslator - For translating DPSMate to french. \nDarkmiao - For translating DPSMate to mandarin."
|
||||||
|
DPSMate.L["remove"] = "Remove"
|
||||||
|
DPSMate.L["removeTooltip"] = "Click here in order to remove the selected window."
|
||||||
|
DPSMate.L["copy"] = "Copy"
|
||||||
|
DPSMate.L["copyTooltip"] = "Click here to copy the configuration to the selected window."
|
||||||
|
DPSMate.L["configto"] = "Copy configuration to:"
|
||||||
|
DPSMate.L["configtoTooltip"] = "Select the window you want to configure."
|
||||||
|
DPSMate.L["configfrom"] = "Copy configuration from:"
|
||||||
|
DPSMate.L["configfromTooltip"] = "Select the windows you want to copy the configuration from."
|
||||||
|
DPSMate.L["reset"] = "Reset"
|
||||||
|
DPSMate.L["syncrequest"] = "Sync reset request"
|
||||||
|
DPSMate.L["syncrequesttooltip"] = "What happens if an sync reset request pops up."
|
||||||
|
DPSMate.L["dataresetslogout"] = "Logout reset request"
|
||||||
|
DPSMate.L["dataresetslogouttooltip"] = "Reset on logout"
|
||||||
|
DPSMate.L["enabledisable"] = "Enable/Disable"
|
||||||
|
DPSMate.L["bgbarcolor"] = "Background bar color"
|
||||||
|
DPSMate.L["bgbarcolorTooltip"] = "Click to choose a background bar color."
|
||||||
|
DPSMate.L["displayoptions"] = "Display options"
|
||||||
|
DPSMate.L["filter"] = "Filter options"
|
||||||
|
DPSMate.L["raidleader"] = "Raid leader options"
|
||||||
|
DPSMate.L["bgOpacityTooltip"] = "Adjust the opacity of the background."
|
||||||
|
DPSMate.L["bgOpacity"] = "Background opacity"
|
||||||
|
DPSMate.L["casts"] = "Casts"
|
||||||
|
DPSMate.L["locktooltip"] = "Check this to lock the frames."
|
||||||
|
DPSMate.L["testmodetooltip"] = "Check this to activate the testmode."
|
||||||
|
DPSMate.L["classiconstooltip"] = "Check this to show additions classicons on the statusbars."
|
||||||
|
DPSMate.L["rankstooltip"] = "Check this to show the rank position in the meter."
|
||||||
|
DPSMate.L["enabletitlebartooltip"] = "Check this to enable the title bar."
|
||||||
|
DPSMate.L["buttonshowtooltip"] = "Check this to show this icon on the titlebar."
|
||||||
|
DPSMate.L["minimaptooltip"] = "Check this to show the minimap icon."
|
||||||
|
DPSMate.L["showtotaltooltip"] = "Check this to get an extra bar for total stats."
|
||||||
|
DPSMate.L["solotooltip"] = "Check this to hide the frame when you are not in a group or raid."
|
||||||
|
DPSMate.L["combattooltip"] = "Check this to hide the frame when you enter combat."
|
||||||
|
DPSMate.L["bossfightstooltip"] = "Check this to only save boss fights."
|
||||||
|
DPSMate.L["pvptooltip"] = "Check this to hide the frame when you enter a battleground."
|
||||||
|
DPSMate.L["disabletooltip"] = "Check this to disable data collection when the frames are hidden."
|
||||||
|
DPSMate.L["mergepetstooltip"] = "Check this to merge pets with their respective owner."
|
||||||
|
DPSMate.L["showtooltips"] = "Show tooltips"
|
||||||
|
DPSMate.L["showtooltipsTooltip"] = "Check this to show tooltips when you hover over something."
|
||||||
|
DPSMate.L["informativetooltips"] = "Informative tooltips"
|
||||||
|
DPSMate.L["informativetooltipsTooltip"] = "Check this to render tooltips with more details."
|
||||||
|
DPSMate.L["shownmodes"] = "Shown modes"
|
||||||
|
DPSMate.L["hiddenmodes"] = "Hidden modes"
|
||||||
|
DPSMate.L["moveleftTooltip"] = "Click to show thise mode."
|
||||||
|
DPSMate.L["moverightTooltip"] = "Click to hide this mode."
|
||||||
|
DPSMate.L["helloworld"] = "Hello World!"
|
||||||
|
DPSMate.L["helloworldTooltip"] = "Return a list of player being in the Synced-Channel."
|
||||||
|
DPSMate.L["enablebroadcasting"] = "Check this to enable the broadcasting options below."
|
||||||
|
DPSMate.L["useraidwarning"] = "Use raidwarning"
|
||||||
|
DPSMate.L["useraidwarningTooltip"] = "Check this to use the raid warning channel instead of the raid channel."
|
||||||
|
DPSMate.L["relevantcds"] = "Relevant cooldowns"
|
||||||
|
DPSMate.L["relevantcdsTooltip"] = "Check this to broadcast relevant cooldowns like Shield Wall for example."
|
||||||
|
DPSMate.L["ress"] = "Ressurections"
|
||||||
|
DPSMate.L["ressTooltip"] = "Check this to broadcast if someone received a ress."
|
||||||
|
DPSMate.L["killingblows"] = "Killingblows"
|
||||||
|
DPSMate.L["killingblowsTooltip"] = "Check this to broadcast killing blow information if a player died."
|
||||||
|
DPSMate.L["failsTooltip"] = "Check this to broadcast if a player failed. (Friendly Fire/Damage taken/Debuff taken)"
|
||||||
|
DPSMate.L["framesavailable"] = "Following frames are available. If there is none type /config."
|
||||||
|
DPSMate.L["slashabout"] = "|c3ffddd80About:|r A combat analyzation tool."
|
||||||
|
DPSMate.L["slashusage"] = "|c3ffddd80Usage:|r /dps {lock|unlock|show|hide|config}"
|
||||||
|
DPSMate.L["slashlock"] = "|c3ffddd80- lock:|r Lock your windows."
|
||||||
|
DPSMate.L["slashunlock"] = "|c3ffddd80- unlock:|r Unlock your windows."
|
||||||
|
DPSMate.L["slashshowAll"] = "|c3ffddd80- showAll:|r Show all windows."
|
||||||
|
DPSMate.L["slashhideAll"] = "|c3ffddd80- hideAll:|r Hide all windows."
|
||||||
|
DPSMate.L["slashshow"] = "|c3ffddd80- show {name}:|r Show the window with the name {name}."
|
||||||
|
DPSMate.L["slashhide"] = "|c3ffddd80- hide {name}:|r Hide the window with the name {name}."
|
||||||
|
DPSMate.L["slashconfig"] = "|c3ffddd80- config:|r Opens the config menu."
|
||||||
|
DPSMate.L["slashreset"] = "|c3ffddd80- reset:|r Wipes all saved data (players, abilities, history, metrics)."
|
||||||
|
DPSMate.L["resetconfirm"] = "Are you sure you want to reset ALL DPSMate data? This cannot be undone. Type /dps resetconfirm to proceed."
|
||||||
|
DPSMate.L["resetdone"] = "All DPSMate data has been reset."
|
||||||
|
DPSMate.L["bccdo"] = function(who, what) return who.." gained "..what end
|
||||||
|
DPSMate.L["bccdt"] = function(who, what) return who.."'s "..what.." faded" end
|
||||||
|
DPSMate.L["bcress"] = function(who, what) return what.." has been resurrected by "..who end
|
||||||
|
DPSMate.L["bckb"] = function(who, what, with, value) return who.." has been killed by "..what.."'s "..with.." ("..value.." damage)" end
|
||||||
|
DPSMate.L["bcfailo"] = function(what, who, value, with) return "Fail: "..what.." friendly fired "..who.." "..value.." damage with "..with end
|
||||||
|
DPSMate.L["bcfailt"] = function(who, with) return "Fail: "..who.." is afflicted by "..with end
|
||||||
|
DPSMate.L["bcfailth"] = function(who, value, with, what) return "Fail: "..who.." suffered "..value.." damage from "..with.." by "..what end
|
||||||
|
DPSMate.L["syncreseterror"] = "DPSMate cant be reset while being in Sync-Mode in raids."
|
||||||
|
DPSMate.L["resetnotofficererror"] = "You are not the leader of the group or an assist!"
|
||||||
|
DPSMate.L["findusererror"] = "Could not find this user!"
|
||||||
|
DPSMate.L["yes"] = "Yes"
|
||||||
|
DPSMate.L["no"] = "No"
|
||||||
|
DPSMate.L["ask"] = "Ask"
|
||||||
|
DPSMate.L["normal"] = "Normal"
|
||||||
|
DPSMate.L["condensed"] = "Condensed"
|
||||||
|
DPSMate.L["default"] = "Default"
|
||||||
|
DPSMate.L["topright"] = "Top Right"
|
||||||
|
DPSMate.L["topleft"] = "Top Left"
|
||||||
|
DPSMate.L["left"] = "Left"
|
||||||
|
DPSMate.L["top"] = "Top"
|
||||||
|
DPSMate.L["gchannel"] = {[1]="Raid",[2]="Party",[3]="Say",[4]="Officer",[5]="Guild"}
|
||||||
|
DPSMate.L["nodetailserror"] = "There are no details to be reported."
|
||||||
|
DPSMate.L["reportof"] = "Report of"
|
||||||
|
DPSMate.L["opendetails"] = "Open details"
|
||||||
|
DPSMate.L["reportdetails"] = "Report the details of this user."
|
||||||
|
DPSMate.L["fdetailsfor"] = "Fight details for "
|
||||||
|
DPSMate.L["removesegmentof"] = "Remove segment of "
|
||||||
|
DPSMate.L["lockedallw"] = "Locked all windows."
|
||||||
|
DPSMate.L["unlockedallw"] = "Unlocked all windows."
|
||||||
|
DPSMate.L["leftclickopend"] = "LeftClick to open the details."
|
||||||
|
DPSMate.L["rightclickopenm"] = "RightClick to open the menu."
|
||||||
|
DPSMate.L["hide"] = "Hide"
|
||||||
|
DPSMate.L["show"] = "Show"
|
||||||
|
DPSMate.L["rcchangemode"] = "RightClick to change the mode."
|
||||||
|
DPSMate.L["segment"] = "Segment"
|
||||||
|
DPSMate.L["sync"] = "Synchronising"
|
||||||
|
DPSMate.L["alliance"] = "Alliance"
|
||||||
|
DPSMate.L["horde"] = "Horde"
|
||||||
|
DPSMate.L["unknown"] = "Unknown"
|
||||||
|
DPSMate.L["votestartederror"] = "Vote has already been started!"
|
||||||
|
DPSMate.L["votefailederror"] = "Reset vote failed!"
|
||||||
|
DPSMate.L["votesuccess"] = "Reset vote was successful! DPSMate has been reset!"
|
||||||
|
DPSMate.L["disease"] = "Disease"
|
||||||
|
DPSMate.L["magic"] = "Magic"
|
||||||
|
DPSMate.L["curse"] = "Curse"
|
||||||
|
DPSMate.L["poison"] = "Poison"
|
||||||
|
DPSMate.L["physical"] = "Physical"
|
||||||
|
DPSMate.L["debufftaken"] = "Debuff taken"
|
||||||
|
DPSMate.L["buffs"] = "Buffs"
|
||||||
|
DPSMate.L["debuffs"] = "Debuffs"
|
||||||
|
|
||||||
|
DPSMate.L["mc"] = "Molten Core"
|
||||||
|
DPSMate.L["bwl"] = "Blackwing Lair"
|
||||||
|
DPSMate.L["ony"] = "Onyxia's Lair"
|
||||||
|
DPSMate.L["zg"] = "Zul'Gurub"
|
||||||
|
DPSMate.L["aq401"] = "Ruins of Ahn'Qiraj"
|
||||||
|
DPSMate.L["aq20"] = "Temple of Ahn'Qiraj"
|
||||||
|
DPSMate.L["aq402"] = "Ahn'Qiraj"
|
||||||
|
DPSMate.L["naxx"] = "Naxxramas"
|
||||||
|
DPSMate.L["azs"] = "Azshara"
|
||||||
|
DPSMate.L["bl"] = "Blasted Lands"
|
||||||
|
DPSMate.L["dw"] = "Duskwood"
|
||||||
|
DPSMate.L["hintl"] = "Hinterlands"
|
||||||
|
DPSMate.L["ash"] = "Ashenvale"
|
||||||
|
DPSMate.L["fe"] = "Feralas"
|
||||||
|
|
||||||
|
DPSMate.L["switchgraphsdesc"] = "Switch graphs"
|
||||||
|
DPSMate.L["switchindividualsdesc"] = "Individual/Total"
|
||||||
|
DPSMate.L["OHPS"] = "OHPS"
|
||||||
|
DPSMate.L["OHealingTaken"] = "Overhealing taken"
|
||||||
|
DPSMate.L["eohps"] = "EOHPS"
|
||||||
|
DPSMate.L["ohealtakenby"] = "Overhealing taken by "
|
||||||
|
DPSMate.L["friendlyfiretaken"] = "Friendly fire taken"
|
||||||
|
DPSMate.L["fftby"] = "Friendly fire taken by "
|
||||||
|
DPSMate.L["poisoncleansingtotem"] = "Poison Cleansing Totem"
|
||||||
|
DPSMate.L["threatdoneby"] = "Threat done by "
|
||||||
|
DPSMate.L["periodic"] = "(Periodic)"
|
||||||
|
DPSMate.L["reportchannel"] = {[1]="Whisper",[2]="Raid",[3]="Party",[4]="Say",[5]="Officer",[6]="Guild"}
|
||||||
|
DPSMate.L["raid"] = "Raid"
|
||||||
|
DPSMate.L["activity"] = "Activity: "
|
||||||
|
DPSMate.L["of"] = "of"
|
||||||
|
DPSMate.L["comparewith"] = "Compare with"
|
||||||
|
DPSMate.L["comparewithdesc"] = "Choose a player to compare this player to."
|
||||||
|
DPSMate.L["targetscale"] = "Target e-frame scale"
|
||||||
|
DPSMate.L["targetscaleTooltip"] = "Change the scale of the evaluation frames, to fit it better to your tastes."
|
||||||
|
DPSMate.L["updateinterval"] = "Display refresh rate"
|
||||||
|
DPSMate.L["updateintervalTooltip"] = "How often (in seconds) the display bars and timer refresh. Lower values are smoother but use more CPU."
|
||||||
|
DPSMate.L["autowipe"] = "Auto-wipe (logins)"
|
||||||
|
DPSMate.L["autowipeTooltip"] = "Automatically wipe all saved data every N logins. Set to 0 to disable. Example: 7 wipes once per week for daily players."
|
||||||
|
DPSMate.L["eddsum"] = "Enemy damage done summary"
|
||||||
|
DPSMate.L["edtsum"] = "Enemy damage taken summary"
|
||||||
|
DPSMate.L["ehpssum"] = "Effective healing summary"
|
||||||
|
DPSMate.L["tehealing"] = "effective healing"
|
||||||
|
DPSMate.L["hpssum"] = "Healing summary"
|
||||||
|
DPSMate.L["thealing"] = "healing"
|
||||||
|
DPSMate.L["ohpssum"] = "Overhealing summary"
|
||||||
|
DPSMate.L["tohealing"] = " overhealing"
|
||||||
|
DPSMate.L["tehealingtaken"] = "effective healing taken"
|
||||||
|
DPSMate.L["ehpstsum"] = "Effective healing taken summary"
|
||||||
|
DPSMate.L["thealingtaken"] = "healing taken"
|
||||||
|
DPSMate.L["hpstsum"] = "Healing taken summary"
|
||||||
|
DPSMate.L["tohealingtaken"] = "overhealing taken"
|
||||||
|
DPSMate.L["ohpstsum"] = "Overhealing taken summary"
|
||||||
|
DPSMate.L["habsum"] = "Healing and Absorbs summary"
|
||||||
|
DPSMate.L["threatdone"] = "threat done"
|
||||||
|
DPSMate.L["threatsum"] = "Threat done summary"
|
||||||
|
DPSMate.L["ffsum"] = "Friendly fire summary"
|
||||||
|
DPSMate.L["fftsum"] = "Friendly fire taken summary"
|
||||||
|
DPSMate.L["over"] = "Over"
|
||||||
|
DPSMate.L["lastability"] = "Last three hits"
|
||||||
|
DPSMate.L["deathssum"] = "Deaths summary"
|
||||||
|
DPSMate.L["victim"] = "Victim"
|
||||||
|
DPSMate.L["deathhistory"] = "death history"
|
||||||
|
DPSMate.L["intersum"] = "Interrupts summary"
|
||||||
|
DPSMate.L["dispelssum"] = "Dispels summary"
|
||||||
|
DPSMate.L["dispels"] = "Dispels"
|
||||||
|
DPSMate.L["decursessum"] = "Decurses summary"
|
||||||
|
DPSMate.L["liftmagicsum"] = "Lift magic summary"
|
||||||
|
DPSMate.L["curediseasesum"] = "Cure disease summary"
|
||||||
|
DPSMate.L["curepoisonsum"] = "Cure poison summary"
|
||||||
|
DPSMate.L["ccbreakersum"] = "CCBreaker summary"
|
||||||
|
DPSMate.L["failssum"] = "Fails summary"
|
||||||
|
DPSMate.L["AutoAttack"] = "AutoAttack"
|
||||||
|
DPSMate.L["AutoShot"] = "Auto Shot"
|
||||||
|
DPSMate.L["castssum"] = "Casts summary"
|
||||||
|
DPSMate.L["procssum"] = "Procs summary"
|
||||||
|
DPSMate.L["aurassum"] = "Auras summary"
|
||||||
|
DPSMate.L["absorbssum"] = "Absorbs summary"
|
||||||
|
DPSMate.L["absorbeddmg"] = "absorbs"
|
||||||
|
DPSMate.L["absorbstakensum"] = "Absorbs taken summary"
|
||||||
|
DPSMate.L["activity"] = "Activity"
|
||||||
|
|
||||||
|
DPSMate.L["cbtdisplay"] = "Disable CBT-Display"
|
||||||
|
DPSMate.L["disablebarbg"] = "Disable background"
|
||||||
|
DPSMate.L["disablebarbgtooltip"] = "Disable the background of each incomplete bar."
|
||||||
|
DPSMate.L["totalbaropacity"] = "Totalbar opacity"
|
||||||
|
DPSMate.L["totalbaropacitytooltip"] = "Slide to change the opacity of the total bar."
|
||||||
|
DPSMate.L["abortvote"] = "Abort reset. As assist or leader you are able to abort the vote, if you are quick enough."
|
||||||
|
DPSMate.L["resetaborted"] = "The reset vote has been aborted. There is a 20 seconds cooldown on reset now."
|
||||||
|
|
||||||
|
DPSMate.L["vreset"] = "Reset"
|
||||||
|
DPSMate.L["vdreset"] = "Don't Reset"
|
||||||
|
DPSMate.L["togglereportframe"] = "Toggle report frame"
|
||||||
|
DPSMate.L["toggleframes"] = "Toggle frames"
|
||||||
|
DPSMate.L["resetdpsmate"] = "Reset DPSMate"
|
||||||
|
DPSMate.L["columnstooltip"] = "Check this to show this extra information in this mode."
|
||||||
|
DPSMate.L["commas"] = "Commas"
|
||||||
|
DPSMate.L["versionisold"] = "Your version of DPSMate is old. Please update! DPSMate will only synchronize with actual versions."
|
||||||
|
DPSMate.L["rezz"] = "Resurrections"
|
||||||
|
DPSMate.L["rezzof"] = "Resurrections of "
|
||||||
|
DPSMate.L["rezzsum"] = "Ressurection summary"
|
||||||
|
DPSMate.L["activity"] = "Activity"
|
||||||
|
DPSMate.L["cbtdisplay"] = "Disable CBT-Display"
|
||||||
|
DPSMate.L["semicondensed"] = "Semi-Condensed"
|
||||||
|
DPSMate.L["loginhide"] = "Hide on login"
|
||||||
|
DPSMate.L["borderOpacityTooltip"] = "Adjust the border opacity."
|
||||||
|
DPSMate.L["borderOpacity"] = "Border opacity"
|
||||||
|
DPSMate.L["bordertextureTooltip"] = "Select the border texture."
|
||||||
|
DPSMate.L["bordertexture"] = "Border texture"
|
||||||
|
DPSMate.L["borderstrataTooltip"] = "Select the border strata. This pushes the border further into the back- or foreground."
|
||||||
|
DPSMate.L["borderstrata"] = "Border strata"
|
||||||
|
DPSMate.L["bordercolor"] = "Border color"
|
||||||
|
DPSMate.L["bordercolorTooltip"] = "Adjust the border color."
|
||||||
|
DPSMate.L["reportdelaytooltip"] = "Add a delay to prevent chat mutes on some servers."
|
||||||
|
DPSMate.L["delay"] = "Delay"
|
||||||
|
|
||||||
|
-- Newly added:
|
||||||
|
DPSMate.L["tttop"] = "Top "
|
||||||
|
DPSMate.L["ttdamage"] = " Damage"
|
||||||
|
DPSMate.L["tthealing"] = " Healing"
|
||||||
|
DPSMate.L["ttpet"] = " Pet"
|
||||||
|
DPSMate.L["ttpet2"] = "Pet: "
|
||||||
|
DPSMate.L["ttabilities"] = " Abilities"
|
||||||
|
DPSMate.L["ttattacked"] = " Attacked"
|
||||||
|
DPSMate.L["tthealed"] = " Healed"
|
||||||
|
DPSMate.L["ttinterrupt"] = " Interrupt"
|
||||||
|
DPSMate.L["ttinterrupted"] = " Interrupted"
|
||||||
|
DPSMate.L["ttdispelled"] = " Dispelled"
|
||||||
|
DPSMate.L["ttabsorbed"] = " Absorbed"
|
||||||
|
DPSMate.L["ttabsorb"] = " Absorb"
|
||||||
|
DPSMate.L["ttthreat"] = " Threat"
|
||||||
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 812 B |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,841 @@
|
|||||||
|
--[[
|
||||||
|
Name: AceLibrary
|
||||||
|
Revision: $Rev: 14130 $
|
||||||
|
Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
|
||||||
|
Inspired By: Iriel (iriel@vigilance-committee.org)
|
||||||
|
Tekkub (tekkub@gmail.com)
|
||||||
|
Revision: $Rev: 14130 $
|
||||||
|
Website: http://www.wowace.com/
|
||||||
|
Documentation: http://www.wowace.com/index.php/AceLibrary
|
||||||
|
SVN: http://svn.wowace.com/root/trunk/Ace2/AceLibrary
|
||||||
|
Description: Versioning library to handle other library instances, upgrading,
|
||||||
|
and proper access.
|
||||||
|
It also provides a base for libraries to work off of, providing
|
||||||
|
proper error tools. It is handy because all the errors occur in the
|
||||||
|
file that called it, not in the library file itself.
|
||||||
|
Dependencies: None
|
||||||
|
]]
|
||||||
|
|
||||||
|
local ACELIBRARY_MAJOR = "AceLibrary"
|
||||||
|
local ACELIBRARY_MINOR = "$Revision: 99130 $"
|
||||||
|
|
||||||
|
local table_setn
|
||||||
|
do
|
||||||
|
local version = GetBuildInfo()
|
||||||
|
if string.find(version, "^2%.") then
|
||||||
|
-- 2.0.0
|
||||||
|
table_setn = function() end
|
||||||
|
else
|
||||||
|
table_setn = table.setn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local string_gfind = string.gmatch or string.gfind
|
||||||
|
local _G = getfenv(0)
|
||||||
|
local previous = _G[ACELIBRARY_MAJOR]
|
||||||
|
|
||||||
|
local tmp
|
||||||
|
if previous then
|
||||||
|
previous.error = function(self, message, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||||
|
if type(self) ~= "table" then
|
||||||
|
_G.error(string.format("Bad argument #1 to `error' (table expected, got %s)", type(self)), 2)
|
||||||
|
end
|
||||||
|
if not tmp then
|
||||||
|
tmp = {}
|
||||||
|
else
|
||||||
|
for k in pairs(tmp) do tmp[k] = nil end
|
||||||
|
table_setn(tmp, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(tmp, a1)
|
||||||
|
table.insert(tmp, a2)
|
||||||
|
table.insert(tmp, a3)
|
||||||
|
table.insert(tmp, a4)
|
||||||
|
table.insert(tmp, a5)
|
||||||
|
table.insert(tmp, a6)
|
||||||
|
table.insert(tmp, a7)
|
||||||
|
table.insert(tmp, a8)
|
||||||
|
table.insert(tmp, a9)
|
||||||
|
table.insert(tmp, a10)
|
||||||
|
table.insert(tmp, a11)
|
||||||
|
table.insert(tmp, a12)
|
||||||
|
table.insert(tmp, a13)
|
||||||
|
table.insert(tmp, a14)
|
||||||
|
table.insert(tmp, a15)
|
||||||
|
table.insert(tmp, a16)
|
||||||
|
table.insert(tmp, a17)
|
||||||
|
table.insert(tmp, a18)
|
||||||
|
table.insert(tmp, a19)
|
||||||
|
table.insert(tmp, a20)
|
||||||
|
|
||||||
|
local stack = debugstack()
|
||||||
|
if not message then
|
||||||
|
local _,_,second = string.find(stack, "\n(.-)\n")
|
||||||
|
message = "error raised! " .. second
|
||||||
|
else
|
||||||
|
for i = 1,table.getn(tmp) do
|
||||||
|
tmp[i] = tostring(tmp[i])
|
||||||
|
end
|
||||||
|
for i = 1,10 do
|
||||||
|
table.insert(tmp, "nil")
|
||||||
|
end
|
||||||
|
message = string.format(message, unpack(tmp))
|
||||||
|
end
|
||||||
|
|
||||||
|
if getmetatable(self) and getmetatable(self).__tostring then
|
||||||
|
message = string.format("%s: %s", tostring(self), message)
|
||||||
|
elseif type(rawget(self, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self:GetLibraryVersion()) then
|
||||||
|
message = string.format("%s: %s", self:GetLibraryVersion(), message)
|
||||||
|
elseif type(rawget(self, 'class')) == "table" and type(rawget(self.class, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self.class:GetLibraryVersion()) then
|
||||||
|
message = string.format("%s: %s", self.class:GetLibraryVersion(), message)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not string.find(message, "Babble%-Spell") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local first = string.gsub(stack, "\n.*", "")
|
||||||
|
local file = string.gsub(first, ".*\\(.*).lua:%d+: .*", "%1")
|
||||||
|
file = string.gsub(file, "([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
|
||||||
|
|
||||||
|
local i = 0
|
||||||
|
for s in string_gfind(stack, "\n([^\n]*)") do
|
||||||
|
i = i + 1
|
||||||
|
if not string.find(s, file .. "%.lua:%d+:") then
|
||||||
|
file = string.gsub(s, "^.*\\(.*).lua:%d+: .*", "%1")
|
||||||
|
file = string.gsub(file, "([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local j = 0
|
||||||
|
for s in string_gfind(stack, "\n([^\n]*)") do
|
||||||
|
j = j + 1
|
||||||
|
if j > i and not string.find(s, file .. "%.lua:%d+:") then
|
||||||
|
_G.error(message, j + 1)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
_G.error(message, 2)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if previous and not previous:IsNewVersion(ACELIBRARY_MAJOR, ACELIBRARY_MINOR) then return end
|
||||||
|
|
||||||
|
-- @table AceLibrary
|
||||||
|
-- @brief System to handle all versioning of libraries.
|
||||||
|
local AceLibrary = {}
|
||||||
|
local AceLibrary_mt = {}
|
||||||
|
setmetatable(AceLibrary, AceLibrary_mt)
|
||||||
|
|
||||||
|
local tmp
|
||||||
|
local function error(self, message, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||||
|
if type(self) ~= "table" then
|
||||||
|
_G.error(string.format("Bad argument #1 to `error' (table expected, got %s)", type(self)), 2)
|
||||||
|
end
|
||||||
|
if not tmp then
|
||||||
|
tmp = {}
|
||||||
|
else
|
||||||
|
for k in pairs(tmp) do tmp[k] = nil end
|
||||||
|
table_setn(tmp, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(tmp, a1)
|
||||||
|
table.insert(tmp, a2)
|
||||||
|
table.insert(tmp, a3)
|
||||||
|
table.insert(tmp, a4)
|
||||||
|
table.insert(tmp, a5)
|
||||||
|
table.insert(tmp, a6)
|
||||||
|
table.insert(tmp, a7)
|
||||||
|
table.insert(tmp, a8)
|
||||||
|
table.insert(tmp, a9)
|
||||||
|
table.insert(tmp, a10)
|
||||||
|
table.insert(tmp, a11)
|
||||||
|
table.insert(tmp, a12)
|
||||||
|
table.insert(tmp, a13)
|
||||||
|
table.insert(tmp, a14)
|
||||||
|
table.insert(tmp, a15)
|
||||||
|
table.insert(tmp, a16)
|
||||||
|
table.insert(tmp, a17)
|
||||||
|
table.insert(tmp, a18)
|
||||||
|
table.insert(tmp, a19)
|
||||||
|
table.insert(tmp, a20)
|
||||||
|
|
||||||
|
local stack = debugstack()
|
||||||
|
if not message then
|
||||||
|
local _,_,second = string.find(stack, "\n(.-)\n")
|
||||||
|
message = "error raised! " .. second
|
||||||
|
else
|
||||||
|
for i = 1,table.getn(tmp) do
|
||||||
|
tmp[i] = tostring(tmp[i])
|
||||||
|
end
|
||||||
|
for i = 1,10 do
|
||||||
|
table.insert(tmp, "nil")
|
||||||
|
end
|
||||||
|
message = string.format(message, unpack(tmp))
|
||||||
|
end
|
||||||
|
|
||||||
|
if getmetatable(self) and getmetatable(self).__tostring then
|
||||||
|
message = string.format("%s: %s", tostring(self), message)
|
||||||
|
elseif type(rawget(self, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self:GetLibraryVersion()) then
|
||||||
|
message = string.format("%s: %s", self:GetLibraryVersion(), message)
|
||||||
|
elseif type(rawget(self, 'class')) == "table" and type(rawget(self.class, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self.class:GetLibraryVersion()) then
|
||||||
|
message = string.format("%s: %s", self.class:GetLibraryVersion(), message)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not string.find(message, "Babble%-Spell") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local first = string.gsub(stack, "\n.*", "")
|
||||||
|
local file = string.gsub(first, ".*\\(.*).lua:%d+: .*", "%1")
|
||||||
|
file = string.gsub(file, "([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
|
||||||
|
|
||||||
|
local i = 0
|
||||||
|
for s in string_gfind(stack, "\n([^\n]*)") do
|
||||||
|
i = i + 1
|
||||||
|
if not string.find(s, file .. "%.lua:%d+:") then
|
||||||
|
file = string.gsub(s, "^.*\\(.*).lua:%d+: .*", "%1")
|
||||||
|
file = string.gsub(file, "([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local j = 0
|
||||||
|
for s in string_gfind(stack, "\n([^\n]*)") do
|
||||||
|
j = j + 1
|
||||||
|
if j > i and not string.find(s, file .. "%.lua:%d+:") then
|
||||||
|
_G.error(message, j + 1)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
_G.error(message, 2)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local function assert(self, condition, message, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||||
|
if not condition then
|
||||||
|
if not message then
|
||||||
|
local stack = debugstack()
|
||||||
|
local _,_,second = string.find(stack, "\n(.-)\n")
|
||||||
|
message = "assertion failed! " .. second
|
||||||
|
end
|
||||||
|
error(self, message, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return condition
|
||||||
|
end
|
||||||
|
|
||||||
|
local function argCheck(self, arg, num, kind, kind2, kind3, kind4, kind5)
|
||||||
|
if type(num) ~= "number" then
|
||||||
|
error(self, "Bad argument #3 to `argCheck' (number expected, got %s)", type(num))
|
||||||
|
elseif type(kind) ~= "string" then
|
||||||
|
error(self, "Bad argument #4 to `argCheck' (string expected, got %s)", type(kind))
|
||||||
|
end
|
||||||
|
local errored = false
|
||||||
|
arg = type(arg)
|
||||||
|
if arg ~= kind and arg ~= kind2 and arg ~= kind3 and arg ~= kind4 and arg ~= kind5 then
|
||||||
|
local _,_,func = string.find(debugstack(), "`argCheck'.-([`<].-['>])")
|
||||||
|
if not func then
|
||||||
|
_,_,func = string.find(debugstack(), "([`<].-['>])")
|
||||||
|
end
|
||||||
|
if kind5 then
|
||||||
|
error(self, "Bad argument #%s to %s (%s, %s, %s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, kind4, kind5, arg)
|
||||||
|
elseif kind4 then
|
||||||
|
error(self, "Bad argument #%s to %s (%s, %s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, kind4, arg)
|
||||||
|
elseif kind3 then
|
||||||
|
error(self, "Bad argument #%s to %s (%s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, arg)
|
||||||
|
elseif kind2 then
|
||||||
|
error(self, "Bad argument #%s to %s (%s or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, arg)
|
||||||
|
else
|
||||||
|
error(self, "Bad argument #%s to %s (%s expected, got %s)", tonumber(num) or 0/0, func, kind, arg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pcall(self, func, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||||
|
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20 = _G.pcall(func, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||||
|
if not a1 then
|
||||||
|
error(self, string.gsub(a2, ".-%.lua:%d-: ", ""))
|
||||||
|
else
|
||||||
|
return a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local recurse = {}
|
||||||
|
local function addToPositions(t, major)
|
||||||
|
if not AceLibrary.positions[t] or AceLibrary.positions[t] == major then
|
||||||
|
rawset(t, recurse, true)
|
||||||
|
AceLibrary.positions[t] = major
|
||||||
|
for k,v in pairs(t) do
|
||||||
|
if type(v) == "table" and not rawget(v, recurse) then
|
||||||
|
addToPositions(v, major)
|
||||||
|
end
|
||||||
|
if type(k) == "table" and not rawget(k, recurse) then
|
||||||
|
addToPositions(k, major)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local mt = getmetatable(t)
|
||||||
|
if mt and not rawget(mt, recurse) then
|
||||||
|
addToPositions(mt, major)
|
||||||
|
end
|
||||||
|
rawset(t, recurse, nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function svnRevisionToNumber(text)
|
||||||
|
if type(text) == "string" then
|
||||||
|
if string.find(text, "^%$Revision: (%d+) %$$") then
|
||||||
|
return tonumber((string.gsub(text, "^%$Revision: (%d+) %$$", "%1")))
|
||||||
|
elseif string.find(text, "^%$Rev: (%d+) %$$") then
|
||||||
|
return tonumber((string.gsub(text, "^%$Rev: (%d+) %$$", "%1")))
|
||||||
|
elseif string.find(text, "^%$LastChangedRevision: (%d+) %$$") then
|
||||||
|
return tonumber((string.gsub(text, "^%$LastChangedRevision: (%d+) %$$", "%1")))
|
||||||
|
end
|
||||||
|
elseif type(text) == "number" then
|
||||||
|
return text
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local crawlReplace
|
||||||
|
do
|
||||||
|
local recurse = {}
|
||||||
|
local function func(t, to, from)
|
||||||
|
if recurse[t] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
recurse[t] = true
|
||||||
|
local mt = getmetatable(t)
|
||||||
|
setmetatable(t, nil)
|
||||||
|
rawset(t, to, rawget(t, from))
|
||||||
|
rawset(t, from, nil)
|
||||||
|
for k,v in pairs(t) do
|
||||||
|
if v == from then
|
||||||
|
t[k] = to
|
||||||
|
elseif type(v) == "table" then
|
||||||
|
if not recurse[v] then
|
||||||
|
func(v, to, from)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(k) == "table" then
|
||||||
|
if not recurse[k] then
|
||||||
|
func(k, to, from)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
setmetatable(t, mt)
|
||||||
|
if mt then
|
||||||
|
if mt == from then
|
||||||
|
setmetatable(t, to)
|
||||||
|
elseif not recurse[mt] then
|
||||||
|
func(mt, to, from)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function crawlReplace(t, to, from)
|
||||||
|
func(t, to, from)
|
||||||
|
for k in pairs(recurse) do
|
||||||
|
recurse[k] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- @function destroyTable
|
||||||
|
-- @brief remove all the contents of a table
|
||||||
|
-- @param t table to destroy
|
||||||
|
local function destroyTable(t)
|
||||||
|
setmetatable(t, nil)
|
||||||
|
for k,v in pairs(t) do t[k] = nil end
|
||||||
|
table_setn(t, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function isFrame(frame)
|
||||||
|
return type(frame) == "table" and type(rawget(frame, 0)) == "userdata" and type(rawget(frame, 'IsFrameType')) == "function" and getmetatable(frame) and type(rawget(getmetatable(frame), '__index')) == "function"
|
||||||
|
end
|
||||||
|
|
||||||
|
local new, del
|
||||||
|
do
|
||||||
|
local tables = setmetatable({}, {__mode = "k"})
|
||||||
|
|
||||||
|
function new()
|
||||||
|
local t = next(tables)
|
||||||
|
if t then
|
||||||
|
tables[t] = nil
|
||||||
|
return t
|
||||||
|
else
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function del(t, depth)
|
||||||
|
if depth and depth > 0 then
|
||||||
|
for k,v in pairs(t) do
|
||||||
|
if type(v) == "table" and not isFrame(v) then
|
||||||
|
del(v, depth - 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
destroyTable(t)
|
||||||
|
tables[t] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- @function copyTable
|
||||||
|
-- @brief Create a shallow copy of a table and return it.
|
||||||
|
-- @param from The table to copy from
|
||||||
|
-- @return A shallow copy of the table
|
||||||
|
local function copyTable(from)
|
||||||
|
local to = new()
|
||||||
|
for k,v in pairs(from) do to[k] = v end
|
||||||
|
table_setn(to, table.getn(from))
|
||||||
|
setmetatable(to, getmetatable(from))
|
||||||
|
return to
|
||||||
|
end
|
||||||
|
|
||||||
|
-- @function deepTransfer
|
||||||
|
-- @brief Fully transfer all data, keeping proper previous table
|
||||||
|
-- backreferences stable.
|
||||||
|
-- @param to The table with which data is to be injected into
|
||||||
|
-- @param from The table whose data will be injected into the first
|
||||||
|
-- @param saveFields If available, a shallow copy of the basic data is saved
|
||||||
|
-- in here.
|
||||||
|
-- @param list The account of table references
|
||||||
|
-- @param list2 The current status on which tables have been traversed.
|
||||||
|
local deepTransfer
|
||||||
|
do
|
||||||
|
-- @function examine
|
||||||
|
-- @brief Take account of all the table references to be shared
|
||||||
|
-- between the to and from tables.
|
||||||
|
-- @param to The table with which data is to be injected into
|
||||||
|
-- @param from The table whose data will be injected into the first
|
||||||
|
-- @param list An account of the table references
|
||||||
|
local function examine(to, from, list, major)
|
||||||
|
list[from] = to
|
||||||
|
for k,v in pairs(from) do
|
||||||
|
if rawget(to, k) and type(from[k]) == "table" and type(to[k]) == "table" and not list[from[k]] then
|
||||||
|
if from[k] == to[k] then
|
||||||
|
list[from[k]] = to[k]
|
||||||
|
elseif AceLibrary.positions[from[v]] ~= major and AceLibrary.positions[from[v]] then
|
||||||
|
list[from[k]] = from[k]
|
||||||
|
elseif not list[from[k]] then
|
||||||
|
examine(to[k], from[k], list, major)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return list
|
||||||
|
end
|
||||||
|
|
||||||
|
function deepTransfer(to, from, saveFields, major, list, list2)
|
||||||
|
setmetatable(to, nil)
|
||||||
|
local createdList
|
||||||
|
if not list then
|
||||||
|
createdList = true
|
||||||
|
list = new()
|
||||||
|
list2 = new()
|
||||||
|
examine(to, from, list, major)
|
||||||
|
end
|
||||||
|
list2[to] = to
|
||||||
|
for k,v in pairs(to) do
|
||||||
|
if type(rawget(from, k)) ~= "table" or type(v) ~= "table" or isFrame(v) then
|
||||||
|
if saveFields then
|
||||||
|
saveFields[k] = v
|
||||||
|
end
|
||||||
|
to[k] = nil
|
||||||
|
elseif v ~= _G then
|
||||||
|
if saveFields then
|
||||||
|
saveFields[k] = copyTable(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for k in pairs(from) do
|
||||||
|
if rawget(to, k) and to[k] ~= from[k] and AceLibrary.positions[to[k]] == major and from[k] ~= _G then
|
||||||
|
if not list2[to[k]] then
|
||||||
|
deepTransfer(to[k], from[k], nil, major, list, list2)
|
||||||
|
end
|
||||||
|
to[k] = list[to[k]] or list2[to[k]]
|
||||||
|
else
|
||||||
|
rawset(to, k, from[k])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table_setn(to, table.getn(from))
|
||||||
|
setmetatable(to, getmetatable(from))
|
||||||
|
local mt = getmetatable(to)
|
||||||
|
if mt then
|
||||||
|
if list[mt] then
|
||||||
|
setmetatable(to, list[mt])
|
||||||
|
elseif mt.__index and list[mt.__index] then
|
||||||
|
mt.__index = list[mt.__index]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
destroyTable(from)
|
||||||
|
if createdList then
|
||||||
|
del(list)
|
||||||
|
del(list2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- @method TryToLoadStandalone
|
||||||
|
-- @brief Attempt to find and load a standalone version of the requested library
|
||||||
|
-- @param major A string representing the major version
|
||||||
|
-- @return If library is found, return values from the call to LoadAddOn are returned
|
||||||
|
-- If the library has been requested previously, nil is returned.
|
||||||
|
local function TryToLoadStandalone(major)
|
||||||
|
if not AceLibrary.scannedlibs then AceLibrary.scannedlibs = {} end
|
||||||
|
if AceLibrary.scannedlibs[major] then return end
|
||||||
|
|
||||||
|
AceLibrary.scannedlibs[major] = true
|
||||||
|
|
||||||
|
local name, _, _, enabled, loadable = GetAddOnInfo(major)
|
||||||
|
if loadable then
|
||||||
|
return LoadAddOn(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1,GetNumAddOns() do
|
||||||
|
if GetAddOnMetadata(i, "X-AceLibrary-"..major) then
|
||||||
|
local name, _, _, enabled, loadable = GetAddOnInfo(i)
|
||||||
|
if loadable then
|
||||||
|
return LoadAddOn(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- @method IsNewVersion
|
||||||
|
-- @brief Obtain whether the supplied version would be an upgrade to the
|
||||||
|
-- current version. This allows for bypass code in library
|
||||||
|
-- declaration.
|
||||||
|
-- @param major A string representing the major version
|
||||||
|
-- @param minor An integer or an svn revision string representing the minor version
|
||||||
|
-- @return whether the supplied version would be newer than what is
|
||||||
|
-- currently available.
|
||||||
|
function AceLibrary:IsNewVersion(major, minor)
|
||||||
|
argCheck(self, major, 2, "string")
|
||||||
|
TryToLoadStandalone(major)
|
||||||
|
|
||||||
|
if type(minor) == "string" then
|
||||||
|
local m = svnRevisionToNumber(minor)
|
||||||
|
if m then
|
||||||
|
minor = m
|
||||||
|
else
|
||||||
|
_G.error(string.format("Bad argument #3 to `IsNewVersion'. Must be a number or SVN revision string. %q is not appropriate", minor), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
argCheck(self, minor, 3, "number")
|
||||||
|
local data = self.libs[major]
|
||||||
|
if not data then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return data.minor < minor
|
||||||
|
end
|
||||||
|
|
||||||
|
-- @method HasInstance
|
||||||
|
-- @brief Returns whether an instance exists. This allows for optional support of a library.
|
||||||
|
-- @param major A string representing the major version.
|
||||||
|
-- @param minor (optional) An integer or an svn revision string representing the minor version.
|
||||||
|
-- @return Whether an instance exists.
|
||||||
|
function AceLibrary:HasInstance(major, minor)
|
||||||
|
argCheck(self, major, 2, "string")
|
||||||
|
TryToLoadStandalone(major)
|
||||||
|
|
||||||
|
if minor then
|
||||||
|
if type(minor) == "string" then
|
||||||
|
local m = svnRevisionToNumber(minor)
|
||||||
|
if m then
|
||||||
|
minor = m
|
||||||
|
else
|
||||||
|
_G.error(string.format("Bad argument #3 to `HasInstance'. Must be a number or SVN revision string. %q is not appropriate", minor), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
argCheck(self, minor, 3, "number")
|
||||||
|
if not self.libs[major] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return self.libs[major].minor == minor
|
||||||
|
end
|
||||||
|
return self.libs[major] and true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- @method GetInstance
|
||||||
|
-- @brief Returns the library with the given major/minor version.
|
||||||
|
-- @param major A string representing the major version.
|
||||||
|
-- @param minor (optional) An integer or an svn revision string representing the minor version.
|
||||||
|
-- @return The library with the given major/minor version.
|
||||||
|
function AceLibrary:GetInstance(major, minor)
|
||||||
|
argCheck(self, major, 2, "string")
|
||||||
|
TryToLoadStandalone(major)
|
||||||
|
|
||||||
|
local data = self.libs[major]
|
||||||
|
if not data then
|
||||||
|
_G.error(string.format("Cannot find a library instance of %s.", major), 2)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if minor then
|
||||||
|
if type(minor) == "string" then
|
||||||
|
local m = svnRevisionToNumber(minor)
|
||||||
|
if m then
|
||||||
|
minor = m
|
||||||
|
else
|
||||||
|
_G.error(string.format("Bad argument #3 to `GetInstance'. Must be a number or SVN revision string. %q is not appropriate", minor), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
argCheck(self, minor, 2, "number")
|
||||||
|
if data.minor ~= minor then
|
||||||
|
_G.error(string.format("Cannot find a library instance of %s, minor version %d.", major, minor), 2)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return data.instance
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Syntax sugar. AceLibrary("FooBar-1.0")
|
||||||
|
AceLibrary_mt.__call = AceLibrary.GetInstance
|
||||||
|
|
||||||
|
local donothing
|
||||||
|
|
||||||
|
local AceEvent
|
||||||
|
|
||||||
|
-- @method Register
|
||||||
|
-- @brief Registers a new version of a given library.
|
||||||
|
-- @param newInstance the library to register
|
||||||
|
-- @param major the major version of the library
|
||||||
|
-- @param minor the minor version of the library
|
||||||
|
-- @param activateFunc (optional) A function to be called when the library is
|
||||||
|
-- fully activated. Takes the arguments
|
||||||
|
-- (newInstance [, oldInstance, oldDeactivateFunc]). If
|
||||||
|
-- oldInstance is given, you should probably call
|
||||||
|
-- oldDeactivateFunc(oldInstance).
|
||||||
|
-- @param deactivateFunc (optional) A function to be called by a newer library's
|
||||||
|
-- activateFunc.
|
||||||
|
-- @param externalFunc (optional) A function to be called whenever a new
|
||||||
|
-- library is registered.
|
||||||
|
function AceLibrary:Register(newInstance, major, minor, activateFunc, deactivateFunc, externalFunc)
|
||||||
|
argCheck(self, newInstance, 2, "table")
|
||||||
|
argCheck(self, major, 3, "string")
|
||||||
|
if type(minor) == "string" then
|
||||||
|
local m = svnRevisionToNumber(minor)
|
||||||
|
if m then
|
||||||
|
minor = m
|
||||||
|
else
|
||||||
|
_G.error(string.format("Bad argument #4 to `Register'. Must be a number or SVN revision string. %q is not appropriate", minor), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
argCheck(self, minor, 4, "number")
|
||||||
|
if math.floor(minor) ~= minor or minor < 0 then
|
||||||
|
error(self, "Bad argument #4 to `Register' (integer >= 0 expected, got %s)", minor)
|
||||||
|
end
|
||||||
|
argCheck(self, activateFunc, 5, "function", "nil")
|
||||||
|
argCheck(self, deactivateFunc, 6, "function", "nil")
|
||||||
|
argCheck(self, externalFunc, 7, "function", "nil")
|
||||||
|
if not deactivateFunc then
|
||||||
|
if not donothing then
|
||||||
|
donothing = function() end
|
||||||
|
end
|
||||||
|
deactivateFunc = donothing
|
||||||
|
end
|
||||||
|
local data = self.libs[major]
|
||||||
|
if not data then
|
||||||
|
-- This is new
|
||||||
|
local instance = copyTable(newInstance)
|
||||||
|
crawlReplace(instance, instance, newInstance)
|
||||||
|
destroyTable(newInstance)
|
||||||
|
if AceLibrary == newInstance then
|
||||||
|
self = instance
|
||||||
|
AceLibrary = instance
|
||||||
|
end
|
||||||
|
self.libs[major] = {
|
||||||
|
instance = instance,
|
||||||
|
minor = minor,
|
||||||
|
deactivateFunc = deactivateFunc,
|
||||||
|
externalFunc = externalFunc,
|
||||||
|
}
|
||||||
|
rawset(instance, 'GetLibraryVersion', function(self)
|
||||||
|
return major, minor
|
||||||
|
end)
|
||||||
|
if not rawget(instance, 'error') then
|
||||||
|
rawset(instance, 'error', error)
|
||||||
|
end
|
||||||
|
if not rawget(instance, 'assert') then
|
||||||
|
rawset(instance, 'assert', assert)
|
||||||
|
end
|
||||||
|
if not rawget(instance, 'argCheck') then
|
||||||
|
rawset(instance, 'argCheck', argCheck)
|
||||||
|
end
|
||||||
|
if not rawget(instance, 'pcall') then
|
||||||
|
rawset(instance, 'pcall', pcall)
|
||||||
|
end
|
||||||
|
addToPositions(instance, major)
|
||||||
|
if activateFunc then
|
||||||
|
activateFunc(instance, nil, nil) -- no old version, so explicit nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if externalFunc then
|
||||||
|
for k,data in pairs(self.libs) do
|
||||||
|
if k ~= major then
|
||||||
|
externalFunc(instance, k, data.instance)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for k,data in pairs(self.libs) do
|
||||||
|
if k ~= major and data.externalFunc then
|
||||||
|
data.externalFunc(data.instance, major, instance)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if major == "AceEvent-2.0" then
|
||||||
|
AceEvent = instance
|
||||||
|
end
|
||||||
|
if AceEvent then
|
||||||
|
AceEvent.TriggerEvent(self, "AceLibrary_Register", major, instance)
|
||||||
|
end
|
||||||
|
|
||||||
|
return instance
|
||||||
|
end
|
||||||
|
local instance = data.instance
|
||||||
|
if minor <= data.minor then
|
||||||
|
-- This one is already obsolete, raise an error.
|
||||||
|
_G.error(string.format("Obsolete library registered. %s is already registered at version %d. You are trying to register version %d. Hint: if not AceLibrary:IsNewVersion(%q, %d) then return end", major, data.minor, minor, major, minor), 2)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- This is an update
|
||||||
|
local oldInstance = new()
|
||||||
|
|
||||||
|
addToPositions(newInstance, major)
|
||||||
|
local isAceLibrary = (AceLibrary == newInstance)
|
||||||
|
local old_error, old_assert, old_argCheck, old_pcall
|
||||||
|
if isAceLibrary then
|
||||||
|
self = instance
|
||||||
|
AceLibrary = instance
|
||||||
|
|
||||||
|
old_error = instance.error
|
||||||
|
old_assert = instance.assert
|
||||||
|
old_argCheck = instance.argCheck
|
||||||
|
old_pcall = instance.pcall
|
||||||
|
|
||||||
|
self.error = error
|
||||||
|
self.assert = assert
|
||||||
|
self.argCheck = argCheck
|
||||||
|
self.pcall = pcall
|
||||||
|
end
|
||||||
|
deepTransfer(instance, newInstance, oldInstance, major)
|
||||||
|
crawlReplace(instance, instance, newInstance)
|
||||||
|
local oldDeactivateFunc = data.deactivateFunc
|
||||||
|
data.minor = minor
|
||||||
|
data.deactivateFunc = deactivateFunc
|
||||||
|
data.externalFunc = externalFunc
|
||||||
|
rawset(instance, 'GetLibraryVersion', function(self)
|
||||||
|
return major, minor
|
||||||
|
end)
|
||||||
|
if not rawget(instance, 'error') then
|
||||||
|
rawset(instance, 'error', error)
|
||||||
|
end
|
||||||
|
if not rawget(instance, 'assert') then
|
||||||
|
rawset(instance, 'assert', assert)
|
||||||
|
end
|
||||||
|
if not rawget(instance, 'argCheck') then
|
||||||
|
rawset(instance, 'argCheck', argCheck)
|
||||||
|
end
|
||||||
|
if not rawget(instance, 'pcall') then
|
||||||
|
rawset(instance, 'pcall', pcall)
|
||||||
|
end
|
||||||
|
if isAceLibrary then
|
||||||
|
for _,v in pairs(self.libs) do
|
||||||
|
local i = type(v) == "table" and v.instance
|
||||||
|
if type(i) == "table" then
|
||||||
|
if not rawget(i, 'error') or i.error == old_error then
|
||||||
|
rawset(i, 'error', error)
|
||||||
|
end
|
||||||
|
if not rawget(i, 'assert') or i.assert == old_assert then
|
||||||
|
rawset(i, 'assert', assert)
|
||||||
|
end
|
||||||
|
if not rawget(i, 'argCheck') or i.argCheck == old_argCheck then
|
||||||
|
rawset(i, 'argCheck', argCheck)
|
||||||
|
end
|
||||||
|
if not rawget(i, 'pcall') or i.pcall == old_pcall then
|
||||||
|
rawset(i, 'pcall', pcall)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if activateFunc then
|
||||||
|
activateFunc(instance, oldInstance, oldDeactivateFunc)
|
||||||
|
else
|
||||||
|
oldDeactivateFunc(oldInstance)
|
||||||
|
end
|
||||||
|
del(oldInstance)
|
||||||
|
|
||||||
|
if externalFunc then
|
||||||
|
for k,data in pairs(self.libs) do
|
||||||
|
if k ~= major then
|
||||||
|
externalFunc(instance, k, data.instance)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return instance
|
||||||
|
end
|
||||||
|
|
||||||
|
local iter
|
||||||
|
function AceLibrary:IterateLibraries()
|
||||||
|
if not iter then
|
||||||
|
local function iter(t, k)
|
||||||
|
k = next(t, k)
|
||||||
|
if not k then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
return k, t[k].instance
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return iter, self.libs, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- @function Activate
|
||||||
|
-- @brief The activateFunc for AceLibrary itself. Called when
|
||||||
|
-- AceLibrary properly registers.
|
||||||
|
-- @param self Reference to AceLibrary
|
||||||
|
-- @param oldLib (optional) Reference to an old version of AceLibrary
|
||||||
|
-- @param oldDeactivate (optional) Function to deactivate the old lib
|
||||||
|
local function activate(self, oldLib, oldDeactivate)
|
||||||
|
if not self.libs then
|
||||||
|
if oldLib then
|
||||||
|
self.libs = oldLib.libs
|
||||||
|
self.scannedlibs = oldLib.scannedlibs
|
||||||
|
end
|
||||||
|
if not self.libs then
|
||||||
|
self.libs = {}
|
||||||
|
end
|
||||||
|
if not self.scannedlibs then
|
||||||
|
self.scannedlibs = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not self.positions then
|
||||||
|
if oldLib then
|
||||||
|
self.positions = oldLib.positions
|
||||||
|
end
|
||||||
|
if not self.positions then
|
||||||
|
self.positions = setmetatable({}, { __mode = "k" })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Expose the library in the global environment
|
||||||
|
_G[ACELIBRARY_MAJOR] = self
|
||||||
|
|
||||||
|
if oldDeactivate then
|
||||||
|
oldDeactivate(oldLib)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not previous then
|
||||||
|
previous = AceLibrary
|
||||||
|
end
|
||||||
|
if not previous.libs then
|
||||||
|
previous.libs = {}
|
||||||
|
end
|
||||||
|
AceLibrary.libs = previous.libs
|
||||||
|
if not previous.positions then
|
||||||
|
previous.positions = setmetatable({}, { __mode = "k" })
|
||||||
|
end
|
||||||
|
AceLibrary.positions = previous.positions
|
||||||
|
AceLibrary:Register(AceLibrary, ACELIBRARY_MAJOR, ACELIBRARY_MINOR, activate)
|
||||||
@@ -0,0 +1,465 @@
|
|||||||
|
--
|
||||||
|
-- ChatThrottleLib by Mikk
|
||||||
|
--
|
||||||
|
-- Manages AddOn chat output to keep player from getting kicked off.
|
||||||
|
--
|
||||||
|
-- ChatThrottleLib.SendChatMessage/.SendAddonMessage functions that accept
|
||||||
|
-- a Priority ("BULK", "NORMAL", "ALERT") as well as prefix for SendChatMessage.
|
||||||
|
--
|
||||||
|
-- Priorities get an equal share of available bandwidth when fully loaded.
|
||||||
|
-- Communication channels are separated on extension+chattype+destination and
|
||||||
|
-- get round-robinned. (Destination only matters for whispers and channels,
|
||||||
|
-- obviously)
|
||||||
|
--
|
||||||
|
-- Will install hooks for SendChatMessage and SendAdd[Oo]nMessage to measure
|
||||||
|
-- bandwidth bypassing the library and use less bandwidth itself.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- Fully embeddable library. Just copy this file into your addon directory,
|
||||||
|
-- add it to the .toc, and it's done.
|
||||||
|
--
|
||||||
|
-- Can run as a standalone addon also, but, really, just embed it! :-)
|
||||||
|
--
|
||||||
|
|
||||||
|
local CTL_VERSION = 13
|
||||||
|
|
||||||
|
local MAX_CPS = 800 -- 2000 seems to be safe if NOTHING ELSE is happening. let's call it 800.
|
||||||
|
local MSG_OVERHEAD = 40 -- Guesstimate overhead for sending a message; source+dest+chattype+protocolstuff
|
||||||
|
|
||||||
|
local BURST = 4000 -- WoW's server buffer seems to be about 32KB. 8KB should be safe, but seen disconnects on _some_ servers. Using 4KB now.
|
||||||
|
|
||||||
|
local MIN_FPS = 20 -- Reduce output CPS to half (and don't burst) if FPS drops below this value
|
||||||
|
|
||||||
|
if(ChatThrottleLib and ChatThrottleLib.version>=CTL_VERSION) then
|
||||||
|
-- There's already a newer (or same) version loaded. Buh-bye.
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(not ChatThrottleLib) then
|
||||||
|
ChatThrottleLib = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local ChatThrottleLib = ChatThrottleLib
|
||||||
|
local strlen = strlen
|
||||||
|
local setmetatable = setmetatable
|
||||||
|
local getn = getn
|
||||||
|
local tremove = tremove
|
||||||
|
local tinsert = tinsert
|
||||||
|
local tostring = tostring
|
||||||
|
local GetTime = GetTime
|
||||||
|
local format = format
|
||||||
|
|
||||||
|
ChatThrottleLib.version=CTL_VERSION;
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- Double-linked ring implementation
|
||||||
|
|
||||||
|
local Ring = {}
|
||||||
|
local RingMeta = { __index=Ring }
|
||||||
|
|
||||||
|
function Ring:New()
|
||||||
|
local ret = {}
|
||||||
|
setmetatable(ret, RingMeta)
|
||||||
|
return ret;
|
||||||
|
end
|
||||||
|
|
||||||
|
function Ring:Add(obj) -- Append at the "far end" of the ring (aka just before the current position)
|
||||||
|
if(self.pos) then
|
||||||
|
obj.prev = self.pos.prev;
|
||||||
|
obj.prev.next = obj;
|
||||||
|
obj.next = self.pos;
|
||||||
|
obj.next.prev = obj;
|
||||||
|
else
|
||||||
|
obj.next = obj;
|
||||||
|
obj.prev = obj;
|
||||||
|
self.pos = obj;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Ring:Remove(obj)
|
||||||
|
obj.next.prev = obj.prev;
|
||||||
|
obj.prev.next = obj.next;
|
||||||
|
if(self.pos == obj) then
|
||||||
|
self.pos = obj.next;
|
||||||
|
if(self.pos == obj) then
|
||||||
|
self.pos = nil;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- Recycling bin for pipes (kept in a linked list because that's
|
||||||
|
-- how they're worked with in the rotating rings; just reusing members)
|
||||||
|
|
||||||
|
ChatThrottleLib.PipeBin = { count=0 }
|
||||||
|
|
||||||
|
function ChatThrottleLib.PipeBin:Put(pipe)
|
||||||
|
for i=getn(pipe),1,-1 do
|
||||||
|
tremove(pipe, i);
|
||||||
|
end
|
||||||
|
pipe.prev = nil;
|
||||||
|
pipe.next = self.list;
|
||||||
|
self.list = pipe;
|
||||||
|
self.count = self.count+1;
|
||||||
|
end
|
||||||
|
|
||||||
|
function ChatThrottleLib.PipeBin:Get()
|
||||||
|
if(self.list) then
|
||||||
|
local ret = self.list;
|
||||||
|
self.list = ret.next;
|
||||||
|
ret.next=nil;
|
||||||
|
self.count = self.count - 1;
|
||||||
|
return ret;
|
||||||
|
end
|
||||||
|
return {};
|
||||||
|
end
|
||||||
|
|
||||||
|
function ChatThrottleLib.PipeBin:Tidy()
|
||||||
|
if(self.count < 25) then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
local n
|
||||||
|
if(self.count > 100) then
|
||||||
|
n=self.count-90;
|
||||||
|
else
|
||||||
|
n=10;
|
||||||
|
end
|
||||||
|
for i=2,n do
|
||||||
|
self.list = self.list.next;
|
||||||
|
end
|
||||||
|
local delme = self.list;
|
||||||
|
self.list = self.list.next;
|
||||||
|
delme.next = nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- Recycling bin for messages
|
||||||
|
|
||||||
|
ChatThrottleLib.MsgBin = {}
|
||||||
|
|
||||||
|
function ChatThrottleLib.MsgBin:Put(msg)
|
||||||
|
msg.text = nil;
|
||||||
|
tinsert(self, msg);
|
||||||
|
end
|
||||||
|
|
||||||
|
function ChatThrottleLib.MsgBin:Get()
|
||||||
|
local ret = tremove(self, getn(self));
|
||||||
|
if(ret) then return ret; end
|
||||||
|
return {};
|
||||||
|
end
|
||||||
|
|
||||||
|
function ChatThrottleLib.MsgBin:Tidy()
|
||||||
|
if(getn(self)<50) then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
if(getn(self)>150) then -- "can't happen" but ...
|
||||||
|
for n=getn(self),120,-1 do
|
||||||
|
tremove(self,n);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for n=getn(self),getn(self)-20,-1 do
|
||||||
|
tremove(self,n);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- ChatThrottleLib:Init
|
||||||
|
-- Initialize queues, set up frame for OnUpdate, etc
|
||||||
|
|
||||||
|
|
||||||
|
function ChatThrottleLib:Init()
|
||||||
|
|
||||||
|
-- Set up queues
|
||||||
|
if(not self.Prio) then
|
||||||
|
self.Prio = {}
|
||||||
|
self.Prio["ALERT"] = { ByName={}, Ring = Ring:New(), avail=0 };
|
||||||
|
self.Prio["NORMAL"] = { ByName={}, Ring = Ring:New(), avail=0 };
|
||||||
|
self.Prio["BULK"] = { ByName={}, Ring = Ring:New(), avail=0 };
|
||||||
|
end
|
||||||
|
|
||||||
|
-- v4: total send counters per priority
|
||||||
|
for _,Prio in pairs(self.Prio) do
|
||||||
|
Prio.nTotalSent = Prio.nTotalSent or 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
self.avail = self.avail or 0; -- v5
|
||||||
|
self.nTotalSent = self.nTotalSent or 0; -- v5
|
||||||
|
|
||||||
|
|
||||||
|
-- Set up a frame to get OnUpdate events
|
||||||
|
if(not self.Frame) then
|
||||||
|
self.Frame = CreateFrame("Frame");
|
||||||
|
self.Frame:Hide();
|
||||||
|
end
|
||||||
|
self.Frame.Show = self.Frame.Show; -- cache for speed
|
||||||
|
self.Frame.Hide = self.Frame.Hide; -- cache for speed
|
||||||
|
self.Frame:SetScript("OnUpdate", self.OnUpdate);
|
||||||
|
self.Frame:SetScript("OnEvent", self.OnEvent); -- v11: Monitor P_E_W so we can throttle hard for a few seconds
|
||||||
|
self.Frame:RegisterEvent("PLAYER_ENTERING_WORLD");
|
||||||
|
self.OnUpdateDelay=0;
|
||||||
|
self.LastAvailUpdate=GetTime();
|
||||||
|
self.HardThrottlingBeginTime=GetTime(); -- v11: Throttle hard for a few seconds after startup
|
||||||
|
|
||||||
|
-- Hook SendChatMessage and SendAddonMessage so we can measure unpiped traffic and avoid overloads (v7)
|
||||||
|
if(not self.ORIG_SendChatMessage) then
|
||||||
|
--SendChatMessage
|
||||||
|
self.ORIG_SendChatMessage = SendChatMessage;
|
||||||
|
SendChatMessage = function(a1,a2,a3,a4) return ChatThrottleLib.Hook_SendChatMessage(a1,a2,a3,a4); end
|
||||||
|
--SendAdd[Oo]nMessage
|
||||||
|
if(SendAddonMessage or SendAddOnMessage) then -- v10: don't pretend like it doesn't exist if it doesn't!
|
||||||
|
self.ORIG_SendAddonMessage = SendAddonMessage or SendAddOnMessage;
|
||||||
|
SendAddonMessage = function(a1,a2,a3) return ChatThrottleLib.Hook_SendAddonMessage(a1,a2,a3); end
|
||||||
|
if(SendAddOnMessage) then -- in case Slouken changes his mind...
|
||||||
|
SendAddOnMessage = SendAddonMessage;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.nBypass = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- ChatThrottleLib.Hook_SendChatMessage / .Hook_SendAddonMessage
|
||||||
|
function ChatThrottleLib.Hook_SendChatMessage(text, chattype, language, destination)
|
||||||
|
local self = ChatThrottleLib;
|
||||||
|
local size = strlen(tostring(text or "")) + strlen(tostring(chattype or "")) + strlen(tostring(destination or "")) + 40;
|
||||||
|
self.avail = self.avail - size;
|
||||||
|
self.nBypass = self.nBypass + size;
|
||||||
|
return self.ORIG_SendChatMessage(text, chattype, language, destination);
|
||||||
|
end
|
||||||
|
function ChatThrottleLib.Hook_SendAddonMessage(prefix, text, chattype)
|
||||||
|
local self = ChatThrottleLib;
|
||||||
|
local size = strlen(tostring(text or "")) + strlen(tostring(chattype or "")) + strlen(tostring(prefix or "")) + 40;
|
||||||
|
self.avail = self.avail - size;
|
||||||
|
self.nBypass = self.nBypass + size;
|
||||||
|
return self.ORIG_SendAddonMessage(prefix, text, chattype);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- ChatThrottleLib:UpdateAvail
|
||||||
|
-- Update self.avail with how much bandwidth is currently available
|
||||||
|
|
||||||
|
function ChatThrottleLib:UpdateAvail()
|
||||||
|
local now = GetTime();
|
||||||
|
local newavail = MAX_CPS * (now-self.LastAvailUpdate);
|
||||||
|
|
||||||
|
if(now - self.HardThrottlingBeginTime < 5) then
|
||||||
|
-- First 5 seconds after startup/zoning: VERY hard clamping to avoid irritating the server rate limiter, it seems very cranky then
|
||||||
|
self.avail = min(self.avail + (newavail*0.1), MAX_CPS*0.5);
|
||||||
|
elseif(GetFramerate()<MIN_FPS) then -- GetFrameRate call takes ~0.002 secs
|
||||||
|
newavail = newavail * 0.5;
|
||||||
|
self.avail = min(MAX_CPS, self.avail + newavail);
|
||||||
|
self.bChoking = true; -- just for stats
|
||||||
|
else
|
||||||
|
self.avail = min(BURST, self.avail + newavail);
|
||||||
|
self.bChoking = false;
|
||||||
|
end
|
||||||
|
|
||||||
|
self.avail = max(self.avail, 0-(MAX_CPS*2)); -- Can go negative when someone is eating bandwidth past the lib. but we refuse to stay silent for more than 2 seconds; if they can do it, we can.
|
||||||
|
self.LastAvailUpdate = now;
|
||||||
|
|
||||||
|
return self.avail;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- Despooling logic
|
||||||
|
|
||||||
|
function ChatThrottleLib:Despool(Prio)
|
||||||
|
local ring = Prio.Ring;
|
||||||
|
while(ring.pos and Prio.avail>ring.pos[1].nSize) do
|
||||||
|
local msg = tremove(Prio.Ring.pos, 1);
|
||||||
|
if(not Prio.Ring.pos[1]) then
|
||||||
|
local pipe = Prio.Ring.pos;
|
||||||
|
Prio.Ring:Remove(pipe);
|
||||||
|
Prio.ByName[pipe.name] = nil;
|
||||||
|
self.PipeBin:Put(pipe);
|
||||||
|
else
|
||||||
|
Prio.Ring.pos = Prio.Ring.pos.next;
|
||||||
|
end
|
||||||
|
Prio.avail = Prio.avail - msg.nSize;
|
||||||
|
msg.f(msg[1], msg[2], msg[3], msg[4]);
|
||||||
|
Prio.nTotalSent = Prio.nTotalSent + msg.nSize;
|
||||||
|
self.MsgBin:Put(msg);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ChatThrottleLib.OnEvent()
|
||||||
|
-- v11: We know that the rate limiter is touchy after login. Assume that it's touch after zoning, too.
|
||||||
|
self = ChatThrottleLib;
|
||||||
|
if(event == "PLAYER_ENTERING_WORLD") then
|
||||||
|
self.HardThrottlingBeginTime=GetTime(); -- Throttle hard for a few seconds after zoning
|
||||||
|
self.avail = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ChatThrottleLib.OnUpdate()
|
||||||
|
self = ChatThrottleLib;
|
||||||
|
|
||||||
|
self.OnUpdateDelay = self.OnUpdateDelay + arg1;
|
||||||
|
if(self.OnUpdateDelay < 0.08) then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
self.OnUpdateDelay = 0;
|
||||||
|
|
||||||
|
self:UpdateAvail();
|
||||||
|
|
||||||
|
if(self.avail<0) then
|
||||||
|
return; -- argh. some bastard is spewing stuff past the lib. just bail early to save cpu.
|
||||||
|
end
|
||||||
|
|
||||||
|
-- See how many of or priorities have queued messages
|
||||||
|
local n=0;
|
||||||
|
for prioname,Prio in pairs(self.Prio) do
|
||||||
|
if(Prio.Ring.pos or Prio.avail<0) then
|
||||||
|
n=n+1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Anything queued still?
|
||||||
|
if(n<1) then
|
||||||
|
-- Nope. Move spillover bandwidth to global availability gauge and clear self.bQueueing
|
||||||
|
for prioname,Prio in pairs(self.Prio) do
|
||||||
|
self.avail = self.avail + Prio.avail;
|
||||||
|
Prio.avail = 0;
|
||||||
|
end
|
||||||
|
self.bQueueing = false;
|
||||||
|
self.Frame:Hide();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- There's stuff queued. Hand out available bandwidth to priorities as needed and despool their queues
|
||||||
|
local avail= self.avail/n;
|
||||||
|
self.avail = 0;
|
||||||
|
|
||||||
|
for prioname,Prio in pairs(self.Prio) do
|
||||||
|
if(Prio.Ring.pos or Prio.avail<0) then
|
||||||
|
Prio.avail = Prio.avail + avail;
|
||||||
|
if(Prio.Ring.pos and Prio.avail>Prio.Ring.pos[1].nSize) then
|
||||||
|
self:Despool(Prio);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Expire recycled tables if needed
|
||||||
|
self.MsgBin:Tidy();
|
||||||
|
self.PipeBin:Tidy();
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- Spooling logic
|
||||||
|
|
||||||
|
|
||||||
|
function ChatThrottleLib:Enqueue(prioname, pipename, msg)
|
||||||
|
local Prio = self.Prio[prioname];
|
||||||
|
local pipe = Prio.ByName[pipename];
|
||||||
|
if(not pipe) then
|
||||||
|
self.Frame:Show();
|
||||||
|
pipe = self.PipeBin:Get();
|
||||||
|
pipe.name = pipename;
|
||||||
|
Prio.ByName[pipename] = pipe;
|
||||||
|
Prio.Ring:Add(pipe);
|
||||||
|
end
|
||||||
|
|
||||||
|
tinsert(pipe, msg);
|
||||||
|
|
||||||
|
self.bQueueing = true;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, language, destination)
|
||||||
|
if(not (self and prio and text and self.Prio[prio] ) ) then
|
||||||
|
error('Usage: ChatThrottleLib:SendChatMessage("{BULK||NORMAL||ALERT}", "prefix" or nil, "text"[, "chattype"[, "language"[, "destination"]]]', 2);
|
||||||
|
end
|
||||||
|
|
||||||
|
prefix = prefix or tostring(this); -- each frame gets its own queue if prefix is not given
|
||||||
|
|
||||||
|
local nSize = strlen(text) + MSG_OVERHEAD;
|
||||||
|
|
||||||
|
-- Check if there's room in the global available bandwidth gauge to send directly
|
||||||
|
if(not self.bQueueing and nSize < self:UpdateAvail()) then
|
||||||
|
self.avail = self.avail - nSize;
|
||||||
|
self.ORIG_SendChatMessage(text, chattype, language, destination);
|
||||||
|
self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize;
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Message needs to be queued
|
||||||
|
msg=self.MsgBin:Get();
|
||||||
|
msg.f=self.ORIG_SendChatMessage
|
||||||
|
msg[1]=text;
|
||||||
|
msg[2]=chattype or "SAY";
|
||||||
|
msg[3]=language;
|
||||||
|
msg[4]=destination;
|
||||||
|
msg.n = 4
|
||||||
|
msg.nSize = nSize;
|
||||||
|
|
||||||
|
self:Enqueue(prio, format("%s/%s/%s", prefix, chattype, destination or ""), msg);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ChatThrottleLib:SendAddonMessage(prio, prefix, text, chattype)
|
||||||
|
if(not (self and prio and prefix and text and chattype and self.Prio[prio] ) ) then
|
||||||
|
error('Usage: ChatThrottleLib:SendAddonMessage("{BULK||NORMAL||ALERT}", "prefix", "text", "chattype")', 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
local nSize = strlen(prefix) + 1 + strlen(text) + MSG_OVERHEAD;
|
||||||
|
|
||||||
|
-- Check if there's room in the global available bandwidth gauge to send directly
|
||||||
|
if(not self.bQueueing and nSize < self:UpdateAvail()) then
|
||||||
|
self.avail = self.avail - nSize;
|
||||||
|
self.ORIG_SendAddonMessage(prefix, text, chattype);
|
||||||
|
self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize;
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Message needs to be queued
|
||||||
|
msg=self.MsgBin:Get();
|
||||||
|
msg.f=self.ORIG_SendAddonMessage;
|
||||||
|
msg[1]=prefix;
|
||||||
|
msg[2]=text;
|
||||||
|
msg[3]=chattype;
|
||||||
|
msg.n = 3
|
||||||
|
msg.nSize = nSize;
|
||||||
|
|
||||||
|
self:Enqueue(prio, format("%s/%s", prefix, chattype), msg);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- Get the ball rolling!
|
||||||
|
|
||||||
|
ChatThrottleLib:Init();
|
||||||
|
|
||||||
|
--[[ WoWBench debugging snippet
|
||||||
|
if(WOWB_VER) then
|
||||||
|
local function SayTimer()
|
||||||
|
print("SAY: "..GetTime().." "..arg1);
|
||||||
|
end
|
||||||
|
ChatThrottleLib.Frame:SetScript("OnEvent", SayTimer);
|
||||||
|
ChatThrottleLib.Frame:RegisterEvent("CHAT_MSG_SAY");
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
## Interface: 20003
|
||||||
|
## LoadOnDemand: 1
|
||||||
|
## Title: Lib: GraphLib
|
||||||
|
## Version: 1.0
|
||||||
|
## Notes: A library allowing for easy creation of graphs
|
||||||
|
## Author: Cryect
|
||||||
|
## X-Category: Library
|
||||||
|
## X-AceLibrary-Graph-1.0: true
|
||||||
|
## OptionalDeps: Ace2
|
||||||
|
## X-Embeds: Ace2
|
||||||
|
|
||||||
|
AceLibrary\AceLibrary.lua
|
||||||
|
Graph-1.0\Graph-1.0.lua
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,446 @@
|
|||||||
|
--[[
|
||||||
|
Name: Babble-Boss-2.2
|
||||||
|
Revision: $Rev: 17545 $
|
||||||
|
Author(s): ckknight (ckknight@gmail.com)
|
||||||
|
Website: http://ckknight.wowinterface.com/
|
||||||
|
Documentation: http://wiki.wowace.com/index.php/Babble-Boss-2.2
|
||||||
|
SVN: http://svn.wowace.com/root/trunk/Babble-2.2/Babble-Boss-2.2
|
||||||
|
Description: A library to provide localizations for bosses.
|
||||||
|
Dependencies: AceLibrary, AceLocale-2.2
|
||||||
|
|
||||||
|
Rewritten a little and added some "bosses" by Shino
|
||||||
|
]]
|
||||||
|
|
||||||
|
if (GetLocale()=="deDE") then
|
||||||
|
|
||||||
|
local bosses = {
|
||||||
|
["Feueranbeter"] = true,
|
||||||
|
["Avalanchion"] = true,
|
||||||
|
["Der Windpl\195\188nderer"] = true,
|
||||||
|
["Baron Charr"] = true,
|
||||||
|
["Prinzessin Tempestria"] = true,
|
||||||
|
["Grethok der Aufseher"] = true,
|
||||||
|
["Flickwerk"] = true,
|
||||||
|
["Grobbulus"] = true,
|
||||||
|
["Gluth"] = true,
|
||||||
|
["Thaddius"] = true,
|
||||||
|
["Feugen"] = true,
|
||||||
|
["Stalagg"] = true,
|
||||||
|
["Anub'Rekhan"] = true,
|
||||||
|
["Großwitwe Faerlina"] = true,
|
||||||
|
["Maexxna"] = true,
|
||||||
|
["Instrukteur Razuvious"] = true,
|
||||||
|
["Reservist der Todesritter"] = true,
|
||||||
|
["Gothik der Seelenjäger"] = true,
|
||||||
|
["Hochlord Mograine"] = true,
|
||||||
|
["Thane Korth'azz"] = true,
|
||||||
|
["Lady Blaumeux"] = true,
|
||||||
|
["Sire Zeliek"] = true,
|
||||||
|
["Die Vier Reiter"]= true,
|
||||||
|
["Noth der Seuchenfürst"] = true,
|
||||||
|
["Heigan der Unreine"] = true,
|
||||||
|
["Loatheb"] = true,
|
||||||
|
["Saphiron"] = true,
|
||||||
|
["Kel'Thuzad"] = true,
|
||||||
|
["Lord Victor Nefarius"] = true,
|
||||||
|
["Nefarian"] = true,
|
||||||
|
["Vaelastrasz der Verdorbene"] = true,
|
||||||
|
["Razorgore der Ungezähmte"] = true,
|
||||||
|
["Brutwächter Dreschbringer"] = true,
|
||||||
|
["Chromaggus"] = true,
|
||||||
|
["Schattenschwinge"] = true,
|
||||||
|
["Feuerschwinge"] = true,
|
||||||
|
["Flammenmaul"] = true,
|
||||||
|
["Majordomus Exekutus"] = true,
|
||||||
|
["Ragnaros"] = true,
|
||||||
|
["Baron Geddon"] = true,
|
||||||
|
["Golemagg der Verbrenner"] = true,
|
||||||
|
["Garr"] = true,
|
||||||
|
["Sulfuronherold"] = true,
|
||||||
|
["Shazzrah"] = true,
|
||||||
|
["Lucifron"] = true,
|
||||||
|
["Gehennas"] = true,
|
||||||
|
["Magmadar"] = true,
|
||||||
|
["Onyxia"] = true,
|
||||||
|
["Azuregos"] = true,
|
||||||
|
["Smariss"] = true,
|
||||||
|
["Taerar"] = true,
|
||||||
|
["Lethon"] = true,
|
||||||
|
["Jin'do der Verhexer"] = true,
|
||||||
|
["Blutfürst Mandokir"] = true,
|
||||||
|
["Hakkar"] = true,
|
||||||
|
["Lord Kazzak"] = true,
|
||||||
|
["Ysondre"] = true,
|
||||||
|
["Hohepriesterin Jeklik"] = true,
|
||||||
|
["Hohepriester Venoxis"] = true,
|
||||||
|
["Hohepriester Thekal"] = true,
|
||||||
|
["Hohepriesterin Arlokk"] = true,
|
||||||
|
["Hohepriesterin Mar'li"] = true,
|
||||||
|
["Gahz'ranka"] = true,
|
||||||
|
["Gri'lek"] = true,
|
||||||
|
["Hazza'rah"] = true,
|
||||||
|
["Renataki"] = true,
|
||||||
|
["Wushoolay"] = true,
|
||||||
|
["Ayamiss der Jäger"] = true,
|
||||||
|
["Buru der Verschlinger"] = true,
|
||||||
|
["General Rajaxx"] = true,
|
||||||
|
["Generallieutenant Andorov"] = true,
|
||||||
|
["Moam"] = true,
|
||||||
|
["Beschützer des Anubisath"] = true,
|
||||||
|
["Ossirian der Narbenlose"] = true,
|
||||||
|
["Lord Kri"] = true,
|
||||||
|
["Prinzessin Yauj"] = true,
|
||||||
|
["Vem"] = true,
|
||||||
|
["Die Käferfamilie"] = true,
|
||||||
|
["Auge von C'Thun"] = true,
|
||||||
|
["C'Thun"] = true,
|
||||||
|
["Verteidiger des Anubisath"] = true,
|
||||||
|
["Fankriss der Unnachgiebige"] = true,
|
||||||
|
["Prinzessin Huhuran"] = true,
|
||||||
|
["Ouro"] = true,
|
||||||
|
["Schlachtwache Sartura"] = true,
|
||||||
|
["Der Prophet Skeram"] = true,
|
||||||
|
["Imperator Vek'lor"] = true,
|
||||||
|
["Imperator Vek'nilash"] = true,
|
||||||
|
["Die Zwillings-Imperatoren"] = true,
|
||||||
|
["Viscidus"] = true,
|
||||||
|
["Alzzin der Wildformer"] = true,
|
||||||
|
["Botschafter Flamelash"] = true,
|
||||||
|
["Anger'rel"] = true,
|
||||||
|
["Archivar Galford"] = true,
|
||||||
|
["Atal'alarion"] = true,
|
||||||
|
["Avatar von Hakkar"] = true,
|
||||||
|
["Bael'Gar"] = true,
|
||||||
|
["Balnazzar"] = true,
|
||||||
|
["Baroness Anastari"] = true,
|
||||||
|
["Baron Rivendare"] = true,
|
||||||
|
["Captain Kromcrush"] = true,
|
||||||
|
["Celebras der Verfluchte"] = true,
|
||||||
|
["Kristallfangzahn"] = true,
|
||||||
|
["Dunkelmeister Gandling"] = true,
|
||||||
|
["Doktor Theolen Krastinov"] = true,
|
||||||
|
["Un'rel"] = true,
|
||||||
|
["Trott'rel"] = true,
|
||||||
|
["Traumsense"] = true,
|
||||||
|
["Fineous Darkvire"] = true,
|
||||||
|
["Gasher"] = true,
|
||||||
|
["General Angerforge"] = true,
|
||||||
|
["General Drakkisath"] = true,
|
||||||
|
["Dunk'rel"] = true,
|
||||||
|
["Golemlord Argelmach"] = true,
|
||||||
|
["Goraluk Anvilcrack"] = true,
|
||||||
|
["Gyth"] = true,
|
||||||
|
["Halycon"] = true,
|
||||||
|
["Hass'rel"] = true,
|
||||||
|
["Hazzas"] = true,
|
||||||
|
["Herdsinger Forresten"] = true,
|
||||||
|
["Hochlord Omokk"] = true,
|
||||||
|
["Hukku"] = true,
|
||||||
|
["Hurley Blackbreath"] = true,
|
||||||
|
["Hydrobrut"] = true,
|
||||||
|
["Illyanna Ravenoak"] = true,
|
||||||
|
["Immol'thar"] = true,
|
||||||
|
["Instrukteurin Malicia"] = true,
|
||||||
|
["Jammal'an der Prophet"] = true,
|
||||||
|
["Jandice Barov"] = true,
|
||||||
|
["Kirtonos der Herold"] = true,
|
||||||
|
["Lady Illucia Barov"] = true,
|
||||||
|
["Erdrutsch"] = true,
|
||||||
|
["Lethtendris"] = true,
|
||||||
|
["Hüter des Wissens Polkelt"] = true,
|
||||||
|
["Loro"] = true,
|
||||||
|
["Magister Kalendris"] = true,
|
||||||
|
["Magistrat Barthilas"] = true,
|
||||||
|
["Magmus"] = true,
|
||||||
|
["Maleki der Leichenblasse"] = true,
|
||||||
|
["Marduk Blackpool"] = true,
|
||||||
|
["Meshlok der Ernter"] = true,
|
||||||
|
["Mijan"] = true,
|
||||||
|
["Morphaz"] = true,
|
||||||
|
["Mutter Glimmernetz"] = true,
|
||||||
|
["Nerub'enkan"] = true,
|
||||||
|
["Noxxion"] = true,
|
||||||
|
["Ogom der Elende"] = true,
|
||||||
|
["Oberanführer Wyrmthalak"] = true,
|
||||||
|
["Phalanx"] = true,
|
||||||
|
["Plugger Spazzring"] = true,
|
||||||
|
["Postmeister Malown"] = true,
|
||||||
|
["Prinzessin Moira Bronzebeard"] = true,
|
||||||
|
["Prinzessin Theradras"] = true,
|
||||||
|
["Prinz Tortheldrin"] = true,
|
||||||
|
["Pusillin"] = true,
|
||||||
|
["Feuerwache Glutseher"] = true,
|
||||||
|
["Ramstein der Verschlinger"] = true,
|
||||||
|
["Blutrippe"] = true,
|
||||||
|
["Schlingwurzler"] = true,
|
||||||
|
["Ribbly Screwspigot"] = true,
|
||||||
|
["Faulschnapper"] = true,
|
||||||
|
["Wut'rel"] = true,
|
||||||
|
["Eranikus' Schemen"] = true,
|
||||||
|
["Solakar Feuerkrone"] = true,
|
||||||
|
["Stampfer Kreeg"] = true,
|
||||||
|
["Tendris Wucherborke"] = true,
|
||||||
|
["Timmy der Grausame"] = true,
|
||||||
|
["Tüftler Gizlock"] = true,
|
||||||
|
["Tsu'zee"] = true,
|
||||||
|
["Vectus"] = true,
|
||||||
|
["Bös'rel"] = true,
|
||||||
|
["Wirker"] = true,
|
||||||
|
["Zevrim Thornhoof"] = true,
|
||||||
|
["Zolo"] = true,
|
||||||
|
["Zul'Lor"] = true,
|
||||||
|
["Kanonenmeister Willey"] = true,
|
||||||
|
["Imperator Dagran Thaurissan"] = true,
|
||||||
|
["Wache Fengus"] = true,
|
||||||
|
["Wache Mol'dar"] = true,
|
||||||
|
["Wache Slip'kik"] = true,
|
||||||
|
["Verhörmeisterin Gerstahn"] = true,
|
||||||
|
["König Gordok"] = true,
|
||||||
|
["Lord Alexei Barov"] = true,
|
||||||
|
["Lord Incendius"] = true,
|
||||||
|
["Lord Schlangenzunge"] = true,
|
||||||
|
["Ras Frostraunen"] = true,
|
||||||
|
["Kriegshäuptling Rend Blackhand"] = true,
|
||||||
|
["Schattenjägerin Vosh'gajin"] = true,
|
||||||
|
["Die Bestie"] = true,
|
||||||
|
["Der Ravenier"] = true,
|
||||||
|
["Kriegsmeister Voone"] = true,
|
||||||
|
|
||||||
|
-- From Mendeleev
|
||||||
|
["Cho'Rush der Beobachter"] = true,
|
||||||
|
["Lord Hel'nurath"] = true,
|
||||||
|
["Pimgib"] = true,
|
||||||
|
["Knot Thimblejack's True"] = true,
|
||||||
|
["Kanonnenmeister Willey"] = true,
|
||||||
|
["Imperator Dagran Thaurissian"] = true,
|
||||||
|
["Erzmagier Arugal"] = true,
|
||||||
|
["Erzmagier Arugal's Leerwanderer"] = true,
|
||||||
|
["Baron Silberleine"] = true,
|
||||||
|
["Kommander Frühlingvale"] = true,
|
||||||
|
["Todeswachen Captain"] = true,
|
||||||
|
["Fenrus der Fresser"] = true,
|
||||||
|
["Odo der Blindwächter"] = true,
|
||||||
|
["Rasiermesserklaue der Metzger"] = true,
|
||||||
|
["Wolfmeister Nados"] = true,
|
||||||
|
["Rend Blackhand"] = true,
|
||||||
|
["Kurinnaxx"] = true,
|
||||||
|
|
||||||
|
-- Costum bosses
|
||||||
|
["Firesworn"] = true,
|
||||||
|
|
||||||
|
["Avalanchion"] = true,
|
||||||
|
["The Windreaver"] = true,
|
||||||
|
["Baron Charr"] = true,
|
||||||
|
["Princess Tempestria"] = true,
|
||||||
|
["Grethok the Controller"] = true,
|
||||||
|
["Patchwerk"] = true,
|
||||||
|
["Grobbulus"] = true,
|
||||||
|
["Gluth"] = true,
|
||||||
|
["Feugen"] = true,
|
||||||
|
["Stalagg"] = true,
|
||||||
|
["Thaddius"] = true,
|
||||||
|
["Anub'Rekhan"] = true,
|
||||||
|
["Grand Widow Faerlina"] = true,
|
||||||
|
["Maexxna"] = true,
|
||||||
|
["Instructor Razuvious"] = true,
|
||||||
|
--["Deathknight Understudy"] = true,
|
||||||
|
["Gothik the Harvester"] = true,
|
||||||
|
["Highlord Mograine"] = true,
|
||||||
|
["Thane Korth'azz"] = true,
|
||||||
|
["Lady Blaumeux"] = true,
|
||||||
|
["Sir Zeliek"] = true,
|
||||||
|
["The Four Horsemen"] = true,
|
||||||
|
["Noth the Plaguebringer"] = true,
|
||||||
|
["Heigan the Unclean"] = true,
|
||||||
|
["Loatheb"] = true,
|
||||||
|
["Sapphiron"] = true,
|
||||||
|
["Kel'Thuzad"] = true,
|
||||||
|
["Lord Victor Nefarius"] = true,
|
||||||
|
["Nefarian"] = true,
|
||||||
|
["Vaelastrasz the Corrupt"] = true,
|
||||||
|
["Razorgore the Untamed"] = true,
|
||||||
|
["Broodlord Lashlayer"] = true,
|
||||||
|
["Chromaggus"] = true,
|
||||||
|
["Ebonroc"] = true,
|
||||||
|
["Firemaw"] = true,
|
||||||
|
["Flamegor"] = true,
|
||||||
|
["Majordomo Executus"] = true,
|
||||||
|
["Ragnaros"] = true,
|
||||||
|
["Baron Geddon"] = true,
|
||||||
|
["Golemagg the Incinerator"] = true,
|
||||||
|
["Garr"] = true,
|
||||||
|
["Sulfuron Harbinger"] = true,
|
||||||
|
["Shazzrah"] = true,
|
||||||
|
["Lucifron"] = true,
|
||||||
|
["Gehennas"] = true,
|
||||||
|
["Magmadar"] = true,
|
||||||
|
["Onyxia"] = true,
|
||||||
|
["Azuregos"] = true,
|
||||||
|
["Lord Kazzak"] = true,
|
||||||
|
["Ysondre"] = true,
|
||||||
|
["Emeriss"] = true,
|
||||||
|
["Taerar"] = true,
|
||||||
|
["Lethon"] = true,
|
||||||
|
["High Priestess Jeklik"] = true,
|
||||||
|
["High Priest Venoxis"] = true,
|
||||||
|
["High Priest Thekal"] = true,
|
||||||
|
["High Priestess Arlokk"] = true,
|
||||||
|
["High Priestess Mar'li"] = true,
|
||||||
|
["Jin'do the Hexxer"] = true,
|
||||||
|
["Bloodlord Mandokir"] = true,
|
||||||
|
["Gahz'ranka"] = true,
|
||||||
|
["Gri'lek"] = true,
|
||||||
|
["Hazza'rah"] = true,
|
||||||
|
["Renataki"] = true,
|
||||||
|
["Wushoolay"] = true,
|
||||||
|
["Hakkar"] = true,
|
||||||
|
["Ayamiss the Hunter"] = true,
|
||||||
|
["Buru the Gorger"] = true,
|
||||||
|
["General Rajaxx"] = true,
|
||||||
|
["Lieutenant General Andorov"] = true,
|
||||||
|
["Moam"] = true,
|
||||||
|
["Ossirian the Unscarred"] = true,
|
||||||
|
["Lord Kri"] = true,
|
||||||
|
["Princess Yauj"] = true,
|
||||||
|
["Vem"] = true,
|
||||||
|
["The Bug Family"] = true,
|
||||||
|
["Eye of C'Thun"] = true,
|
||||||
|
["C'Thun"] = true,
|
||||||
|
["Fankriss the Unyielding"] = true,
|
||||||
|
["Princess Huhuran"] = true,
|
||||||
|
["Ouro"] = true,
|
||||||
|
["Battleguard Sartura"] = true,
|
||||||
|
["The Prophet Skeram"] = true,
|
||||||
|
["Emperor Vek'lor"] = true,
|
||||||
|
["Emperor Vek'nilash"] = true,
|
||||||
|
["The Twin Emperors"] = true,
|
||||||
|
["Viscidus"] = true,
|
||||||
|
["Alzzin the Wildshaper"] = true,
|
||||||
|
["Ambassador Flamelash"] = true,
|
||||||
|
["Anger'rel"] = true,
|
||||||
|
["Archivist Galford"] = true,
|
||||||
|
["Atal'alarion"] = true,
|
||||||
|
["Avatar of Hakkar"] = true,
|
||||||
|
["Bael'Gar"] = true,
|
||||||
|
["Balnazzar"] = true,
|
||||||
|
["Baroness Anastari"] = true,
|
||||||
|
["Baron Rivendare"] = true,
|
||||||
|
["Cannon Master Willey"] = true,
|
||||||
|
["Captain Kromcrush"] = true,
|
||||||
|
["Celebras the Cursed"] = true,
|
||||||
|
["Crystal Fang"] = true,
|
||||||
|
["Darkmaster Gandling"] = true,
|
||||||
|
["Doctor Theolen Krastinov"] = true,
|
||||||
|
["Doom'rel"] = true,
|
||||||
|
["Dope'rel"] = true,
|
||||||
|
["Dreamscythe"] = true,
|
||||||
|
["Emperor Dagran Thaurissan"] = true,
|
||||||
|
["Fineous Darkvire"] = true,
|
||||||
|
["Gasher"] = true,
|
||||||
|
["General Angerforge"] = true,
|
||||||
|
["General Drakkisath"] = true,
|
||||||
|
["Gloom'rel"] = true,
|
||||||
|
["Golem Lord Argelmach"] = true,
|
||||||
|
["Goraluk Anvilcrack"] = true,
|
||||||
|
["Guard Fengus"] = true,
|
||||||
|
["Guard Mol'dar"] = true,
|
||||||
|
["Guard Slip'kik"] = true,
|
||||||
|
["Gyth"] = true,
|
||||||
|
["Halycon"] = true,
|
||||||
|
["Hate'rel"] = true,
|
||||||
|
["Hazzas"] = true,
|
||||||
|
["Hearthsinger Forresten"] = true,
|
||||||
|
["High Interrogator Gerstahn"] = true,
|
||||||
|
["Highlord Omokk"] = true,
|
||||||
|
["Hukku"] = true,
|
||||||
|
["Hurley Blackbreath"] = true,
|
||||||
|
["Hydrospawn"] = true,
|
||||||
|
["Illyanna Ravenoak"] = true,
|
||||||
|
["Immol'thar"] = true,
|
||||||
|
["Instructor Malicia"] = true,
|
||||||
|
["Jammal'an the Prophet"] = true,
|
||||||
|
["Jandice Barov"] = true,
|
||||||
|
["King Gordok"] = true,
|
||||||
|
["Kirtonos the Herald"] = true,
|
||||||
|
["Lady Illucia Barov"] = true,
|
||||||
|
["Landslide"] = true,
|
||||||
|
["Lethtendris"] = true,
|
||||||
|
["Lord Alexei Barov"] = true,
|
||||||
|
["Lord Incendius"] = true,
|
||||||
|
["Lord Vyletongue"] = true,
|
||||||
|
["Lorekeeper Polkelt"] = true,
|
||||||
|
["Loro"] = true,
|
||||||
|
["Magister Kalendris"] = true,
|
||||||
|
["Magistrate Barthilas"] = true,
|
||||||
|
["Magmus"] = true,
|
||||||
|
["Maleki the Pallid"] = true,
|
||||||
|
["Marduk Blackpool"] = true,
|
||||||
|
["Meshlok the Harvester"] = true,
|
||||||
|
["Mijan"] = true,
|
||||||
|
["Morphaz"] = true,
|
||||||
|
["Mother Smolderweb"] = true,
|
||||||
|
["Nerub'enkan"] = true,
|
||||||
|
["Noxxion"] = true,
|
||||||
|
["Ogom the Wretched"] = true,
|
||||||
|
["Overlord Wyrmthalak"] = true,
|
||||||
|
["Phalanx"] = true,
|
||||||
|
["Plugger Spazzring"] = true,
|
||||||
|
["Postmaster Malown"] = true,
|
||||||
|
["Princess Moira Bronzebeard"] = true,
|
||||||
|
["Princess Theradras"] = true,
|
||||||
|
["Prince Tortheldrin"] = true,
|
||||||
|
["Pusillin"] = true,
|
||||||
|
["Pyroguard Emberseer"] = true,
|
||||||
|
["Ramstein the Gorger"] = true,
|
||||||
|
["Ras Frostwhisper"] = true,
|
||||||
|
["Rattlegore"] = true,
|
||||||
|
["Razorlash"] = true,
|
||||||
|
["Warchief Rend Blackhand"] = true,
|
||||||
|
["Ribbly Screwspigot"] = true,
|
||||||
|
["Rotgrip"] = true,
|
||||||
|
["Seeth'rel"] = true,
|
||||||
|
["Shade of Eranikus"] = true,
|
||||||
|
["Shadow Hunter Vosh'gajin"] = true,
|
||||||
|
["Solakar Flamewreath"] = true,
|
||||||
|
["Stomper Kreeg"] = true,
|
||||||
|
["Tendris Warpwood"] = true,
|
||||||
|
["The Beast"] = true,
|
||||||
|
["The Ravenian"] = true,
|
||||||
|
["Timmy the Cruel"] = true,
|
||||||
|
["Tinkerer Gizlock"] = true,
|
||||||
|
["Tsu'zee"] = true,
|
||||||
|
["Vectus"] = true,
|
||||||
|
["Vile'rel"] = true,
|
||||||
|
["War Master Voone"] = true,
|
||||||
|
["Weaver"] = true,
|
||||||
|
["Zevrim Thornhoof"] = true,
|
||||||
|
["Zolo"] = true,
|
||||||
|
["Zul'Lor"] = true,
|
||||||
|
|
||||||
|
-- From Mendeleev
|
||||||
|
["Cho'Rush the Observer"] = true,
|
||||||
|
["Lord Hel'nurath"] = true,
|
||||||
|
["Pimgib"] = true,
|
||||||
|
["Knot Thimblejack's Cache"] = true,
|
||||||
|
["Cannonmaster Willey"] = true,
|
||||||
|
["Emperor Dagran Thaurissian"] = true,
|
||||||
|
["Archmage Arugal"] = true,
|
||||||
|
["Archmage Arugal's Voidwalker"] = true,
|
||||||
|
["Baron Silverlaine"] = true,
|
||||||
|
["Commander Springvale"] = true,
|
||||||
|
["Deathsworn Captain"] = true,
|
||||||
|
["Fenrus the Devourer"] = true,
|
||||||
|
["Odo the Blindwatcher"] = true,
|
||||||
|
["Razorclaw the Butcher"] = true,
|
||||||
|
["Wolf Master Nandos"] = true,
|
||||||
|
["Rend Blackhand"] = true,
|
||||||
|
["Kurinnaxx"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
BabbleBoss = {}
|
||||||
|
function BabbleBoss:Contains(name)
|
||||||
|
return bosses[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.BabbleBoss = BabbleBoss
|
||||||
|
end
|
||||||
@@ -0,0 +1,442 @@
|
|||||||
|
--[[
|
||||||
|
Name: Babble-Boss-2.2
|
||||||
|
Revision: $Rev: 17545 $
|
||||||
|
Author(s): ckknight (ckknight@gmail.com)
|
||||||
|
Website: http://ckknight.wowinterface.com/
|
||||||
|
Documentation: http://wiki.wowace.com/index.php/Babble-Boss-2.2
|
||||||
|
SVN: http://svn.wowace.com/root/trunk/Babble-2.2/Babble-Boss-2.2
|
||||||
|
Description: A library to provide localizations for bosses.
|
||||||
|
Dependencies: AceLibrary, AceLocale-2.2
|
||||||
|
|
||||||
|
Rewritten a little and added some "bosses" by Shino
|
||||||
|
]]
|
||||||
|
|
||||||
|
if (GetLocale()=="frFR") then
|
||||||
|
|
||||||
|
local bosses = {
|
||||||
|
["Avalanchion"] = true,
|
||||||
|
["Ouraganien"] = true,
|
||||||
|
["Baron Charr"] = true,
|
||||||
|
["Princesse Tempestria"] = true,
|
||||||
|
["Grethok le Contr\195\180leur"] = true,
|
||||||
|
["Le Recousu"] = true,
|
||||||
|
["Grobbulus"] = true,
|
||||||
|
["Gluth"] = true,
|
||||||
|
["Feugen"] = true, -- CHECK
|
||||||
|
["Stalagg"] = true, -- CHECK
|
||||||
|
["Thaddius"] = true,
|
||||||
|
["Anub'Rekhan"] = true,
|
||||||
|
["Grande veuve Faerlina"] = true,
|
||||||
|
["Maexxna"] = true,
|
||||||
|
["Instructeur Razuvious"] = true,
|
||||||
|
["Doublure de chevalier de la mort"] = true, -- CHECK
|
||||||
|
["Gothik le Moissonneur"] = true,
|
||||||
|
["Grand Seigneur Mograine"] = true, -- CHECK
|
||||||
|
["Thane Korth'azz"] = true, -- CHECK
|
||||||
|
["Dame Blaumeux"] = true, -- CHECK
|
||||||
|
["Sir Zeliek "] = true, -- CHECK
|
||||||
|
["Les 4 Cavaliers"] = true,
|
||||||
|
["Noth the Plaguebringer"] ="Noth le Porte-peste",
|
||||||
|
["Heigan l'Impur"] = true,
|
||||||
|
["Horreb"] = true,
|
||||||
|
["Sapphiron"] = true,
|
||||||
|
["Kel'Thuzad"] = true,
|
||||||
|
["Seigneur Victor Nefarius"] = true,
|
||||||
|
["Nefarian"] = true,
|
||||||
|
["Vaelastrasz le Corrompu"] = true,
|
||||||
|
["Tranchetripe l'Indompt\195\169"] = true,
|
||||||
|
["Seigneur des couv\195\169es Lashlayer"] = true,
|
||||||
|
["Chromaggus"] = true,
|
||||||
|
["Roch\195\169b\195\168ne"] = true,
|
||||||
|
["Gueule-de-feu"] = true,
|
||||||
|
["Flamegor"] = true,
|
||||||
|
["Chambellan Executus"] = true,
|
||||||
|
["Ragnaros"] = true,
|
||||||
|
["Baron Geddon"] = true,
|
||||||
|
["Golemagg l'Incin\195\169rateur"] = true,
|
||||||
|
["Garr"] = true,
|
||||||
|
["Messager de Sulfuron"] = true,
|
||||||
|
["Shazzrah"] = true,
|
||||||
|
["Lucifron"] = true,
|
||||||
|
["Gehennas"] = true,
|
||||||
|
["Magmadar"] = true,
|
||||||
|
["Onyxia"] = true,
|
||||||
|
["Azuregos"] = true,
|
||||||
|
["Seigneur Kazzak"] = true,
|
||||||
|
["Ysondre"] = true,
|
||||||
|
["Emeriss"] = true,
|
||||||
|
["Taerar"] = true,
|
||||||
|
["L\195\169thon"] = true,
|
||||||
|
["Grande pr\195\170tresse Jeklik"] = true,
|
||||||
|
["Grand pr\195\170tre Venoxis"] = true,
|
||||||
|
["Grand pr\195\170tre Thekal"] = true,
|
||||||
|
["Grande pr\195\170tresse Arlokk"] = true,
|
||||||
|
["Grande pr\195\170tresse Mar'li"] = true,
|
||||||
|
["Jin'do le Mal\195\169ficieur"] = true,
|
||||||
|
["Seigneur sanglant Mandokir"] = true,
|
||||||
|
["Gahz'ranka"] = true,
|
||||||
|
["Gri'lek"] = true,
|
||||||
|
["Hazza'rah"] = true,
|
||||||
|
["Renataki"] = true,
|
||||||
|
["Wushoolay"] = true,
|
||||||
|
["Hakkar"] = true,
|
||||||
|
["Ayamiss le Chasseur"] = true,
|
||||||
|
["Buru Grandgosier"] = true,
|
||||||
|
["G\195\169n\195\169ral Rajaxx"] = true,
|
||||||
|
["G\195\169n\195\169ral de division Andorov"] = true,
|
||||||
|
["Moam"] = true,
|
||||||
|
["Gardien Anubisath"] = true,
|
||||||
|
["Ossirian l'Intouch\195\169"] = true,
|
||||||
|
["Seigneur Kri"] = true,
|
||||||
|
["Princesse Yauj"] = true,
|
||||||
|
["Vem"] = true,
|
||||||
|
["La famille insecte"] = true,
|
||||||
|
["Oeil de C'Thun"] = true,
|
||||||
|
["C'Thun"] = true,
|
||||||
|
["D\195\169fenseur Anubisath"] = true,
|
||||||
|
["Fankriss l'Inflexible"] = true,
|
||||||
|
["Princesse Huhuran"] = true,
|
||||||
|
["Ouro"] = true,
|
||||||
|
["Garde de guerre Sartura"] = true,
|
||||||
|
["Le Proph\195\168te Skeram"] = true,
|
||||||
|
["Empereur Vek'lor"] = true,
|
||||||
|
["Empereur Vek'nilash"] = true,
|
||||||
|
["Les Empereurs jumeaux"] = true,
|
||||||
|
["Viscidus"] = true,
|
||||||
|
["Alzzin le Modeleur"] = true,
|
||||||
|
["Ambassadeur Cinglefouet"] = true,
|
||||||
|
["Col\195\169'rel"] = true,
|
||||||
|
["Archiviste Galford"] = true,
|
||||||
|
["Atal'alarion"] = true,
|
||||||
|
["Avatar d'Hakkar"] = true,
|
||||||
|
["Bael'Gar"] = true,
|
||||||
|
["Balnazzar"] = true,
|
||||||
|
["Baronne Anastari"] = true,
|
||||||
|
["Baron Rivendare"] = true,
|
||||||
|
["Ma\195\174tre canonnier Willey"] = true,
|
||||||
|
["Capitaine Kromcrush"] = true,
|
||||||
|
["Celebras le Maudit"] = true,
|
||||||
|
["Croc cristallin"] = true,
|
||||||
|
["Sombre Ma\195\174tre Gandling"] = true,
|
||||||
|
["Docteur Theolen Krastinov"] = true,
|
||||||
|
["Tragi'rel"] = true,
|
||||||
|
["Demeu'rel"] = true,
|
||||||
|
["Fauche-r\195\170ve"] = true,
|
||||||
|
["Empereur Dagran Thaurissan"] = true,
|
||||||
|
["Fineous Darkvire"] = true,
|
||||||
|
["Gasher"] = true,
|
||||||
|
["G\195\169n\195\169ral Angerforge"] = true,
|
||||||
|
["G\195\169n\195\169ral Drakkisath"] = true,
|
||||||
|
["Fun\195\169b'rel"] = true,
|
||||||
|
["Seigneur golem Argelmach"] = true,
|
||||||
|
["Goraluk Anvilcrack"] = true,
|
||||||
|
["Garde Fengus"] = true,
|
||||||
|
["Garde Mol'dar"] = true,
|
||||||
|
["Garde Slip'kik"] = true,
|
||||||
|
["Gyth"] = true,
|
||||||
|
["Halycon"] = true,
|
||||||
|
["Haine'rel"] = true,
|
||||||
|
["Hazzas"] = true,
|
||||||
|
["Hearthsinger Forresten"] = true,
|
||||||
|
["Grand Interrogateur Gerstahn"] = true,
|
||||||
|
["G\195\169n\195\169ralissime Omokk"] = true,
|
||||||
|
["Hukku"] = true,
|
||||||
|
["Hurley Blackbreath"] = true,
|
||||||
|
["Hydrog\195\169nos"] = true,
|
||||||
|
["Illyanna Ravenoak"] = true,
|
||||||
|
["Immol'thar"] = true,
|
||||||
|
["Instructeur Malicia"] = true,
|
||||||
|
["Jammal'an le proph\195\168te"] = true,
|
||||||
|
["Jandice Barov"] = true,
|
||||||
|
["Roi Gordok"] = true,
|
||||||
|
["Kirtonos le H\195\169raut"] = true,
|
||||||
|
["Dame Illucia Barov"] = true,
|
||||||
|
["Glissement de terrain"] = true,
|
||||||
|
["Lethtendris"] = true,
|
||||||
|
["Seigneur Alexei Barov"] = true,
|
||||||
|
["Seigneur Incendius"] = true,
|
||||||
|
["Seigneur Vylelangue"] = true,
|
||||||
|
["Gardien du savoir Polkelt"] = true,
|
||||||
|
["Loro"] = true,
|
||||||
|
["Magist\195\168re Kalendris"] = true,
|
||||||
|
["Magistrat Barthilas"] = true,
|
||||||
|
["Magmus"] = true,
|
||||||
|
["Maleki le Blafard"] = true,
|
||||||
|
["Marduk Noir\195\169tang"] = true,
|
||||||
|
["Meshlok le Moissonneur"] = true,
|
||||||
|
["Mijan"] = true,
|
||||||
|
["Morphaz"] = true,
|
||||||
|
["Matriarche Couveuse"] = true,
|
||||||
|
["Nerub'enkan"] = true,
|
||||||
|
["Noxxion"] = true,
|
||||||
|
["Ogom le Mis\195\169rable"] = true,
|
||||||
|
["Seigneur Wyrmthalak"] = true,
|
||||||
|
["Phalange"] = true,
|
||||||
|
["Plugger Spazzring"] = true,
|
||||||
|
["Postier Malown"] = true,
|
||||||
|
["Princesse Moira Bronzebeard"] = true,
|
||||||
|
["Princesse Theradras"] = true,
|
||||||
|
["Prince Tortheldrin"] = true,
|
||||||
|
["Pusillin"] = true,
|
||||||
|
["Pyrogarde Proph\195\168te ardent"] = true,
|
||||||
|
["Ramstein Grandgosier"] = true,
|
||||||
|
["Ras Murmegivre"] = true,
|
||||||
|
["Cliquettripes"] = true,
|
||||||
|
["Tranchefouet"] = true,
|
||||||
|
["Chef de guerre Rend Blackhand"] = true,
|
||||||
|
["Ribbly Screwspigot"] = true,
|
||||||
|
["Grippe-charogne"] = true,
|
||||||
|
["Fulmi'rel"] = true,
|
||||||
|
["Ombre d'Eranikus"] = true,
|
||||||
|
["Chasseresse des ombres Vosh'gajin"] = true,
|
||||||
|
["Solakar Voluteflamme"] = true,
|
||||||
|
["Kreeg le Marteleur"] = true,
|
||||||
|
["Tendris Crochebois"] = true,
|
||||||
|
["La B\195\170te"] = true,
|
||||||
|
["Le Voracien"] = true,
|
||||||
|
["Timmy le Cruel"] = true,
|
||||||
|
["Artisan Gizlock"] = true,
|
||||||
|
["Tsu'zee"] = true,
|
||||||
|
["Vectus"] = true,
|
||||||
|
["Ignobl'rel"] = true,
|
||||||
|
["Ma\195\174tre de guerre Voone"] = true,
|
||||||
|
["Tisserand"] = true,
|
||||||
|
["Zevrim Thornhoof"] = true,
|
||||||
|
["Zolo"] = true,
|
||||||
|
["Zul'Lor"] = true,
|
||||||
|
|
||||||
|
-- From Mendeleev
|
||||||
|
["Cho'Rush l'Observateur"] = true,
|
||||||
|
["Seigneur Hel'nurath"] = true,
|
||||||
|
["Pimgib"] = true,
|
||||||
|
["R\195\169serve de Knot Thimblejack"] = true,
|
||||||
|
["Archimage Arugal"] = true,
|
||||||
|
["Marcheur du Vide d'Arugal"] = true,
|
||||||
|
["Baron d'Argelaine"] = true,
|
||||||
|
["Commandant Springvale"] = true,
|
||||||
|
["Capitaine Ligemort"] = true,
|
||||||
|
["Fenrus le D\195\169voreur"] = true,
|
||||||
|
["Odo l'Aveugle"] = true,
|
||||||
|
["Tranchegriffe le Boucher"] = true,
|
||||||
|
["Ma\195\174tre-loup Nandos"] = true,
|
||||||
|
["Kurinnaxx"] = true,
|
||||||
|
|
||||||
|
-- Costum bosses
|
||||||
|
["Firesworn"] = true,
|
||||||
|
|
||||||
|
["Avalanchion"] = true,
|
||||||
|
["The Windreaver"] = true,
|
||||||
|
["Baron Charr"] = true,
|
||||||
|
["Princess Tempestria"] = true,
|
||||||
|
["Grethok the Controller"] = true,
|
||||||
|
["Patchwerk"] = true,
|
||||||
|
["Grobbulus"] = true,
|
||||||
|
["Gluth"] = true,
|
||||||
|
["Feugen"] = true,
|
||||||
|
["Stalagg"] = true,
|
||||||
|
["Thaddius"] = true,
|
||||||
|
["Anub'Rekhan"] = true,
|
||||||
|
["Grand Widow Faerlina"] = true,
|
||||||
|
["Maexxna"] = true,
|
||||||
|
["Instructor Razuvious"] = true,
|
||||||
|
--["Deathknight Understudy"] = true,
|
||||||
|
["Gothik the Harvester"] = true,
|
||||||
|
["Highlord Mograine"] = true,
|
||||||
|
["Thane Korth'azz"] = true,
|
||||||
|
["Lady Blaumeux"] = true,
|
||||||
|
["Sir Zeliek"] = true,
|
||||||
|
["The Four Horsemen"] = true,
|
||||||
|
["Noth the Plaguebringer"] = true,
|
||||||
|
["Heigan the Unclean"] = true,
|
||||||
|
["Loatheb"] = true,
|
||||||
|
["Sapphiron"] = true,
|
||||||
|
["Kel'Thuzad"] = true,
|
||||||
|
["Lord Victor Nefarius"] = true,
|
||||||
|
["Nefarian"] = true,
|
||||||
|
["Vaelastrasz the Corrupt"] = true,
|
||||||
|
["Razorgore the Untamed"] = true,
|
||||||
|
["Broodlord Lashlayer"] = true,
|
||||||
|
["Chromaggus"] = true,
|
||||||
|
["Ebonroc"] = true,
|
||||||
|
["Firemaw"] = true,
|
||||||
|
["Flamegor"] = true,
|
||||||
|
["Majordomo Executus"] = true,
|
||||||
|
["Ragnaros"] = true,
|
||||||
|
["Baron Geddon"] = true,
|
||||||
|
["Golemagg the Incinerator"] = true,
|
||||||
|
["Garr"] = true,
|
||||||
|
["Sulfuron Harbinger"] = true,
|
||||||
|
["Shazzrah"] = true,
|
||||||
|
["Lucifron"] = true,
|
||||||
|
["Gehennas"] = true,
|
||||||
|
["Magmadar"] = true,
|
||||||
|
["Onyxia"] = true,
|
||||||
|
["Azuregos"] = true,
|
||||||
|
["Lord Kazzak"] = true,
|
||||||
|
["Ysondre"] = true,
|
||||||
|
["Emeriss"] = true,
|
||||||
|
["Taerar"] = true,
|
||||||
|
["Lethon"] = true,
|
||||||
|
["High Priestess Jeklik"] = true,
|
||||||
|
["High Priest Venoxis"] = true,
|
||||||
|
["High Priest Thekal"] = true,
|
||||||
|
["High Priestess Arlokk"] = true,
|
||||||
|
["High Priestess Mar'li"] = true,
|
||||||
|
["Jin'do the Hexxer"] = true,
|
||||||
|
["Bloodlord Mandokir"] = true,
|
||||||
|
["Gahz'ranka"] = true,
|
||||||
|
["Gri'lek"] = true,
|
||||||
|
["Hazza'rah"] = true,
|
||||||
|
["Renataki"] = true,
|
||||||
|
["Wushoolay"] = true,
|
||||||
|
["Hakkar"] = true,
|
||||||
|
["Ayamiss the Hunter"] = true,
|
||||||
|
["Buru the Gorger"] = true,
|
||||||
|
["General Rajaxx"] = true,
|
||||||
|
["Lieutenant General Andorov"] = true,
|
||||||
|
["Moam"] = true,
|
||||||
|
["Ossirian the Unscarred"] = true,
|
||||||
|
["Lord Kri"] = true,
|
||||||
|
["Princess Yauj"] = true,
|
||||||
|
["Vem"] = true,
|
||||||
|
["The Bug Family"] = true,
|
||||||
|
["Eye of C'Thun"] = true,
|
||||||
|
["C'Thun"] = true,
|
||||||
|
["Fankriss the Unyielding"] = true,
|
||||||
|
["Princess Huhuran"] = true,
|
||||||
|
["Ouro"] = true,
|
||||||
|
["Battleguard Sartura"] = true,
|
||||||
|
["The Prophet Skeram"] = true,
|
||||||
|
["Emperor Vek'lor"] = true,
|
||||||
|
["Emperor Vek'nilash"] = true,
|
||||||
|
["The Twin Emperors"] = true,
|
||||||
|
["Viscidus"] = true,
|
||||||
|
["Alzzin the Wildshaper"] = true,
|
||||||
|
["Ambassador Flamelash"] = true,
|
||||||
|
["Anger'rel"] = true,
|
||||||
|
["Archivist Galford"] = true,
|
||||||
|
["Atal'alarion"] = true,
|
||||||
|
["Avatar of Hakkar"] = true,
|
||||||
|
["Bael'Gar"] = true,
|
||||||
|
["Balnazzar"] = true,
|
||||||
|
["Baroness Anastari"] = true,
|
||||||
|
["Baron Rivendare"] = true,
|
||||||
|
["Cannon Master Willey"] = true,
|
||||||
|
["Captain Kromcrush"] = true,
|
||||||
|
["Celebras the Cursed"] = true,
|
||||||
|
["Crystal Fang"] = true,
|
||||||
|
["Darkmaster Gandling"] = true,
|
||||||
|
["Doctor Theolen Krastinov"] = true,
|
||||||
|
["Doom'rel"] = true,
|
||||||
|
["Dope'rel"] = true,
|
||||||
|
["Dreamscythe"] = true,
|
||||||
|
["Emperor Dagran Thaurissan"] = true,
|
||||||
|
["Fineous Darkvire"] = true,
|
||||||
|
["Gasher"] = true,
|
||||||
|
["General Angerforge"] = true,
|
||||||
|
["General Drakkisath"] = true,
|
||||||
|
["Gloom'rel"] = true,
|
||||||
|
["Golem Lord Argelmach"] = true,
|
||||||
|
["Goraluk Anvilcrack"] = true,
|
||||||
|
["Guard Fengus"] = true,
|
||||||
|
["Guard Mol'dar"] = true,
|
||||||
|
["Guard Slip'kik"] = true,
|
||||||
|
["Gyth"] = true,
|
||||||
|
["Halycon"] = true,
|
||||||
|
["Hate'rel"] = true,
|
||||||
|
["Hazzas"] = true,
|
||||||
|
["Hearthsinger Forresten"] = true,
|
||||||
|
["High Interrogator Gerstahn"] = true,
|
||||||
|
["Highlord Omokk"] = true,
|
||||||
|
["Hukku"] = true,
|
||||||
|
["Hurley Blackbreath"] = true,
|
||||||
|
["Hydrospawn"] = true,
|
||||||
|
["Illyanna Ravenoak"] = true,
|
||||||
|
["Immol'thar"] = true,
|
||||||
|
["Instructor Malicia"] = true,
|
||||||
|
["Jammal'an the Prophet"] = true,
|
||||||
|
["Jandice Barov"] = true,
|
||||||
|
["King Gordok"] = true,
|
||||||
|
["Kirtonos the Herald"] = true,
|
||||||
|
["Lady Illucia Barov"] = true,
|
||||||
|
["Landslide"] = true,
|
||||||
|
["Lethtendris"] = true,
|
||||||
|
["Lord Alexei Barov"] = true,
|
||||||
|
["Lord Incendius"] = true,
|
||||||
|
["Lord Vyletongue"] = true,
|
||||||
|
["Lorekeeper Polkelt"] = true,
|
||||||
|
["Loro"] = true,
|
||||||
|
["Magister Kalendris"] = true,
|
||||||
|
["Magistrate Barthilas"] = true,
|
||||||
|
["Magmus"] = true,
|
||||||
|
["Maleki the Pallid"] = true,
|
||||||
|
["Marduk Blackpool"] = true,
|
||||||
|
["Meshlok the Harvester"] = true,
|
||||||
|
["Mijan"] = true,
|
||||||
|
["Morphaz"] = true,
|
||||||
|
["Mother Smolderweb"] = true,
|
||||||
|
["Nerub'enkan"] = true,
|
||||||
|
["Noxxion"] = true,
|
||||||
|
["Ogom the Wretched"] = true,
|
||||||
|
["Overlord Wyrmthalak"] = true,
|
||||||
|
["Phalanx"] = true,
|
||||||
|
["Plugger Spazzring"] = true,
|
||||||
|
["Postmaster Malown"] = true,
|
||||||
|
["Princess Moira Bronzebeard"] = true,
|
||||||
|
["Princess Theradras"] = true,
|
||||||
|
["Prince Tortheldrin"] = true,
|
||||||
|
["Pusillin"] = true,
|
||||||
|
["Pyroguard Emberseer"] = true,
|
||||||
|
["Ramstein the Gorger"] = true,
|
||||||
|
["Ras Frostwhisper"] = true,
|
||||||
|
["Rattlegore"] = true,
|
||||||
|
["Razorlash"] = true,
|
||||||
|
["Warchief Rend Blackhand"] = true,
|
||||||
|
["Ribbly Screwspigot"] = true,
|
||||||
|
["Rotgrip"] = true,
|
||||||
|
["Seeth'rel"] = true,
|
||||||
|
["Shade of Eranikus"] = true,
|
||||||
|
["Shadow Hunter Vosh'gajin"] = true,
|
||||||
|
["Solakar Flamewreath"] = true,
|
||||||
|
["Stomper Kreeg"] = true,
|
||||||
|
["Tendris Warpwood"] = true,
|
||||||
|
["The Beast"] = true,
|
||||||
|
["The Ravenian"] = true,
|
||||||
|
["Timmy the Cruel"] = true,
|
||||||
|
["Tinkerer Gizlock"] = true,
|
||||||
|
["Tsu'zee"] = true,
|
||||||
|
["Vectus"] = true,
|
||||||
|
["Vile'rel"] = true,
|
||||||
|
["War Master Voone"] = true,
|
||||||
|
["Weaver"] = true,
|
||||||
|
["Zevrim Thornhoof"] = true,
|
||||||
|
["Zolo"] = true,
|
||||||
|
["Zul'Lor"] = true,
|
||||||
|
|
||||||
|
-- From Mendeleev
|
||||||
|
["Cho'Rush the Observer"] = true,
|
||||||
|
["Lord Hel'nurath"] = true,
|
||||||
|
["Pimgib"] = true,
|
||||||
|
["Knot Thimblejack's Cache"] = true,
|
||||||
|
["Cannonmaster Willey"] = true,
|
||||||
|
["Emperor Dagran Thaurissian"] = true,
|
||||||
|
["Archmage Arugal"] = true,
|
||||||
|
["Archmage Arugal's Voidwalker"] = true,
|
||||||
|
["Baron Silverlaine"] = true,
|
||||||
|
["Commander Springvale"] = true,
|
||||||
|
["Deathsworn Captain"] = true,
|
||||||
|
["Fenrus the Devourer"] = true,
|
||||||
|
["Odo the Blindwatcher"] = true,
|
||||||
|
["Razorclaw the Butcher"] = true,
|
||||||
|
["Wolf Master Nandos"] = true,
|
||||||
|
["Rend Blackhand"] = true,
|
||||||
|
["Kurinnaxx"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
BabbleBoss = {}
|
||||||
|
function BabbleBoss:Contains(name)
|
||||||
|
return bosses[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.BabbleBoss = BabbleBoss
|
||||||
|
end
|
||||||
@@ -0,0 +1,631 @@
|
|||||||
|
--[[
|
||||||
|
Name: Babble-Boss-2.2
|
||||||
|
Revision: $Rev: 17545 $
|
||||||
|
Author(s): ckknight (ckknight@gmail.com)
|
||||||
|
Website: http://ckknight.wowinterface.com/
|
||||||
|
Documentation: http://wiki.wowace.com/index.php/Babble-Boss-2.2
|
||||||
|
SVN: http://svn.wowace.com/root/trunk/Babble-2.2/Babble-Boss-2.2
|
||||||
|
Description: A library to provide localizations for bosses.
|
||||||
|
Dependencies: AceLibrary, AceLocale-2.2
|
||||||
|
|
||||||
|
Rewritten a little and added some "bosses" by Shino
|
||||||
|
]]
|
||||||
|
|
||||||
|
if (GetLocale()=="koKR") then
|
||||||
|
|
||||||
|
local bosses = {
|
||||||
|
["아누비사스 문지기"] = true,
|
||||||
|
["전투감시병 살투라"] = true,
|
||||||
|
["쑨"] = true,
|
||||||
|
["제왕 베클로어"] = true,
|
||||||
|
["제왕 베크닐라쉬"] = true,
|
||||||
|
["쑨의 눈"] = true,
|
||||||
|
["불굴의 판크리스"] = true,
|
||||||
|
["군주 크리"] = true,
|
||||||
|
["아우로"] = true,
|
||||||
|
["공주 후후란"] = true,
|
||||||
|
["공주 야우즈"] = true,
|
||||||
|
["벌레 무리"] = true,
|
||||||
|
["예언자 스케람"] = true,
|
||||||
|
["쌍둥이 제왕"] = true,
|
||||||
|
["벰"] = true,
|
||||||
|
["비시디우스"] = true,
|
||||||
|
|
||||||
|
["총독 말라다르"] = true,
|
||||||
|
["죽음의 감시인 쉴라크"] = true,
|
||||||
|
["연합왕자 샤파르"] = true,
|
||||||
|
["팬더모니우스"] = true,
|
||||||
|
["타바로크"] = true,
|
||||||
|
["사자 지옥아귀"] = true,
|
||||||
|
["선동자 검은심장"] = true,
|
||||||
|
["단장 보르필"] = true,
|
||||||
|
["울림"] = true,
|
||||||
|
["안주"] = true, --summoned boss
|
||||||
|
["흑마술사 시스"] = true,
|
||||||
|
["갈퀴대왕 이키스"] = true,
|
||||||
|
|
||||||
|
["아쿠마이"] = true,
|
||||||
|
["남작 아쿠아니스"] = true,
|
||||||
|
["겔리하스트"] = true,
|
||||||
|
["가무라 "] = true,
|
||||||
|
["여왕 사레베스"] = true,
|
||||||
|
["늙은 세라키스"] = true,
|
||||||
|
["황혼의 군주 켈리스"] = true,
|
||||||
|
|
||||||
|
["사자 화염채찍"] = true,
|
||||||
|
["격노의 문지기"] = true,
|
||||||
|
["아눕쉬아"] = true,
|
||||||
|
["벨가르"] = true,
|
||||||
|
["Chest of The Seven"] = true,
|
||||||
|
["운명의 문지기"] = true,
|
||||||
|
["최면의 문지기"] = true,
|
||||||
|
["제왕 다그란 타우릿산"] = true,
|
||||||
|
["적출자"] = true,
|
||||||
|
["파이너스 다크바이어"] = true,
|
||||||
|
["사령관 앵거포지"] = true,
|
||||||
|
["그늘의 문지기"] = true,
|
||||||
|
["골렘군주 아젤마크"] = true,
|
||||||
|
["광신자 고로쉬"] = true, --check
|
||||||
|
["그리즐"] = true,
|
||||||
|
["증오의 문지기"] = true,
|
||||||
|
["왕거미 헤드룸"] = true,
|
||||||
|
["대심문관 게르스탄"] = true,
|
||||||
|
["타우릿산의 대여사제"] = true,
|
||||||
|
["사냥개조련사 그렙마르"] = true,
|
||||||
|
["헐레이 블랙브레스"] = true,
|
||||||
|
["군주 인센디우스"] = true,
|
||||||
|
["불의군주 록코르"] = true,
|
||||||
|
["마그무스"] = true,
|
||||||
|
["파괴자 오크토르"] = true,
|
||||||
|
["무적의 판저"] = true,
|
||||||
|
["팔란스"] = true,
|
||||||
|
["플러거스파즈링"] = true,
|
||||||
|
["공주 모이라 브론즈비어드"] = true,
|
||||||
|
["화염술사 로어그레인"] = true,
|
||||||
|
["리블리 스크류스피곳"] = true,
|
||||||
|
["불안의 문지기"] = true,
|
||||||
|
["The Seven Dwarves"] = true,
|
||||||
|
["베레크"] = true,
|
||||||
|
["타락의 문지기"] = true,
|
||||||
|
["문지기 스틸기스"] = true,
|
||||||
|
|
||||||
|
["반노크 그림액스"] = true,
|
||||||
|
["불타는 지옥수호병"] = true,
|
||||||
|
["수정 맹독 거미"] = true,
|
||||||
|
["고크 배시구드"] = true,
|
||||||
|
["흉포한 기즈룰"] = true,
|
||||||
|
["할리콘"] = true,
|
||||||
|
["대군주 오모크"] = true,
|
||||||
|
["모르 그레이후프"] = true,
|
||||||
|
["여왕 불그물거미"] = true,
|
||||||
|
["대군주 윔타라크"] = true,
|
||||||
|
["병참장교 지그리스"] = true,
|
||||||
|
["어둠사냥꾼 보쉬가진"] = true,
|
||||||
|
["뾰족바위일족 전투대장"] = true,
|
||||||
|
["뾰족바위일족 학살자"] = true,
|
||||||
|
["뾰족바위일족 마법사장"] = true,
|
||||||
|
["우르크 둠하울"] = true,
|
||||||
|
["대장군 부네"] = true,
|
||||||
|
["사령관 드라키사스"] = true,
|
||||||
|
["고랄루크 앤빌크랙"] = true,
|
||||||
|
["기스"] = true,
|
||||||
|
["제드 룬와처"] = true,
|
||||||
|
["군주 발타라크"] = true,
|
||||||
|
["불의 수호자 엠버시어"] = true,
|
||||||
|
["화염고리 솔라카르"] = true,
|
||||||
|
["괴수"] = true,
|
||||||
|
["대족장 렌드 블랙핸드"] = true,
|
||||||
|
|
||||||
|
["용기대장 래쉬레이어"] = true,
|
||||||
|
["크로마구스"] = true,
|
||||||
|
["에본로크"] = true,
|
||||||
|
["화염아귀"] = true,
|
||||||
|
["플레임고르"] = true,
|
||||||
|
["감시자 그레토크"] = true,
|
||||||
|
["군주 빅터 네파리우스"] = true,
|
||||||
|
["네파리안"] = true,
|
||||||
|
["폭군 서슬송곳니"] = true,
|
||||||
|
["타락한 밸라스트라즈"] = true,
|
||||||
|
|
||||||
|
["머쉬고그"] = true,
|
||||||
|
["무적의 스카르"] = true,
|
||||||
|
["라자"] = true,
|
||||||
|
["칼날바람 알진"] = true,
|
||||||
|
["히드로스폰"] = true,
|
||||||
|
["이살리엔"] = true,
|
||||||
|
["레스텐드리스"] = true,
|
||||||
|
["핌기브"] = true,
|
||||||
|
["푸실린"] = true,
|
||||||
|
["제브림 쏜후프"] = true,
|
||||||
|
["대장 크롬크러쉬"] = true,
|
||||||
|
["정찰병 초루쉬"] = true,
|
||||||
|
["경비병 펜구스"] = true,
|
||||||
|
["경비병 몰다르"] = true,
|
||||||
|
["경기병 슬립킥"] = true,
|
||||||
|
["왕 고르독"] = true,
|
||||||
|
["천둥발 크리그"] = true,
|
||||||
|
["일샨나 레이븐호크"] = true,
|
||||||
|
["이몰타르"] = true,
|
||||||
|
["군주 헬누라스"] = true,
|
||||||
|
["마법사 칼렌드리스"] = true,
|
||||||
|
["왕자 토르텔드린"] = true,
|
||||||
|
["굽이나무 텐드리스"] = true,
|
||||||
|
["츄지"] = true,
|
||||||
|
|
||||||
|
["고철 압축기 9-60"] = true,
|
||||||
|
["검은무쇠단 사절"] = true,
|
||||||
|
["기계화 문지기 6000"] = true,
|
||||||
|
["그루비스 "] = true,
|
||||||
|
["멕기니어 텔마플러그"] = true,
|
||||||
|
["첨단로봇"] = true,
|
||||||
|
["방사성 폐기물"] = true,
|
||||||
|
|
||||||
|
["저주받은 셀레브라스"] = true,
|
||||||
|
["겔크"] = true,
|
||||||
|
["콜크"] = true,
|
||||||
|
["산사태"] = true,
|
||||||
|
["군주 바일텅"] = true,
|
||||||
|
["마그라"] = true,
|
||||||
|
["마라우도스"] = true,
|
||||||
|
["정원사 메슬로크"] = true,
|
||||||
|
["녹시온"] = true,
|
||||||
|
["공주 테라드라스"] = true,
|
||||||
|
["칼날채찍"] = true,
|
||||||
|
["썩은 아귀"] = true,
|
||||||
|
["땜장이 기즐록"] = true,
|
||||||
|
["벵"] = true,
|
||||||
|
|
||||||
|
["남작 게돈"] = true,
|
||||||
|
["Cache of the Firelord"] = true,
|
||||||
|
["가르"] = true,
|
||||||
|
["게헨나스"] = true,
|
||||||
|
["초열의 골레마그"] = true,
|
||||||
|
["루시프론"] = true,
|
||||||
|
["마그마다르"] = true,
|
||||||
|
["청지기 이그젝큐투스"] = true,
|
||||||
|
["라그나로스"] = true,
|
||||||
|
["샤즈라"] = true,
|
||||||
|
["설퍼론 사자"] = true,
|
||||||
|
|
||||||
|
["아눕레칸"] = true,
|
||||||
|
["죽음의 기사 수습생"] = true,
|
||||||
|
["퓨진"] = true,
|
||||||
|
["Four Horsemen Chest"] = true,
|
||||||
|
["글루스"] = true,
|
||||||
|
["영혼 착취자 고딕"] = true,
|
||||||
|
["귀부인 팰리나"] = true,
|
||||||
|
["그라불루스"] = true,
|
||||||
|
["부정의 헤이건"] = true,
|
||||||
|
["대영주 모그레인"] = true,
|
||||||
|
["훈련교관 라주비어스"] = true,
|
||||||
|
["켈투자드"] = true,
|
||||||
|
["여군주 블라미우스"] = true,
|
||||||
|
["로데브"] = true,
|
||||||
|
["맥스나"] = true,
|
||||||
|
["역병술사 노스"] = true,
|
||||||
|
["패치워크"] = true,
|
||||||
|
["사피론"] = true,
|
||||||
|
["젤리에크 경"] = true,
|
||||||
|
["스탈라그"] = true,
|
||||||
|
["타디우스"] = true,
|
||||||
|
["영주 코스아즈"] = true,
|
||||||
|
["4인의 기병대"] = true,
|
||||||
|
|
||||||
|
["오닉시아"] = true,
|
||||||
|
|
||||||
|
["바잘란"] = true,
|
||||||
|
["기원사 제로쉬"] = true,
|
||||||
|
["마우르 그림토템"] = true,
|
||||||
|
["욕망의 타라가만"] = true,
|
||||||
|
|
||||||
|
["혹한의 암네나르"] = true,
|
||||||
|
["게걸먹보"] = true,
|
||||||
|
["불꽃눈 모드레쉬"] = true,
|
||||||
|
["썩어가는 역병아귀"] = true,
|
||||||
|
["너덜주둥이"] = true,
|
||||||
|
["투텐카쉬"] = true,
|
||||||
|
|
||||||
|
["흉포한 아가테로스"] = true,
|
||||||
|
["장님 사냥꾼"] = true,
|
||||||
|
["서슬깃 차를가"] = true,
|
||||||
|
["죽음의 예언자 잘그바"] = true,
|
||||||
|
["대지술사 함가르"] = true,
|
||||||
|
["대군주 램터스크"] = true,
|
||||||
|
|
||||||
|
["아누비사스 감시자"] = true,
|
||||||
|
["사냥꾼 아야미스"] = true,
|
||||||
|
["먹보 부루"] = true,
|
||||||
|
["장군 라작스"] = true,
|
||||||
|
["쿠린낙스"] = true,
|
||||||
|
["사령관 안도로브"] = true,
|
||||||
|
["모암"] = true,
|
||||||
|
["무적의 오시리안"] = true,
|
||||||
|
|
||||||
|
["헤로드"] = true,
|
||||||
|
["종교재판관 페어뱅크스"] = true,
|
||||||
|
["종교재판관 화이트메인"] = true,
|
||||||
|
["붉은십자군 사령관 모그레인"] = true,
|
||||||
|
["잠들지 않는 아즈시르"] = true,
|
||||||
|
["혈법사 탈노스"] = true,
|
||||||
|
["타락한 용사"] = true,
|
||||||
|
["심문관 비샤스"] = true,
|
||||||
|
["무쇠해골"] = true,
|
||||||
|
["신비술사 도안"] = true,
|
||||||
|
["사냥개 조련사 록시"] = true,
|
||||||
|
|
||||||
|
["키르토노스의 혈지기"] = true,
|
||||||
|
["암흑스승 간틀링"] = true,
|
||||||
|
["죽음의 기사 다크리버"] = true,
|
||||||
|
["학자 테올린 크라스티노브"] = true,
|
||||||
|
["조교 말리시아"] = true,
|
||||||
|
["잔다이스 바로브"] = true,
|
||||||
|
["사자 키르토노스"] = true,
|
||||||
|
["코르모크"] = true,
|
||||||
|
["여군주 일루시아 바로브"] = true,
|
||||||
|
["군주 알렉세이 바로브"] = true,
|
||||||
|
["현자 폴켈트"] = true,
|
||||||
|
["마르두크 블랙풀"] = true,
|
||||||
|
["라스 프로스트위스퍼"] = true,
|
||||||
|
["들창어금니"] = true,
|
||||||
|
["라베니안"] = true,
|
||||||
|
["벡투스"] = true,
|
||||||
|
|
||||||
|
["대마법사 아루갈"] = true,
|
||||||
|
["아루갈의 보이드워커"] = true,
|
||||||
|
["남작 실버레인"] = true,
|
||||||
|
["사령관 스프링베일"] = true,
|
||||||
|
["죽음의 경비대장"] = true, -- check
|
||||||
|
["파멸의 펜루스"] = true,
|
||||||
|
["눈먼감시자 오도"] = true,
|
||||||
|
["도살자 칼날발톱"] = true,
|
||||||
|
["늑대왕 난도스"] = true,
|
||||||
|
|
||||||
|
["기록관 갈포드"] = true,
|
||||||
|
["발나자르"] = true,
|
||||||
|
["남작 리븐데어"] = true,
|
||||||
|
["남작부인 아나스타리"] = true,
|
||||||
|
["검은호위대 검제작자"] = true,
|
||||||
|
["포병대장 윌리"] = true,
|
||||||
|
["진홍십자군 대장장이"] = true,
|
||||||
|
["프라스 샤비"] = true,
|
||||||
|
["하스싱어 포레스턴"] = true,
|
||||||
|
["집정관 바실라스"] = true,
|
||||||
|
["냉혈한 말레키"] = true,
|
||||||
|
["네룹엔칸"] = true,
|
||||||
|
["우체국장 말로운"] = true,
|
||||||
|
["먹보 람스타인"] = true,
|
||||||
|
["스컬"] = true,
|
||||||
|
["뾰족바위"] = true,
|
||||||
|
["용서받지 못한 자"] = true,
|
||||||
|
["잔혹한 티미"] = true,
|
||||||
|
|
||||||
|
["세뇌당한 귀족"] = true,
|
||||||
|
["선장 그린스킨"] = true,
|
||||||
|
["쿠키"] = true,
|
||||||
|
["에드윈 밴클리프"] = true,
|
||||||
|
["현장감독 시슬네틀"] = true,
|
||||||
|
["길니드"] = true,
|
||||||
|
["마리사 두페이지"] = true,
|
||||||
|
["광부 존슨"] = true,
|
||||||
|
["미스터 스마이트"] = true,
|
||||||
|
["라크조르"] = true,
|
||||||
|
["스니드"] = true,
|
||||||
|
["스니드의 벌목기"] = true,
|
||||||
|
|
||||||
|
["바질 스레드"] = true,
|
||||||
|
["무쇠주먹 브루갈"] = true,
|
||||||
|
["덱스트렌 워드"] = true,
|
||||||
|
["햄혹"] = true,
|
||||||
|
["캄 딥퓨리"] = true,
|
||||||
|
["흉악범 타고르"] = true,
|
||||||
|
|
||||||
|
["아탈알라리온"] = true,
|
||||||
|
["학카르의 화신"] = true,
|
||||||
|
["드림사이드"] = true,
|
||||||
|
["게이셔"] = true,
|
||||||
|
["하자스"] = true,
|
||||||
|
["후쿠"] = true,
|
||||||
|
["제이드"] = true,
|
||||||
|
["예언자 잠말란"] = true,
|
||||||
|
["타락한 카즈카즈"] = true,
|
||||||
|
["로로"] = true,
|
||||||
|
["마이잔"] = true,
|
||||||
|
["몰파즈"] = true,
|
||||||
|
["비운의 오그옴"] = true,
|
||||||
|
["에라니쿠스의 사령"] = true,
|
||||||
|
["식인트롤 베이쟉"] = true,
|
||||||
|
["위버"] = true,
|
||||||
|
["젝키스"] = true,
|
||||||
|
["졸로"] = true,
|
||||||
|
["줄로"] = true,
|
||||||
|
|
||||||
|
["고대 바위 문지기"] = true,
|
||||||
|
["아카에다스"] = true,
|
||||||
|
["밸로그"] = true,
|
||||||
|
["발굴단장 쇼벨플랜지"] = true,
|
||||||
|
["갈간 파이어해머"] = true,
|
||||||
|
["그림로크"] = true,
|
||||||
|
["아이로나야"] = true,
|
||||||
|
["흑요석 파수꾼"] = true,
|
||||||
|
["레벨로쉬"] = true,
|
||||||
|
|
||||||
|
["보안"] = true,
|
||||||
|
["돌연변이 요정용"] = true,
|
||||||
|
["크레쉬"] = true,
|
||||||
|
["여군주 아나콘드라"] = true,
|
||||||
|
["군주 코브란"] = true,
|
||||||
|
["군주 피타스"] = true,
|
||||||
|
["군주 서펜디스"] = true,
|
||||||
|
["광기의 매글리시"] = true,
|
||||||
|
["걸신들린 무타누스"] = true,
|
||||||
|
["스컴"] = true,
|
||||||
|
["채찍꼬리 트리고어"] = true,
|
||||||
|
["영생의 베르단"] = true,
|
||||||
|
|
||||||
|
["아발란치온"] = true,
|
||||||
|
["아주어고스"] = true,
|
||||||
|
["남작 차르"] = true,
|
||||||
|
["남작 카줌"] = true,
|
||||||
|
["파멸의 군주 카자크"] = true,
|
||||||
|
["파멸의 절단기"] = true,
|
||||||
|
["에메리스"] = true,
|
||||||
|
["대장군 휠락시스"] = true, -- check
|
||||||
|
["레손"] = true,
|
||||||
|
["군주 스퀄"] = true,
|
||||||
|
["왕자 스칼레녹스"] = true,
|
||||||
|
["공주 템페스트리아"] = true,
|
||||||
|
["타에라"] = true,
|
||||||
|
["칼날바람"] = true,
|
||||||
|
["이손드레"] = true,
|
||||||
|
|
||||||
|
["안투술"] = true,
|
||||||
|
["족장 우코르즈 샌드스칼프"] = true,
|
||||||
|
["더스트레이스"] = true,
|
||||||
|
["가즈릴라"] = true,
|
||||||
|
["유체술사 벨라타"] = true,
|
||||||
|
["무르타 그림구트"] = true,
|
||||||
|
["네크룸 거트츄어"] = true,
|
||||||
|
["오로 아이가우지"] = true,
|
||||||
|
["루즐루"] = true,
|
||||||
|
["Sandarr Dunereaver"] = true,
|
||||||
|
["성난모래부족 사형집행인"] = true,
|
||||||
|
["하사관 블라이"] = true,
|
||||||
|
["어둠의사제 세즈지즈"] = true,
|
||||||
|
["순교자 데카"] = true,
|
||||||
|
["의술사 줌라"] = true,
|
||||||
|
["제릴리스"] = true,
|
||||||
|
["줄파락 죽음의 영웅"] = true,
|
||||||
|
|
||||||
|
["혈군주 만도키르"] = true,
|
||||||
|
["가즈란카"] = true,
|
||||||
|
["그리렉"] = true,
|
||||||
|
["학카르"] = true,
|
||||||
|
["하자라"] = true,
|
||||||
|
["대사제 데칼"] = true,
|
||||||
|
["대사제 베녹시스"] = true,
|
||||||
|
["대여사제 알로크"] = true,
|
||||||
|
["대여사제 제클릭"] = true,
|
||||||
|
["대여사제 말리"] = true,
|
||||||
|
["주술사 진도"] = true,
|
||||||
|
["레나타키"] = true,
|
||||||
|
["우슬레이"] = true,
|
||||||
|
|
||||||
|
-- Costum bosses
|
||||||
|
["Firesworn"] = true,
|
||||||
|
|
||||||
|
["Avalanchion"] = true,
|
||||||
|
["The Windreaver"] = true,
|
||||||
|
["Baron Charr"] = true,
|
||||||
|
["Princess Tempestria"] = true,
|
||||||
|
["Grethok the Controller"] = true,
|
||||||
|
["Patchwerk"] = true,
|
||||||
|
["Grobbulus"] = true,
|
||||||
|
["Gluth"] = true,
|
||||||
|
["Feugen"] = true,
|
||||||
|
["Stalagg"] = true,
|
||||||
|
["Thaddius"] = true,
|
||||||
|
["Anub'Rekhan"] = true,
|
||||||
|
["Grand Widow Faerlina"] = true,
|
||||||
|
["Maexxna"] = true,
|
||||||
|
["Instructor Razuvious"] = true,
|
||||||
|
--["Deathknight Understudy"] = true,
|
||||||
|
["Gothik the Harvester"] = true,
|
||||||
|
["Highlord Mograine"] = true,
|
||||||
|
["Thane Korth'azz"] = true,
|
||||||
|
["Lady Blaumeux"] = true,
|
||||||
|
["Sir Zeliek"] = true,
|
||||||
|
["The Four Horsemen"] = true,
|
||||||
|
["Noth the Plaguebringer"] = true,
|
||||||
|
["Heigan the Unclean"] = true,
|
||||||
|
["Loatheb"] = true,
|
||||||
|
["Sapphiron"] = true,
|
||||||
|
["Kel'Thuzad"] = true,
|
||||||
|
["Lord Victor Nefarius"] = true,
|
||||||
|
["Nefarian"] = true,
|
||||||
|
["Vaelastrasz the Corrupt"] = true,
|
||||||
|
["Razorgore the Untamed"] = true,
|
||||||
|
["Broodlord Lashlayer"] = true,
|
||||||
|
["Chromaggus"] = true,
|
||||||
|
["Ebonroc"] = true,
|
||||||
|
["Firemaw"] = true,
|
||||||
|
["Flamegor"] = true,
|
||||||
|
["Majordomo Executus"] = true,
|
||||||
|
["Ragnaros"] = true,
|
||||||
|
["Baron Geddon"] = true,
|
||||||
|
["Golemagg the Incinerator"] = true,
|
||||||
|
["Garr"] = true,
|
||||||
|
["Sulfuron Harbinger"] = true,
|
||||||
|
["Shazzrah"] = true,
|
||||||
|
["Lucifron"] = true,
|
||||||
|
["Gehennas"] = true,
|
||||||
|
["Magmadar"] = true,
|
||||||
|
["Onyxia"] = true,
|
||||||
|
["Azuregos"] = true,
|
||||||
|
["Lord Kazzak"] = true,
|
||||||
|
["Ysondre"] = true,
|
||||||
|
["Emeriss"] = true,
|
||||||
|
["Taerar"] = true,
|
||||||
|
["Lethon"] = true,
|
||||||
|
["High Priestess Jeklik"] = true,
|
||||||
|
["High Priest Venoxis"] = true,
|
||||||
|
["High Priest Thekal"] = true,
|
||||||
|
["High Priestess Arlokk"] = true,
|
||||||
|
["High Priestess Mar'li"] = true,
|
||||||
|
["Jin'do the Hexxer"] = true,
|
||||||
|
["Bloodlord Mandokir"] = true,
|
||||||
|
["Gahz'ranka"] = true,
|
||||||
|
["Gri'lek"] = true,
|
||||||
|
["Hazza'rah"] = true,
|
||||||
|
["Renataki"] = true,
|
||||||
|
["Wushoolay"] = true,
|
||||||
|
["Hakkar"] = true,
|
||||||
|
["Ayamiss the Hunter"] = true,
|
||||||
|
["Buru the Gorger"] = true,
|
||||||
|
["General Rajaxx"] = true,
|
||||||
|
["Lieutenant General Andorov"] = true,
|
||||||
|
["Moam"] = true,
|
||||||
|
["Ossirian the Unscarred"] = true,
|
||||||
|
["Lord Kri"] = true,
|
||||||
|
["Princess Yauj"] = true,
|
||||||
|
["Vem"] = true,
|
||||||
|
["The Bug Family"] = true,
|
||||||
|
["Eye of C'Thun"] = true,
|
||||||
|
["C'Thun"] = true,
|
||||||
|
["Fankriss the Unyielding"] = true,
|
||||||
|
["Princess Huhuran"] = true,
|
||||||
|
["Ouro"] = true,
|
||||||
|
["Battleguard Sartura"] = true,
|
||||||
|
["The Prophet Skeram"] = true,
|
||||||
|
["Emperor Vek'lor"] = true,
|
||||||
|
["Emperor Vek'nilash"] = true,
|
||||||
|
["The Twin Emperors"] = true,
|
||||||
|
["Viscidus"] = true,
|
||||||
|
["Alzzin the Wildshaper"] = true,
|
||||||
|
["Ambassador Flamelash"] = true,
|
||||||
|
["Anger'rel"] = true,
|
||||||
|
["Archivist Galford"] = true,
|
||||||
|
["Atal'alarion"] = true,
|
||||||
|
["Avatar of Hakkar"] = true,
|
||||||
|
["Bael'Gar"] = true,
|
||||||
|
["Balnazzar"] = true,
|
||||||
|
["Baroness Anastari"] = true,
|
||||||
|
["Baron Rivendare"] = true,
|
||||||
|
["Cannon Master Willey"] = true,
|
||||||
|
["Captain Kromcrush"] = true,
|
||||||
|
["Celebras the Cursed"] = true,
|
||||||
|
["Crystal Fang"] = true,
|
||||||
|
["Darkmaster Gandling"] = true,
|
||||||
|
["Doctor Theolen Krastinov"] = true,
|
||||||
|
["Doom'rel"] = true,
|
||||||
|
["Dope'rel"] = true,
|
||||||
|
["Dreamscythe"] = true,
|
||||||
|
["Emperor Dagran Thaurissan"] = true,
|
||||||
|
["Fineous Darkvire"] = true,
|
||||||
|
["Gasher"] = true,
|
||||||
|
["General Angerforge"] = true,
|
||||||
|
["General Drakkisath"] = true,
|
||||||
|
["Gloom'rel"] = true,
|
||||||
|
["Golem Lord Argelmach"] = true,
|
||||||
|
["Goraluk Anvilcrack"] = true,
|
||||||
|
["Guard Fengus"] = true,
|
||||||
|
["Guard Mol'dar"] = true,
|
||||||
|
["Guard Slip'kik"] = true,
|
||||||
|
["Gyth"] = true,
|
||||||
|
["Halycon"] = true,
|
||||||
|
["Hate'rel"] = true,
|
||||||
|
["Hazzas"] = true,
|
||||||
|
["Hearthsinger Forresten"] = true,
|
||||||
|
["High Interrogator Gerstahn"] = true,
|
||||||
|
["Highlord Omokk"] = true,
|
||||||
|
["Hukku"] = true,
|
||||||
|
["Hurley Blackbreath"] = true,
|
||||||
|
["Hydrospawn"] = true,
|
||||||
|
["Illyanna Ravenoak"] = true,
|
||||||
|
["Immol'thar"] = true,
|
||||||
|
["Instructor Malicia"] = true,
|
||||||
|
["Jammal'an the Prophet"] = true,
|
||||||
|
["Jandice Barov"] = true,
|
||||||
|
["King Gordok"] = true,
|
||||||
|
["Kirtonos the Herald"] = true,
|
||||||
|
["Lady Illucia Barov"] = true,
|
||||||
|
["Landslide"] = true,
|
||||||
|
["Lethtendris"] = true,
|
||||||
|
["Lord Alexei Barov"] = true,
|
||||||
|
["Lord Incendius"] = true,
|
||||||
|
["Lord Vyletongue"] = true,
|
||||||
|
["Lorekeeper Polkelt"] = true,
|
||||||
|
["Loro"] = true,
|
||||||
|
["Magister Kalendris"] = true,
|
||||||
|
["Magistrate Barthilas"] = true,
|
||||||
|
["Magmus"] = true,
|
||||||
|
["Maleki the Pallid"] = true,
|
||||||
|
["Marduk Blackpool"] = true,
|
||||||
|
["Meshlok the Harvester"] = true,
|
||||||
|
["Mijan"] = true,
|
||||||
|
["Morphaz"] = true,
|
||||||
|
["Mother Smolderweb"] = true,
|
||||||
|
["Nerub'enkan"] = true,
|
||||||
|
["Noxxion"] = true,
|
||||||
|
["Ogom the Wretched"] = true,
|
||||||
|
["Overlord Wyrmthalak"] = true,
|
||||||
|
["Phalanx"] = true,
|
||||||
|
["Plugger Spazzring"] = true,
|
||||||
|
["Postmaster Malown"] = true,
|
||||||
|
["Princess Moira Bronzebeard"] = true,
|
||||||
|
["Princess Theradras"] = true,
|
||||||
|
["Prince Tortheldrin"] = true,
|
||||||
|
["Pusillin"] = true,
|
||||||
|
["Pyroguard Emberseer"] = true,
|
||||||
|
["Ramstein the Gorger"] = true,
|
||||||
|
["Ras Frostwhisper"] = true,
|
||||||
|
["Rattlegore"] = true,
|
||||||
|
["Razorlash"] = true,
|
||||||
|
["Warchief Rend Blackhand"] = true,
|
||||||
|
["Ribbly Screwspigot"] = true,
|
||||||
|
["Rotgrip"] = true,
|
||||||
|
["Seeth'rel"] = true,
|
||||||
|
["Shade of Eranikus"] = true,
|
||||||
|
["Shadow Hunter Vosh'gajin"] = true,
|
||||||
|
["Solakar Flamewreath"] = true,
|
||||||
|
["Stomper Kreeg"] = true,
|
||||||
|
["Tendris Warpwood"] = true,
|
||||||
|
["The Beast"] = true,
|
||||||
|
["The Ravenian"] = true,
|
||||||
|
["Timmy the Cruel"] = true,
|
||||||
|
["Tinkerer Gizlock"] = true,
|
||||||
|
["Tsu'zee"] = true,
|
||||||
|
["Vectus"] = true,
|
||||||
|
["Vile'rel"] = true,
|
||||||
|
["War Master Voone"] = true,
|
||||||
|
["Weaver"] = true,
|
||||||
|
["Zevrim Thornhoof"] = true,
|
||||||
|
["Zolo"] = true,
|
||||||
|
["Zul'Lor"] = true,
|
||||||
|
|
||||||
|
-- From Mendeleev
|
||||||
|
["Cho'Rush the Observer"] = true,
|
||||||
|
["Lord Hel'nurath"] = true,
|
||||||
|
["Pimgib"] = true,
|
||||||
|
["Knot Thimblejack's Cache"] = true,
|
||||||
|
["Cannonmaster Willey"] = true,
|
||||||
|
["Emperor Dagran Thaurissian"] = true,
|
||||||
|
["Archmage Arugal"] = true,
|
||||||
|
["Archmage Arugal's Voidwalker"] = true,
|
||||||
|
["Baron Silverlaine"] = true,
|
||||||
|
["Commander Springvale"] = true,
|
||||||
|
["Deathsworn Captain"] = true,
|
||||||
|
["Fenrus the Devourer"] = true,
|
||||||
|
["Odo the Blindwatcher"] = true,
|
||||||
|
["Razorclaw the Butcher"] = true,
|
||||||
|
["Wolf Master Nandos"] = true,
|
||||||
|
["Rend Blackhand"] = true,
|
||||||
|
["Kurinnaxx"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
BabbleBoss = {}
|
||||||
|
function BabbleBoss:Contains(name)
|
||||||
|
return bosses[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
DPSMate.BabbleBoss = BabbleBoss
|
||||||
|
end
|
||||||