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
|
||||