vanilla-wow-addons – Rev 1
?pathlinks?
--[[
Recap 3.32 - Gello
An AddOn for WoW to track and summarize all damage done around the user.
]]
Recap_Version = 3.32
--[[ local tables ]]
-- colors for the gauges
local gaugecolor = { ["DmgIn"] = { r=.66,g=.25,b=.25 }, ["DmgOut"] = { r=.25,g=.66,b=.35 }, ["Heal"] = { r=.25,g=.5,b=.85 },
["Time"] = { r=.75, g=.75, b=.75 }, ["Kills"] = { r=.75, g=.75, b=.75 }, ["MaxHit"] = { r=.75, g=.75, b=.75 },
["DPS"] = { r=.25, g=.66, b=.35 }, ["Over"] = { r=.25, g=.5, b=.85 } }
-- keys for (det)ails and (inc)oming data sets
local detkey = { ["HitsDmg"]="d", ["Hits"]="n", ["HitsMax"]="x", ["CritsDmg"]="D", ["Crits"]="N",
["CritsMax"]="X", ["CritsEvents"]="e", ["Missed"]="m", ["TicksDmg"]="t", ["TicksMax"]="T" }
local inckey = { ["MeleeDamage"]="a", ["MeleeMax"]="b", ["MeleeHits"]="c", ["MeleeCrits"]="d", ["MeleeMissed"]="e",
["MeleeDodged"]="f", ["MeleeParried"]="g", ["MeleeBlocked"]="h", ["NonMeleeDamage"]="i",
["NonMeleeMax"]="j", ["NonMeleeHits"]="k", ["NonMeleeCrits"]="l", ["NonMeleeMissed"]="m" }
-- .Opt.x and its buttons
local recapbuttons = { ["Minimized"] = "RecapMinimizeButton", ["Pinned"] = "RecapPinButton",
["Paused"] = "RecapPauseButton", ["SelfView"] = "RecapSelfViewButton" }
--[[ Saved Variables ]]
recap = {} -- options and current data
recap_set = {} -- fight data sets
--[[ Callback functions ]]
function Recap_OnLoad()
this:RegisterEvent("VARIABLES_LOADED")
this:RegisterEvent("PLAYER_ENTERING_WORLD")
this:RegisterEvent("UNIT_NAME_UPDATE")
-- function overrides: recap.NormalExit is true on a successful /quit or /logout
Recap_OldQuit = Quit
Recap_OldLogout = Logout
Recap_OldCancelLogout = CancelLogout
Quit = function() recap.NormalExit = true; Recap_OldQuit(); end
Logout = function() recap.NormalExit = true; Recap_OldLogout(); end
CancelLogout = function() recap.NormalExit = nil; Recap_OldCancelLogout(); end
end
function Recap_OnEvent()
if event=="VARIABLES_LOADED" then
SlashCmdList["RecapCOMMAND"] = Recap_SlashHandler
SLASH_RecapCOMMAND1 = "/Recap"
elseif event=="PLAYER_ENTERING_WORLD" or event=="UNIT_NAME_UPDATE" then
Recap_Initialize()
elseif event=="PLAYER_REGEN_DISABLED" then
if recap.Opt.LimitFights.value then
Recap_StartFight()
end
elseif event=="PLAYER_REGEN_ENABLED" then
Recap_EndFight()
elseif event=="PARTY_MEMBERS_CHANGED" or event=="RAID_ROSTER_UPDATE" then
Recap_MakeFriends()
elseif event=="CHAT_MSG_CHANNEL_NOTICE" then
if string.find(arg4,"recaplog"..string.lower(UnitName("player"))) and arg1=="YOU_JOINED" then
RecapOpt_WriteLogLabel:SetText(RECAP_CHANNEL_JOINED_WRITING)
ChatFrameLog(1)
RecapFrame:UnregisterEvent("CHAT_MSG_CHANNEL_NOTICE")
RecapFrame:RegisterEvent("CHAT_MSG_CHANNEL")
Recap_WriteLog()
end
elseif event=="CHAT_MSG_CHANNEL" then
if string.find(string.lower(arg4),"recaplog") and arg2==UnitName("player") and arg1=="EOF" then
ChatFrameLog(0)
RecapOpt_WriteLogLabel:SetText(RECAP_SAVE_TO_WOWCHATLOG_TXT)
LeaveChannelByName("recaplog"..UnitName("player"))
RecapFrame:UnregisterEvent("CHAT_MSG_CHANNEL")
DEFAULT_CHAT_FRAME:AddMessage(recap_temp.Local.LogWritten)
end
end
end
function Recap_Idle_OnUpdate(arg1)
-- timer to end idle fights if option checked
if recap_temp.IdleTimer~=-1 and recap_temp.Loaded and recap.Opt.IdleFight.value then
recap_temp.IdleTimer = recap_temp.IdleTimer + arg1
if recap_temp.IdleTimer > recap.Opt.IdleFightTimer.value then
recap_temp.IdleTimer = -1
Recap_EndFight()
end
end
-- if fighting and a plugin loaded or we're minimized, update min dps every half second
if recap_temp.Loaded and recap_temp.UpdateTimer~=-1 and recap.Opt.State.value=="Active" and
((IB_Recap_Update or TitanPanelRecap_Update) or recap.Opt.Minimized.value) then
recap_temp.UpdateTimer = recap_temp.UpdateTimer + arg1
if recap_temp.UpdateTimer>.5 then
recap_temp.UpdateTimer = 0
Recap_UpdateMinimizedDPS()
end
end
end
function Recap_OnUpdate(arg1)
-- update fade timer if option checked
if recap_temp.Loaded and recap.Opt.AutoFade.value and not recap.Opt.Minimized.value and MouseIsOver(RecapFrame) and recap_temp.FadeTimer<recap.Opt.AutoFadeTimer.value then
recap_temp.FadeTimer = 0
elseif recap_temp.Loaded and recap_temp.FadeTimer~=-1 and recap.Opt.AutoFade.value and not recap.Opt.Minimized.value then
recap_temp.FadeTimer = recap_temp.FadeTimer + arg1
if recap_temp.FadeTimer > recap.Opt.AutoFadeTimer.value then
RecapFrame:SetAlpha( max(1-min(2*(recap_temp.FadeTimer-recap.Opt.AutoFadeTimer.value),1),.1))
if recap_temp.FadeTimer > (recap.Opt.AutoFadeTimer.value+.5) then
RecapFrame_Hide()
end
end
end
if recap_temp.Loaded and recap.Opt.AutoMinimize.value and recap_temp.Selected==0 then
if not recap.Opt.Minimized.value and not MouseIsOver(RecapFrame) and not IsShiftKeyDown() then
Recap_Minimize()
elseif recap.Opt.Minimized.value and MouseIsOver(RecapFrame) and not IsShiftKeyDown() then
Recap_Maximize()
end
end
end
function Recap_SlashHandler(arg1)
Recap_Initialize()
if arg1 and arg1=="reset" then
RecapFrame:ClearAllPoints()
RecapFrame:SetPoint("CENTER","UIParent","CENTER")
RecapOptFrame:ClearAllPoints()
RecapOptFrame:SetPoint("CENTER","UIParent","CENTER")
Recap_SetView()
elseif arg1=="debug" then
if recap.debug then
DEFAULT_CHAT_FRAME:AddMessage("recap.debug is ON. To turn it off: /recap debug off")
for i=1,150 do
if recap.debug_Filter[i] then
DEFAULT_CHAT_FRAME:AddMessage("["..i.."] \""..recap.debug_Filter[i].pattern.."\" hits: "..recap.debug_Filter[i].hits..", total: "..recap.debug_Filter[i].total)
end
end
DEFAULT_CHAT_FRAME:AddMessage("__ Filters not used __")
Recap_DebugUnusedFilters("Filter")
Recap_DebugUnusedFilters("HealFilter")
Recap_DebugUnusedFilters("DeathFilter")
else
DEFAULT_CHAT_FRAME:AddMessage("recap.debug is OFF. To turn it on: /recap debug on")
end
elseif arg1=="debug on" then
recap.debug = true
DEFAULT_CHAT_FRAME:AddMessage("recap.debug is now ON.")
elseif arg1=="debug off" then
recap.debug = false
DEFAULT_CHAT_FRAME:AddMessage("recap.debug is now OFF.")
elseif arg1=="debug reset" then
recap.debug_Filter = {}
DEFAULT_CHAT_FRAME:AddMessage("recap.debug_Filter is RESET.")
elseif string.find(arg1,"opt") then
if RecapOptFrame:IsShown() then
RecapOptFrame:Hide()
else
RecapOptFrame:Show()
end
elseif RecapFrame:IsShown() then
RecapFrame_Hide()
RecapOptFrame:Hide()
else
RecapFrame_Show()
Recap_CheckWindowBounds()
if recap.Opt.State.value == "Stopped" then
Recap_SetState("Idle")
recap.Opt.Paused.value = false
Recap_SetButtons()
end
end
end
--[[ Window appearance functions ]]
function Recap_SetState(arg1)
if arg1 then
recap.Opt.State.value = arg1
end
if recap.Opt.State.value=="Stopped" then
RecapStatusTexture:SetVertexColor(1,0,0)
Recap_Unregister_CombatEvents()
elseif recap.Opt.State.value=="Active" then
RecapStatusTexture:SetVertexColor(0,1,0)
Recap_Register_CombatEvents()
else
RecapStatusTexture:SetVertexColor(.5,.5,.5)
Recap_Register_CombatEvents()
end
Recap_UpdatePlugins()
end
function RecapFrame_Hide()
if not recap_temp.Loaded then
Recap_Initialize()
end
recap_temp.FadeTimer = -1
RecapFrame:SetAlpha(1)
RecapFrame:Hide()
recap.Opt.Visible.value = false
end
function RecapFrame_Show()
if not recap_temp.Loaded then
Recap_Initialize()
end
RecapFrame:Show()
recap.Opt.Visible.value = true
end
function RecapOptFrame_Hide()
--[[
RecapSetEditBox:SetText("")
RecapSetEditBox:ClearFocus()
if RecapOptClipFrame:IsVisible() then
RecapClipEditBox:ClearFocus()
RecapOptClipFrame:Hide()
RecapOptSubFrame4:Show()
end
]]
RecapOptFrame:Hide()
end
function RecapFrame_Toggle()
if RecapFrame:IsShown() then
RecapFrame_Hide()
RecapOptFrame:Hide()
else
RecapFrame_Show()
end
end
function Recap_Shutdown()
recap.Opt.Paused.value = true
Recap_EndFight()
Recap_SetState("Stopped")
Recap_SetButtons()
RecapOptFrame:Hide()
RecapFrame_Hide()
RecapCombatEvents:UnregisterAll()
end
function Recap_ToggleView()
if recap.Opt.View.value=="All" then
Recap_SetView("Last")
else
Recap_SetView("All")
end
end
-- changes button textures depending on their state
function Recap_SetButtons()
local i
for i in recapbuttons do
if recap.Opt[i].value then
getglobal(recapbuttons[i]):SetNormalTexture("Interface\\AddOns\\Recap\\RecapButtons-Down")
getglobal(recapbuttons[i]):SetPushedTexture("Interface\\AddOns\\Recap\\RecapButtons-Up")
else
getglobal(recapbuttons[i]):SetNormalTexture("Interface\\AddOns\\Recap\\RecapButtons-Up")
getglobal(recapbuttons[i]):SetPushedTexture("Interface\\AddOns\\Recap\\RecapButtons-Down")
end
end
if recap.Opt.View.value=="Last" then
RecapShowAllButton:SetNormalTexture("Interface\\AddOns\\Recap\\RecapButtons-Up")
RecapShowAllButton:SetPushedTexture("Interface\\AddOns\\Recap\\RecapButtons-Down")
else
RecapShowAllButton:SetNormalTexture("Interface\\AddOns\\Recap\\RecapButtons-Down")
RecapShowAllButton:SetPushedTexture("Interface\\AddOns\\Recap\\RecapButtons-Up")
end
end
-- this resizes the window width to the columns defined in options
function Recap_SetColumns()
local cx = 168 -- 8(edge)+120(name)+32(scroll)+8(edge)
local i,j,icx,item
RecapHeader_Name:Show()
RecapTotals:Show()
if recap.Opt.SelfView.value then
for i in recap.Opt do
if recap.Opt[i].ewidth then
if recap.Opt[i].value then
getglobal("RecapHeader_"..i):SetWidth(recap_temp.DefaultOpt[i].ewidth)
getglobal("RecapHeader_"..i):Show()
for j=1,15 do
getglobal("RecapSelf"..j.."_"..i):SetWidth(recap_temp.DefaultOpt[i].ewidth)
getglobal("RecapSelf"..j.."_"..i):Show()
end
cx = cx + recap_temp.DefaultOpt[i].ewidth
else
getglobal("RecapHeader_"..i):SetWidth(1)
getglobal("RecapHeader_"..i):Hide()
for j=1,15 do
getglobal("RecapSelf"..j.."_"..i):SetWidth(1)
getglobal("RecapSelf"..j.."_"..i):Hide()
end
cx = cx + 1
end
elseif recap.Opt[i].width then
getglobal("RecapHeader_"..i):Hide()
end
end
RecapHeader_EName:Show()
RecapHeader_Name:Hide()
RecapTotals:Hide()
for i=1,15 do
getglobal("RecapList"..i):Hide()
getglobal("RecapSelf"..i):Show()
getglobal("RecapSelf"..i):SetWidth(cx-48)
end
RecapTotals_DPSIn:Hide()
else
for i in recap.Opt do
if recap.Opt[i].width then
if recap.Opt[i].value then
item = getglobal("RecapHeader_"..i)
item:SetWidth(recap_temp.DefaultOpt[i].width)
item:Show()
item = getglobal("RecapTotals_"..i)
item:SetWidth(recap_temp.DefaultOpt[i].width)
item:Show()
for j=1,15 do
item = getglobal("RecapList"..j.."_"..i)
item:SetWidth(recap_temp.DefaultOpt[i].width)
item:Show()
end
cx = cx + recap_temp.DefaultOpt[i].width
else
item = getglobal("RecapHeader_"..i)
item:SetWidth(1)
item:Hide()
item = getglobal("RecapTotals_"..i)
item:SetWidth(1)
item:Hide()
for j=1,15 do
item = getglobal("RecapList"..j.."_"..i)
item:SetWidth(1)
item:Hide()
end
cx = cx + 1
end
elseif recap.Opt[i].ewidth then
getglobal("RecapHeader_"..i):Hide()
end
end
for i=1,15 do
getglobal("RecapSelf"..i):Hide()
getglobal("RecapList"..i):Show()
getglobal("RecapList"..i):SetWidth(cx-48)
end
RecapHeader_EName:Hide()
if recap.Opt.DPSIn.value then
RecapTotals_DPSIn:Show()
else
RecapTotals_DPSIn:Hide()
end
end
RecapTotals:SetWidth(cx-48)
if recap.Opt.GrowLeftwards.value and RecapFrame then
i = RecapFrame:GetRight()
j = RecapFrame:GetTop()
if i and j then
RecapFrame:ClearAllPoints()
RecapFrame:SetPoint("TOPLEFT","UIParent","BOTTOMLEFT",i-cx,j) -- *** i not defined sometimes :( **
end
end
RecapTopBar:SetWidth(cx-8)
RecapBottomBar:SetWidth(cx-16)
RecapFrame:SetWidth(cx)
RecapScrollBar:SetWidth(cx-16)
recap_temp.GaugeWidth = cx-51 - ( (not recap.Opt.SelfView.value) and ((((recap.Opt.Faction.value and recap.Opt.Faction.width) or 1) + ((recap.Opt.Class.value and recap.Opt.Class.width) or 1) + ((recap.Opt.Ranks.value and recap.Opt.Ranks.width) or 1)) or 0) or 0)
Recap_CheckWindowBounds()
Recap_SetView()
RecapScrollBar_Update()
end
-- changes view mode
function Recap_SetView(arg1)
local text
if arg1 then
recap.Opt.View.value = arg1
end
Recap_SetButtons()
Recap_ConstructList()
cx = RecapFrame:GetWidth()
-- change titlebar
if cx and cx>300 and recap.Opt.SelfView.value then
text = recap_temp.Player.."'s Details"
elseif cx and cx>230 and recap.Opt.SelfView.value then
text = recap_temp.Player
elseif cx and cx<230 or recap.Opt.Minimized.value then
text = ""
if cx>180 and not recap.Opt.SelfView.value then
text = recap.Opt.View.value
end
elseif cx and cx<260 then
text = recap_temp.Local.LastAll[recap.Opt.View.value]
else
text = "Recap of "..recap_temp.Local.LastAll[recap.Opt.View.value]
end
RecapTitle:SetText(text)
RecapHeader_Name:SetText((recap_temp.ListSize-1).." Combatants")
Recap_ChangeBack()
end
function Recap_SetColors()
if recap.Opt.UseColor.value then
recap_temp.ColorDmgIn = recap_temp.ColorRed
recap_temp.ColorDmgOut = recap_temp.ColorGreen
recap_temp.ColorHeal = recap_temp.ColorBlue
recap_temp.ColorHits = recap_temp.ColorCyan
recap_temp.ColorTicks = recap_temp.ColorYellow
recap_temp.ColorCrits = recap_temp.ColorLime
recap_temp.ColorMiss = recap_temp.ColorPink
else
recap_temp.ColorDmgIn = recap_temp.ColorWhite
recap_temp.ColorDmgOut = recap_temp.ColorNone
recap_temp.ColorHeal = recap_temp.ColorWhite
recap_temp.ColorHits = recap_temp.ColorWhite
recap_temp.ColorTicks = recap_temp.ColorWhite
recap_temp.ColorCrits = recap_temp.ColorWhite
recap_temp.ColorMiss = recap_temp.ColorWhite
end
RecapTotals_DmgIn:SetTextColor(recap_temp.ColorDmgIn.r,recap_temp.ColorDmgIn.g,recap_temp.ColorDmgIn.b)
RecapTotals_DmgOut:SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
RecapTotals_DPS:SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
RecapTotals_DPSvsAll:SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
RecapTotals_DPSIn:SetTextColor(recap_temp.ColorDmgIn.r,recap_temp.ColorDmgIn.g,recap_temp.ColorDmgIn.b)
RecapTotals_Heal:SetTextColor(recap_temp.ColorHeal.r,recap_temp.ColorHeal.g,recap_temp.ColorHeal.b)
RecapTotals_Over:SetTextColor(recap_temp.ColorHeal.r,recap_temp.ColorHeal.g,recap_temp.ColorHeal.b)
RecapMinDPSIn_Text:SetTextColor(recap_temp.ColorDmgIn.r,recap_temp.ColorDmgIn.g,recap_temp.ColorDmgIn.b)
RecapMinDPSOut_Text:SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
for i=1,15 do
getglobal("RecapList"..i.."_HealP"):SetTextColor(recap_temp.ColorHeal.r,recap_temp.ColorHeal.g,recap_temp.ColorHeal.b)
getglobal("RecapList"..i.."_Over"):SetTextColor(recap_temp.ColorHeal.r,recap_temp.ColorHeal.g,recap_temp.ColorHeal.b)
getglobal("RecapList"..i.."_DmgInP"):SetTextColor(recap_temp.ColorDmgIn.r,recap_temp.ColorDmgIn.g,recap_temp.ColorDmgIn.b)
getglobal("RecapList"..i.."_DmgOutP"):SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
getglobal("RecapSelf"..i.."_EHits"):SetTextColor(recap_temp.ColorHits.r,recap_temp.ColorHits.g,recap_temp.ColorHits.b)
getglobal("RecapSelf"..i.."_EHitsAvg"):SetTextColor(recap_temp.ColorHits.r,recap_temp.ColorHits.g,recap_temp.ColorHits.b)
getglobal("RecapSelf"..i.."_EHitsMax"):SetTextColor(recap_temp.ColorHits.r,recap_temp.ColorHits.g,recap_temp.ColorHits.b)
getglobal("RecapSelf"..i.."_ETicks"):SetTextColor(recap_temp.ColorTicks.r,recap_temp.ColorTicks.g,recap_temp.ColorTicks.b)
getglobal("RecapSelf"..i.."_ETicksAvg"):SetTextColor(recap_temp.ColorTicks.r,recap_temp.ColorTicks.g,recap_temp.ColorTicks.b)
getglobal("RecapSelf"..i.."_ETicksMax"):SetTextColor(recap_temp.ColorTicks.r,recap_temp.ColorTicks.g,recap_temp.ColorTicks.b)
getglobal("RecapSelf"..i.."_ECrits"):SetTextColor(recap_temp.ColorCrits.r,recap_temp.ColorCrits.g,recap_temp.ColorCrits.b)
getglobal("RecapSelf"..i.."_ECritsAvg"):SetTextColor(recap_temp.ColorCrits.r,recap_temp.ColorCrits.g,recap_temp.ColorCrits.b)
getglobal("RecapSelf"..i.."_ECritsMax"):SetTextColor(recap_temp.ColorCrits.r,recap_temp.ColorCrits.g,recap_temp.ColorCrits.b)
getglobal("RecapSelf"..i.."_ECritsP"):SetTextColor(recap_temp.ColorCrits.r,recap_temp.ColorCrits.g,recap_temp.ColorCrits.b)
getglobal("RecapSelf"..i.."_EMiss"):SetTextColor(recap_temp.ColorMiss.r,recap_temp.ColorMiss.g,recap_temp.ColorMiss.b)
getglobal("RecapSelf"..i.."_EMissP"):SetTextColor(recap_temp.ColorMiss.r,recap_temp.ColorMiss.g,recap_temp.ColorMiss.b)
end
Recap_ChangeBack()
end
function Recap_ChangeBack()
if recap.Opt.UseColor.value and (recap.Opt.MinBack.value or not recap.Opt.Minimized.value) then
if recap.Opt.SelfView.value and not recap.Opt.Minimized.value then
RecapTitleBack:SetVertexColor(0,0,.8)
elseif recap.Opt.View.value=="Last" then
RecapTitleBack:SetVertexColor(0,.66,0)
else
RecapTitleBack:SetVertexColor(.66,0,0)
end
RecapTitleBack:Show()
else
RecapTitleBack:Hide()
end
end
--[[ Initialization ]]
-- Can be called often, will immediately dump out if it ran through successfully
function Recap_Initialize()
local i,x
local init_time
if not recap_temp.Loaded then
if UnitName("player") and UnitName("player")~=UNKNOWNOBJECT and RecapFrame and RecapOptFrame then
init_time = GetTime()
recap_temp.Player = UnitName("player")
recap_temp.Server = GetCVar("realmName")
-- recap index for this player
recap_temp.p = recap_temp.Player..recap_temp.Server -- use for stuff that can be made global
recap_temp.s = recap_temp.Player..recap_temp.Server -- use for stuff that should never be global
if recap and recap.UseOneSettings and recap.User then
recap_temp.p = recap.User
end
-- sources of damage/heals otherwise not declared in chat spam
recap_temp.FilterIndex[6] = recap_temp.Player
recap_temp.FilterIndex[7] = "Melee"
recap_temp.FilterIndex[8] = "Damage Shields"
recap_temp.FilterIndex[13] = 0
Recap_InitializeData()
if not recap[recap_temp.p].WindowTop and RecapFrame then
RecapFrame:ClearAllPoints()
RecapFrame:SetPoint("CENTER","UIParent","CENTER")
RecapOptFrame:ClearAllPoints()
RecapOptFrame:SetPoint("CENTER", "UIParent", "CENTER")
elseif recap[recap_temp.p].WindowTop and RecapFrame then
RecapFrame:ClearAllPoints()
RecapFrame:SetPoint("TOPLEFT","UIParent","BOTTOMLEFT",recap[recap_temp.p].WindowLeft,recap[recap_temp.p].WindowTop)
RecapFrame:SetWidth(recap[recap_temp.p].WindowWidth)
RecapFrame:SetHeight(recap[recap_temp.p].WindowHeight)
end
for i in recap.Combatant do
recap.Combatant[i].WasInLast = false
recap.Combatant[i].WasInCurrent = false
end
recap[recap_temp.p].LastDuration = 0
Recap_SetColors()
-- if we loaded out of stopped state, force into idle state
if recap.Opt.State.value ~= "Stopped" then
recap.Opt.State.value = "Idle"
end
Recap_SetState()
RecapTotals_Name:SetWidth(82)
Recap_InitDataSets()
if recap.Opt.LightData.value then
recap.Opt.SelfView.value = false
RecapSelfViewButton:Hide()
end
if recap.Opt.Minimized.value then
Recap_SetButtons()
Recap_ConstructList()
Recap_Minimize()
else
Recap_Maximize()
end
-- we're in the world (in theory), register active events
this:RegisterEvent("PLAYER_REGEN_DISABLED")
this:RegisterEvent("PLAYER_REGEN_ENABLED")
this:RegisterEvent("PARTY_MEMBERS_CHANGED")
this:RegisterEvent("RAID_ROSTER_UPDATE")
Recap_Register_CombatEvents()
recap_temp.Loaded = true
Recap_InitializeOptions()
Recap_MoveMinimize()
-- initialize panel
recap_temp.Selected = 0
if recap.Opt.LightData.value then
recap.Opt.PanelView.value = 3
RecapPanelTab1:SetAlpha(.5)
RecapPanelTab2:SetAlpha(.5)
end
RecapPanel_SwitchPanels(recap.Opt.PanelView.value)
if recap.Opt.PanelAnchor.value then
RecapPanel:ClearAllPoints()
RecapPanel:SetPoint(recap.Opt.PanelAnchor.Panel,"RecapFrame",recap.Opt.PanelAnchor.Main,Recap_PanelOffset("x"),Recap_PanelOffset("y"))
end
RecapPanelFaction:SetAlpha(.75)
for i=1,15 do
getglobal("RecapList"..i.."_Faction"):SetAlpha(.75)
end
if recap.Opt.Visible.value then
RecapFrame_Show()
else
RecapFrame_Hide()
end
if recap.Opt.Paused.value then
RecapFrame_Hide()
end
if recap.debug then
DEFAULT_CHAT_FRAME:AddMessage("[recap.debug] Time to initialize: "..string.format("%.4f",GetTime()-init_time).." seconds.")
end
-- warn if user has a lot of data (over 500 combatants)
x = 0
for i in recap.Combatant do
x = x + 1
end
if x>500 and recap.Opt.WarnData.value then
StaticPopupDialogs["RECAP_LOTS_OF_DATA_WARNING"] = {
text = TEXT(string.format(recap_temp.Local.LotsOfDataWarning,x)),
button1 = TEXT(OKAY),
timeout = 0,
showAlert = 1,
whileDead = 1
}
StaticPopup_Show("RECAP_LOTS_OF_DATA_WARNING")
end
table.insert(UISpecialFrames,"RecapOptFrame")
table.insert(UISpecialFrames,"RecapPanel")
end
end
end
-- arg1==1 to hide buttons, 16 to show
function Recap_ShowButtons(arg1)
RecapCloseButton:SetWidth(arg1)
RecapPinButton:SetWidth(arg1)
RecapPauseButton:SetWidth(arg1)
RecapOptionsButton:SetWidth(arg1)
RecapShowAllButton:SetWidth(arg1)
if arg1==16 then
RecapCloseButton:Show()
RecapPinButton:Show()
RecapPauseButton:Show()
RecapOptionsButton:Show()
RecapShowAllButton:Show()
else
RecapCloseButton:Hide()
RecapPinButton:Hide()
RecapPauseButton:Hide()
RecapOptionsButton:Hide()
RecapShowAllButton:Hide()
end
end
function Recap_Minimize()
local i,j
local cx = 20 -- 8(edge)+4(space right of status)+8
recap.Opt.Minimized.value = true
for i in recap.Opt do
if recap.Opt[i].minwidth then
if recap.Opt[i].value then
item = getglobal("Recap"..i)
item:SetWidth(recap.Opt[i].minwidth)
item:Show()
cx = cx + recap.Opt[i].minwidth
else
item = getglobal("Recap"..i)
item:SetWidth(1)
item:Hide()
cx = cx + 1
end
elseif recap.Opt[i].width or recap.Opt[i].ewidth then
getglobal("RecapHeader_"..i):Hide()
end
end
if recap.Opt.MinButtons.value then
cx = cx + 108
Recap_ShowButtons(16)
else
Recap_ShowButtons(1)
cx = cx + 23 -- 5 + 18
end
RecapTitle:SetText(recap.Opt.View.value)
RecapTopBar:Hide()
RecapBottomBar:Hide()
RecapTotals_DPSIn:Hide()
RecapResetButton:Hide()
for i=1,15 do
getglobal("RecapList"..i):Hide()
getglobal("RecapSelf"..i):Hide()
end
RecapTotals:Hide()
RecapHeader_EName:Hide()
RecapHeader_Name:Hide()
RecapScrollBar:Hide()
if recap.Opt.AutoMinimize.value then
cx = cx-15
end
if recap.Opt.GrowLeftwards.value and RecapFrame then
i = RecapFrame:GetRight()
j = RecapFrame:GetTop()
if i and j then
RecapFrame:ClearAllPoints()
RecapFrame:SetPoint("TOPLEFT","UIParent","BOTTOMLEFT",i-cx,j)
end
end
RecapFrame:SetWidth(cx)
Recap_SetHeight(28)
if recap.Opt.MinBack.value then
RecapFrame:SetBackdropColor(1,1,1,1)
RecapFrame:SetBackdropBorderColor(.5,.5,.5,1)
else
RecapFrame:SetBackdropColor(0,0,0,0)
RecapFrame:SetBackdropBorderColor(0,0,0,0)
end
RecapSelfViewButton:Hide()
RecapPanel_Hide(1)
Recap_MoveMinimize()
Recap_ChangeBack()
RecapMinView:GetLeft()
end
function Recap_Maximize()
recap.Opt.Minimized.value = false
for i in recap.Opt do
if recap.Opt[i].minwidth then
item = getglobal("Recap"..i)
item:SetWidth(recap.Opt[i].minwidth)
item:Hide()
end
end
RecapMinStatus:Show()
RecapMinView:Show()
Recap_ShowButtons(16)
RecapTopBar:Show()
RecapBottomBar:Show()
RecapResetButton:Show()
RecapTotals:Show()
RecapHeader_Name:Show()
RecapScrollBar:Show()
Recap_SetColumns()
RecapFrame:SetBackdropColor(1,1,1,1)
RecapFrame:SetBackdropBorderColor(.5,.5,.5,1)
if not recap.Opt.LightData.value then
RecapSelfViewButton:Show()
end
Recap_MoveMinimize()
end
function Recap_SetHeight(newcy)
local i,j
if recap.Opt.GrowUpwards.value and RecapFrame then
i = RecapFrame:GetBottom()
j = RecapFrame:GetLeft()
if i and j then
RecapFrame:ClearAllPoints()
RecapFrame:SetPoint("TOPLEFT","UIParent","BOTTOMLEFT",j,i+newcy)
end
end
RecapFrame:SetHeight(newcy)
Recap_CheckWindowBounds()
end
function RecapScrollBar_Update()
local i, index, item
local listsize = recap.Opt.SelfView.value and recap_temp.SelfListSize or recap_temp.ListSize
if not recap.Opt.Minimized.value then
i = 72 + ( math.max( math.min(listsize-1,recap.Opt.MaxRows.value),1 )*14 )
Recap_SetHeight(i)
RecapScrollBar:SetHeight(i-63)
FauxScrollFrame_Update(RecapScrollBar,listsize-1,recap.Opt.MaxRows.value,10)
for i=1,recap.Opt.MaxRows.value do
index = i + FauxScrollFrame_GetOffset(RecapScrollBar)
if not recap.Opt.SelfView.value then
if index < listsize then
getglobal("RecapList"..i.."_Ranks"):SetText(index..".")
Recap_SetFactionIcon(i,recap.Combatant[recap_temp.List[index].Name].Faction)
Recap_SetClassIcon(i,recap.Combatant[recap_temp.List[index].Name].Class)
if recap.Opt.Faction.value and recap.Combatant[recap_temp.List[index].Name].Level==-1 then
getglobal("RecapList"..i.."_Level"):SetText("??")
elseif recap.Opt.Faction.value and recap.Combatant[recap_temp.List[index].Name].Level and tonumber(recap.Combatant[recap_temp.List[index].Name].Level)>0 then
getglobal("RecapList"..i.."_Level"):SetText(recap.Combatant[recap_temp.List[index].Name].Level)
else
getglobal("RecapList"..i.."_Level"):SetText(" ")
end
item = getglobal("RecapList"..i.."_Name")
item:SetText(recap_temp.List[index].Name)
if recap.Combatant[recap_temp.List[index].Name].Friend then
item:SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
else
item:SetTextColor(recap_temp.ColorWhite.r,recap_temp.ColorWhite.g,recap_temp.ColorWhite.b)
end
item = getglobal("RecapList"..i.."_Gauge")
if recap.Opt.ShowGauges.value and recap_temp.GaugeMax>0 and recap.Combatant[recap_temp.List[index].Name].Friend and recap_temp.GaugeBy then
item:SetWidth(1+recap_temp.GaugeWidth*recap_temp.List[index][recap_temp.GaugeBy]/recap_temp.GaugeMax)
item:Show()
else
item:Hide()
end
getglobal("RecapList"..i.."_Kills"):SetText(recap_temp.List[index].Kills)
getglobal("RecapList"..i.."_Time"):SetText(Recap_FormatTime(recap_temp.List[index].Time))
item = getglobal("RecapList"..i.."_Heal")
item:SetText(recap_temp.List[index].Heal)
if recap.Combatant[recap_temp.List[index].Name].Friend then
item:SetTextColor(recap_temp.ColorHeal.r,recap_temp.ColorHeal.g,recap_temp.ColorHeal.b)
else
item:SetTextColor(recap_temp.ColorWhite.r,recap_temp.ColorWhite.g,recap_temp.ColorWhite.b)
end
getglobal("RecapList"..i.."_HealP"):SetText(recap.Combatant[recap_temp.List[index].Name].Friend and recap_temp.List[index].HealP.."%" or "")
getglobal("RecapList"..i.."_Over"):SetText(recap.Combatant[recap_temp.List[index].Name].Friend and recap_temp.List[index].Over.."%" or "")
getglobal("RecapList"..i.."_MaxHit"):SetText(recap_temp.List[index].MaxHit)
item = getglobal("RecapList"..i.."_DmgIn")
item:SetText(recap_temp.List[index].DmgIn)
if recap.Combatant[recap_temp.List[index].Name].Friend then
item:SetTextColor(recap_temp.ColorDmgIn.r,recap_temp.ColorDmgIn.g,recap_temp.ColorDmgIn.b)
else
item:SetTextColor(recap_temp.ColorWhite.r,recap_temp.ColorWhite.g,recap_temp.ColorWhite.b)
end
getglobal("RecapList"..i.."_DmgInP"):SetText(recap.Combatant[recap_temp.List[index].Name].Friend and recap_temp.List[index].DmgInP.."%" or "")
item = getglobal("RecapList"..i.."_DmgOut")
item:SetText(recap_temp.List[index].DmgOut)
if recap.Combatant[recap_temp.List[index].Name].Friend then
item:SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
else
item:SetTextColor(recap_temp.ColorWhite.r,recap_temp.ColorWhite.g,recap_temp.ColorWhite.b)
end
getglobal("RecapList"..i.."_DmgOutP"):SetText(recap.Combatant[recap_temp.List[index].Name].Friend and recap_temp.List[index].DmgOutP.."%" or "")
item = getglobal("RecapList"..i.."_DPS")
item:SetText(format(recap_temp.List[index].DPS<1000 and "%.1f" or "%d",recap_temp.List[index].DPS))
if recap.Combatant[recap_temp.List[index].Name].Friend then
item:SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
else
item:SetTextColor(recap_temp.ColorWhite.r,recap_temp.ColorWhite.g,recap_temp.ColorWhite.b)
end
item = getglobal("RecapList"..i.."_DPSvsAll")
item:SetText(format(recap_temp.List[index].DPSvsAll<1000 and "%.1f" or "%d",recap_temp.List[index].DPSvsAll))
if recap.Combatant[recap_temp.List[index].Name].Friend then
item:SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
else
item:SetTextColor(recap_temp.ColorWhite.r,recap_temp.ColorWhite.g,recap_temp.ColorWhite.b)
end
item = getglobal("RecapList"..i)
item:Show()
if recap_temp.Selected == index then
item:LockHighlight()
else
item:UnlockHighlight()
end
else
getglobal("RecapList"..i):Hide()
getglobal("RecapList"..i):UnlockHighlight()
end
for i=recap.Opt.MaxRows.value+1,15 do
getglobal("RecapList"..i):Hide()
end
elseif recap.Opt.SelfView.value then
if index < listsize then
getglobal("RecapSelf"..i.."_EName"):SetText(string.sub(recap_temp.SelfList[index].EName,2))
getglobal("RecapSelf"..i.."_ETotal"):SetText(recap_temp.SelfList[index].ETotal)
getglobal("RecapSelf"..i.."_EHits"):SetText(recap_temp.SelfList[index].EHits)
getglobal("RecapSelf"..i.."_ETicks"):SetText(recap_temp.SelfList[index].ETicks)
getglobal("RecapSelf"..i.."_ECrits"):SetText(recap_temp.SelfList[index].ECrits)
getglobal("RecapSelf"..i.."_EHitsAvg"):SetText(recap_temp.SelfList[index].EHitsAvg)
getglobal("RecapSelf"..i.."_ETicksAvg"):SetText(recap_temp.SelfList[index].ETicksAvg)
getglobal("RecapSelf"..i.."_ECritsAvg"):SetText(recap_temp.SelfList[index].ECritsAvg)
getglobal("RecapSelf"..i.."_EHitsMax"):SetText(recap_temp.SelfList[index].EHitsMax)
getglobal("RecapSelf"..i.."_ETicksMax"):SetText(recap_temp.SelfList[index].ETicksMax)
getglobal("RecapSelf"..i.."_ECritsMax"):SetText(recap_temp.SelfList[index].ECritsMax)
getglobal("RecapSelf"..i.."_ECritsP"):SetText(recap_temp.SelfList[index].ECritsP)
getglobal("RecapSelf"..i.."_EMiss"):SetText(recap_temp.SelfList[index].EMiss)
getglobal("RecapSelf"..i.."_EMissP"):SetText(recap_temp.SelfList[index].EMissP)
getglobal("RecapSelf"..i.."_EMaxAll"):SetText(recap_temp.SelfList[index].EMaxAll)
getglobal("RecapSelf"..i.."_ETotalP"):SetText(recap_temp.SelfList[index].ETotalP)
if string.sub(recap_temp.SelfList[index].EName,1,1)<"3" then
getglobal("RecapSelf"..i.."_EName"):SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
getglobal("RecapSelf"..i.."_ETotal"):SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
getglobal("RecapSelf"..i.."_ETotalP"):SetTextColor(recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
else
getglobal("RecapSelf"..i.."_EName"):SetTextColor(recap_temp.ColorHeal.r,recap_temp.ColorHeal.g,recap_temp.ColorHeal.b)
getglobal("RecapSelf"..i.."_ETotal"):SetTextColor(recap_temp.ColorHeal.r,recap_temp.ColorHeal.g,recap_temp.ColorHeal.b)
getglobal("RecapSelf"..i.."_ETotalP"):SetTextColor(recap_temp.ColorHeal.r,recap_temp.ColorHeal.g,recap_temp.ColorHeal.b)
end
getglobal("RecapSelf"..i):Show()
else
getglobal("RecapSelf"..i):Hide()
end
for i=recap.Opt.MaxRows.value+1,15 do
getglobal("RecapSelf"..i):Hide()
end
end
end
end
end
--[[ Fight functions ]]
function Recap_CreateCombatant(arg1,is_source)
if not arg1 then
return
end
-- if arg1 not a .Combatant, add an entry for them
if not recap.Combatant[arg1] then
Recap_CreateBlankCombatant(arg1)
end
-- if they haven't fought this session, add a .Last entry for them
if not recap_temp.Last[arg1] then
recap_temp.Last[arg1] = { Start = 0, End = 0, DmgIn = 0, DmgOut = 0, MaxHit = 0, Kills = 0, Heal = 0 }
end
-- if arg1 is hitting others, update their start or end time
if is_source then
if recap_temp.FightStart==0 then
recap_temp.FightStart = GetTime()
recap_temp.FightEnd = recap_temp.FightStart
else
recap_temp.FightEnd = GetTime()
end
if recap_temp.Last[arg1].Start==0 then
recap_temp.Last[arg1].Start = GetTime()
recap_temp.Last[arg1].End = recap_temp.Last[arg1].Start
else
recap_temp.Last[arg1].End = GetTime()
end
end
recap.Combatant[arg1].WasInCurrent = true
end
function Recap_StartFight()
local i
if recap.Opt.State.value=="Idle" then
if recap.Opt.AutoHide.value and not recap.Opt.Minimized.value then
RecapFrame_Hide()
end
for i in recap.Combatant do
recap.Combatant[i].WasInCurrent = false
end
if not recap.Opt.LimitFights.value and recap.Opt.IdleFight.value then
recap_temp.IdleTimer = 0
end
RecapIdleFrame:Show() -- start idle OnUpdates
Recap_SetState("Active")
end
end
-- returns the current DPS of combatant named arg1 if it exists. UpdateDuration/DamageOut reused to save allocations
function Recap_GetCurrentDPS(arg1)
if arg1 and recap_temp.Last[arg1] and recap_temp.Last[arg1].DmgOut>0 then
recap_temp.UpdateDuration = recap_temp.Last[arg1].End - recap_temp.Last[arg1].Start
if recap.Opt.View.value=="All" then
recap_temp.UpdateDuration = recap_temp.UpdateDuration + recap.Combatant[arg1].TotalTime
end
recap_temp.UpdateDamageOut = recap_temp.Last[arg1].DmgOut
if recap.Opt.View.value=="All" then
recap_temp.UpdateDamageOut = recap_temp.UpdateDamageOut + recap.Combatant[arg1].TotalDmgOut
end
if recap_temp.UpdateDuration > recap_temp.MinTime then
return (recap_temp.UpdateDamageOut / recap_temp.UpdateDuration)
end
end
return 0
end
function Recap_UpdateMinimizedDPS()
if recap.Opt.State.value=="Active" then
if recap_temp.Last[recap_temp.Player] and recap_temp.Last[recap_temp.Player].DmgOut>0 then
i = Recap_GetCurrentDPS(recap_temp.Player)+Recap_GetCurrentDPS(UnitName("pet"))
RecapMinYourDPS_Text:SetText(string.format("%.1f",i))
end
-- calculate running total DPS In and Out
recap_temp.UpdateDuration = 0
if recap_temp.FightEnd>0 and recap_temp.FightStart>0 then
recap_temp.UpdateDuration = recap_temp.FightEnd - recap_temp.FightStart
end
if recap.Opt.View.value=="All" then
recap_temp.UpdateDuration = recap_temp.UpdateDuration + recap[recap_temp.p].TotalDuration
end
if recap_temp.UpdateDuration>recap_temp.MinTime then
recap_temp.UpdateDmgIn = 0
recap_temp.UpdateDmgOut = 0
for i in recap_temp.Last do
if recap.Combatant[i].Friend then
recap_temp.UpdateDmgIn = recap_temp.UpdateDmgIn + recap_temp.Last[i].DmgIn
recap_temp.UpdateDmgOut = recap_temp.UpdateDmgOut + recap_temp.Last[i].DmgOut
end
end
if recap.Opt.View.value=="All" then
for i in recap.Combatant do
if recap.Combatant[i].Friend then
recap_temp.UpdateDmgIn = recap_temp.UpdateDmgIn + recap.Combatant[i].TotalDmgIn
recap_temp.UpdateDmgOut = recap_temp.UpdateDmgOut + recap.Combatant[i].TotalDmgOut
end
end
end
RecapMinDPSIn_Text:SetText(string.format("%.1f",recap_temp.UpdateDmgIn/recap_temp.UpdateDuration))
RecapMinDPSOut_Text:SetText(string.format("%.1f",recap_temp.UpdateDmgOut/recap_temp.UpdateDuration))
end
Recap_UpdatePlugins()
end
end
function Recap_AddPetToOwner(pet,owner)
local earliest,latest
local peteffect
-- times are only for DAMAGE
if (recap.Combatant[pet].WasInCurrent and recap_temp.Last[pet].DmgOut>0) and (recap.Combatant[owner].WasInCurrent and recap_temp.Last[owner].DmgOut>0) then
-- both pet and owner were in fight
earliest = math.min(recap_temp.Last[pet].Start,recap_temp.Last[owner].Start)
latest = math.max(recap_temp.Last[pet].End,recap_temp.Last[owner].End)
recap_temp.Last[owner].Start = earliest
recap_temp.Last[owner].End = latest
elseif (recap.Combatant[pet].WasInCurrent and recap_temp.Last[pet].DmgOut>0) and (not recap.Combatant[owner].WasInCurrent or recap_temp.Last[owner].DmgOut==0) then
-- just the pet was in fight
recap_temp.Last[owner].Start = recap_temp.Last[pet].Start
recap_temp.Last[owner].End = recap_temp.Last[pet].End
else
return -- temp fix for attempt to index field ? (a nil value) in line below ***
end
recap_temp.Last[owner].DmgIn = recap_temp.Last[owner].DmgIn + recap_temp.Last[pet].DmgIn
recap_temp.Last[owner].DmgOut = recap_temp.Last[owner].DmgOut + recap_temp.Last[pet].DmgOut
recap_temp.Last[owner].MaxHit = math.max(recap_temp.Last[owner].MaxHit,recap_temp.Last[pet].MaxHit)
Recap_AccumulateCombatant(owner)
recap_temp.Last[pet].Start = 0
recap_temp.Last[pet].End = 0
recap_temp.Last[pet].DmgIn = 0
recap_temp.Last[pet].DmgOut = 0
recap_temp.Last[pet].MaxHit = 0
recap_temp.Last[pet].Kills = 0
recap_temp.Last[pet].Heal = 0
recap.Combatant[pet].WasInLast = false
recap.Combatant[owner].WasInLast = true
recap.Combatant[pet].WasInCurrent = false
recap.Combatant[owner].WasInCurrent = false
if not recap.Opt.LightData.value then
for i in recap.Combatant[pet].Detail do
if string.sub(i,1,1)=="1" then
peteffect = "2"..pet.."'s "..string.sub(i,2)
else
peteffect = "4"..pet.."'s "..string.sub(i,2)
end
recap.Combatant[owner].Detail[peteffect] = {
Hits = recap.Combatant[pet].Detail[i].Hits, HitsDmg = recap.Combatant[pet].Detail[i].HitsDmg,
HitsMax = recap.Combatant[pet].Detail[i].HitsMax, Crits = recap.Combatant[pet].Detail[i].Crits,
CritsEvents = recap.Combatant[pet].Detail[i].CritsEvents, CritsDmg = recap.Combatant[pet].Detail[i].CritsDmg,
CritsMax = recap.Combatant[pet].Detail[i].CritsMax, Missed = recap.Combatant[pet].Detail[i].Missed,
TicksDmg = recap.Combatant[pet].Detail[i].TicksDmg, TicksMax = recap.Combatant[pet].Detail[i].TicksMax }
if owner==recap_temp.Player then
recap.Self[recap_temp.s][peteffect] = {
Hits = recap.Combatant[pet].Detail[i].Hits, HitsDmg = recap.Combatant[pet].Detail[i].HitsDmg,
HitsMax = recap.Combatant[pet].Detail[i].HitsMax, Crits = recap.Combatant[pet].Detail[i].Crits,
CritsEvents = recap.Combatant[pet].Detail[i].CritsEvents, CritsDmg = recap.Combatant[pet].Detail[i].CritsDmg,
CritsMax = recap.Combatant[pet].Detail[i].CritsMax, Missed = recap.Combatant[pet].Detail[i].Missed,
TicksDmg = recap.Combatant[pet].Detail[i].TicksDmg, TicksMax = recap.Combatant[pet].Detail[i].TicksMax }
end
end
end
end
function Recap_AccumulateCombatant(i)
recap.Combatant[i].LastDmgIn = recap_temp.Last[i].DmgIn
recap.Combatant[i].LastDmgOut = recap_temp.Last[i].DmgOut
recap.Combatant[i].LastTime = recap_temp.Last[i].End-recap_temp.Last[i].Start
recap.Combatant[i].LastMaxHit = recap_temp.Last[i].MaxHit
recap.Combatant[i].LastKills = recap_temp.Last[i].Kills
recap.Combatant[i].LastHeal = recap_temp.Last[i].Heal
recap_temp.Last[i].Start = 0
recap_temp.Last[i].End = 0
recap_temp.Last[i].DmgIn = 0
recap_temp.Last[i].DmgOut = 0
recap_temp.Last[i].MaxHit = 0
recap_temp.Last[i].Kills = 0
recap_temp.Last[i].Heal = 0
recap.Combatant[i].TotalDmgIn = recap.Combatant[i].TotalDmgIn + recap.Combatant[i].LastDmgIn
recap.Combatant[i].TotalDmgOut = recap.Combatant[i].TotalDmgOut + recap.Combatant[i].LastDmgOut
recap.Combatant[i].TotalTime = recap.Combatant[i].TotalTime + recap.Combatant[i].LastTime
recap.Combatant[i].TotalKills = recap.Combatant[i].TotalKills + recap.Combatant[i].LastKills
recap.Combatant[i].TotalHeal = recap.Combatant[i].TotalHeal + recap.Combatant[i].LastHeal
if recap.Combatant[i].LastTime > recap_temp.MinTime then
recap.Combatant[i].LastDPS = recap.Combatant[i].LastDmgOut/recap.Combatant[i].LastTime
else
recap.Combatant[i].LastDPS = 0
end
if recap.Combatant[i].TotalTime > recap_temp.MinTime then
recap.Combatant[i].TotalDPS = recap.Combatant[i].TotalDmgOut/recap.Combatant[i].TotalTime
else
recap.Combatant[i].TotalDPS = 0
end
recap.Combatant[i].TotalMaxHit = math.max(recap.Combatant[i].LastMaxHit,recap.Combatant[i].TotalMaxHit)
recap.Combatant[i].WasInLast = true
end
function Recap_EndFight()
recap_temp.IdleTimer = -1
RecapIdleFrame:Hide()
if recap.Opt.State.value=="Active" then
recap.Opt.State.value = "Stopped" -- suspend logging to calculate
local debug_time = GetTime()
Recap_MakeFriends()
if recap_temp.FightEnd>recap_temp.FightStart then
recap[recap_temp.p].LastDuration = recap_temp.FightEnd-recap_temp.FightStart
else
recap[recap_temp.p].LastDuration = 0
end
recap[recap_temp.p].TotalDuration = recap[recap_temp.p].TotalDuration + recap[recap_temp.p].LastDuration
recap_temp.FightStart = 0
recap_temp.FightEnd = 0
recap_temp.ListSize = 1
for i in recap_temp.Last do
if recap.Combatant[i].WasInCurrent then
if recap.Combatant[i].OwnedBy and recap.Opt.MergePets.value then
Recap_AddPetToOwner(i,recap.Combatant[i].OwnedBy)
elseif recap.Combatant[i].OwnsPet and recap.Opt.MergePets.value then
Recap_AddPetToOwner(recap.Combatant[i].OwnsPet,i)
else
Recap_AccumulateCombatant(i)
end
else
recap.Combatant[i].WasInLast = false
end
end
if recap.Opt.AutoPost.value then
recap.Opt.SortBy.value = Recap_AutoPostGetStatID(recap.Opt.AutoPost.Stat)
recap.Opt.SortDir.value = false
end
Recap_ConstructList()
Recap_SetState("Idle")
if not recap.Opt.Minimized.value and recap.Opt.AutoHide.value then
RecapFrame_Show()
if recap.Opt.AutoFade.value then
recap_temp.FadeTimer = 0
end
end
if recap.Opt.AutoPost.value then
Recap_PostFight()
end
if recap.Opt.AutoLeader.value then
Recap_PostLeader()
end
if recap.debug then
DEFAULT_CHAT_FRAME:AddMessage("[recap.debug] Fight processed in "..string.format("%.4f",GetTime()-debug_time).." seconds for "..(recap_temp.ListSize-1).." combatants.")
end
end
end
-- parses CHAT_MSG_SPELL/COMBAT messages to .Last running totals
function Recap_DamageEvent(arg1)
local i, source, dest, damage, miss, effect
local found = false
local blocked = false
if recap.Opt.State.value~="Stopped" then
blocked = string.find(arg1,string.gsub(BLOCK_TRAILER,"%%d","%%d+")) -- true if (%d blocked)
arg1 = string.gsub(arg1," %(.+%)","") -- strip trailing ()'s we don't use
arg1 = string.gsub(arg1,"%.$","") -- strip trailing .'s
for i=1,recap_temp.FilterSize do
found,_,recap_temp.FilterIndex[1],recap_temp.FilterIndex[2],recap_temp.FilterIndex[3],recap_temp.FilterIndex[4],recap_temp.FilterIndex[5] = string.find(arg1,recap_temp.Filter[i].pattern)
if found then
source=recap_temp.FilterIndex[recap_temp.Filter[i].source]
dest=recap_temp.FilterIndex[recap_temp.Filter[i].dest]
if recap_temp.Local.SelfPronouns[string.lower(dest)] then
dest = recap_temp.Player
end
if recap_temp.Filter[i].damage then
damage=tonumber(recap_temp.FilterIndex[recap_temp.Filter[i].damage])
end
if recap_temp.Filter[i].effect then
effect = recap_temp.FilterIndex[recap_temp.Filter[i].effect]
end
if (recap.Combatant[source] and recap.Combatant[source].Ignore) or (recap.Combatant[dest] and recap.Combatant[dest].Ignore) then
return -- this is an ignored combatant, pretend the hit didn't happen at all
end
if not recap.Opt.LimitFights.value then
if recap.Opt.IdleFight.value then
recap_temp.IdleTimer = 0
end
if recap.Opt.State.value=="Idle" then
Recap_StartFight()
end
end
if recap.debug then
if not recap.debug_Filter then
recap.debug_Filter = {}
end
if not recap.debug_Filter[i] then
recap.debug_Filter[i] = { hits=1, total=(damage or 1), pattern=recap_temp.Filter[i].pattern }
else
recap.debug_Filter[i].hits = recap.debug_Filter[i].hits + 1
recap.debug_Filter[i].total = recap.debug_Filter[i].total + (damage or 1)
end
if recap_temp.Filter[i].watch then
DEFAULT_CHAT_FRAME:AddMessage("["..i.."] \""..recap_temp.Filter[i].pattern.."\" triggered!")
DEFAULT_CHAT_FRAME:AddMessage("source="..tostring(source)..", dest="..tostring(dest)..", damage="..tostring(damage)..", miss="..tostring(miss))
end
end
if damage~=0 then -- if this wasn't just a cast
Recap_CreateCombatant(source,1)
Recap_CreateCombatant(dest)
-- remove friend flag from hostiles no longer charmed
if recap.Combatant[source].Friend and recap.Combatant[dest].Friend then
recap.Combatant[source].Friend = false
end
else
if (not recap.Opt.LightData.value) and recap.Combatant[source] and recap.Combatant[source].Detail["1"..effect] then
Recap_CreateCombatant(source,1) -- if this was a cast that's done damage before, start timer
end
end
if damage and damage>0 then
-- process totals
recap_temp.Last[source].DmgOut = recap_temp.Last[source].DmgOut + damage
if damage > recap_temp.Last[source].MaxHit then
recap_temp.Last[source].MaxHit = damage
end
recap_temp.Last[dest].DmgIn = recap_temp.Last[dest].DmgIn + damage
if recap_temp.Last[dest].HP then
recap_temp.Last[dest].HP = recap_temp.Last[dest].HP - damage
end
if not recap.Opt.LightData.value then
if recap_temp.Filter[i].effect==7 then -- melee damage
recap.Combatant[dest].Incoming.MeleeDamage = (recap.Combatant[dest].Incoming.MeleeDamage or 0) + damage
if recap_temp.Filter[i].crit==1 then
recap.Combatant[dest].Incoming.MeleeCrits = (recap.Combatant[dest].Incoming.MeleeCrits or 0) + 1
else
recap.Combatant[dest].Incoming.MeleeHits = (recap.Combatant[dest].Incoming.MeleeHits or 0) + 1
end
recap.Combatant[dest].Incoming.MeleeMax = math.max(damage,recap.Combatant[dest].Incoming.MeleeMax or 0)
if blocked then
recap.Combatant[dest].Incoming.MeleeBlocked = (recap.Combatant[dest].Incoming.MeleeBlocked or 0)+ 1
end
else
recap.Combatant[dest].Incoming.NonMeleeDamage = (recap.Combatant[dest].Incoming.NonMeleeDamage or 0) + damage
if recap_temp.Filter[i].crit==1 then
recap.Combatant[dest].Incoming.NonMeleeCrits = (recap.Combatant[dest].Incoming.NonMeleeCrits or 0) + 1
else
recap.Combatant[dest].Incoming.NonMeleeHits = (recap.Combatant[dest].Incoming.NonMeleeHits or 0) + 1
end
recap.Combatant[dest].Incoming.NonMeleeMax = math.max(damage,recap.Combatant[dest].Incoming.NonMeleeMax or 0)
end
Recap_CreateEffect(source,effect,1,damage,recap_temp.Filter[i].crit)
end
elseif recap_temp.Filter[i].miss and not recap.Opt.LightData.value then
if recap_temp.Filter[i].miss==9 and recap_temp.Filter[i].effect==7 then -- melee normal miss
recap.Combatant[dest].Incoming.MeleeMissed = (recap.Combatant[dest].Incoming.MeleeMissed or 0) + 1
elseif recap_temp.Filter[i].miss==9 then -- non-melee miss
recap.Combatant[dest].Incoming.NonMeleeMissed = (recap.Combatant[dest].Incoming.NonMeleeMissed or 0) + 1
elseif recap_temp.Filter[i].miss==10 then -- melee dodge
recap.Combatant[dest].Incoming.MeleeDodged = (recap.Combatant[dest].Incoming.MeleeDodged or 0) + 1
elseif recap_temp.Filter[i].miss==11 then -- melee parry
recap.Combatant[dest].Incoming.MeleeParried = (recap.Combatant[dest].Incoming.MeleeParried or 0) + 1
elseif recap_temp.Filter[i].miss==12 then -- melee block
recap.Combatant[dest].Incoming.MeleeBlocked = (recap.Combatant[dest].Incoming.MeleeBlocked or 0) + 1
end
Recap_CreateEffect(source,effect,1,0)
end
i=recap_temp.FilterSize+1
end
end
end
end
-- did_crit=1 for a crit, =0 for a normal hit but it could crit
-- total = amount of hit/heal, 0 for a miss
function Recap_CreateEffect(source,effect,type,total,did_crit)
effect = type..effect
-- skip misses that aren't a stored effect yet, to prevent logging debuff resists
if not (total==0 and not recap.Combatant[source].Detail[effect]) then
-- ChatFrame2:AddMessage("effect: "..effect..", source: "..source..", total: "..total..", did_crit: "..tostring(did_crit))
if not recap.Combatant[source].Detail[effect] then
recap.Combatant[source].Detail[effect] = {} -- Hits=0, HitsDmg=0, HitsMax=0, Crits=0, CritsEvents=0, CritsDmg=0, CritsMax=0, Missed=0, TicksDmg, TicksMax }
end
if source==recap_temp.Player and not recap.Self[recap_temp.s][effect] then
recap.Self[recap_temp.s][effect] = {}
end
if did_crit==1 then
recap.Combatant[source].Detail[effect].CritsEvents = (recap.Combatant[source].Detail[effect].CritsEvents or 0) + 1
recap.Combatant[source].Detail[effect].Crits = (recap.Combatant[source].Detail[effect].Crits or 0) + did_crit
recap.Combatant[source].Detail[effect].CritsDmg = (recap.Combatant[source].Detail[effect].CritsDmg or 0) + total
recap.Combatant[source].Detail[effect].CritsMax = math.max(total,recap.Combatant[source].Detail[effect].CritsMax or 0)
if source==recap_temp.Player then
recap.Self[recap_temp.s][effect].CritsEvents = (recap.Self[recap_temp.s][effect].CritsEvents or 0) + 1
recap.Self[recap_temp.s][effect].Crits = (recap.Self[recap_temp.s][effect].Crits or 0) + did_crit
recap.Self[recap_temp.s][effect].CritsDmg = (recap.Self[recap_temp.s][effect].CritsDmg or 0) + total
recap.Self[recap_temp.s][effect].CritsMax = math.max(total,recap.Self[recap_temp.s][effect].CritsMax or 0)
end
elseif did_crit==0 then
recap.Combatant[source].Detail[effect].CritsEvents = (recap.Combatant[source].Detail[effect].CritsEvents or 0) + 1
recap.Combatant[source].Detail[effect].Hits = (recap.Combatant[source].Detail[effect].Hits or 0) + 1
recap.Combatant[source].Detail[effect].HitsDmg = (recap.Combatant[source].Detail[effect].HitsDmg or 0) + total
recap.Combatant[source].Detail[effect].HitsMax = math.max(total,recap.Combatant[source].Detail[effect].HitsMax or 0)
if source==recap_temp.Player then
recap.Self[recap_temp.s][effect].CritsEvents = (recap.Self[recap_temp.s][effect].CritsEvents or 0) + 1
recap.Self[recap_temp.s][effect].Hits = (recap.Self[recap_temp.s][effect].Hits or 0) + 1
recap.Self[recap_temp.s][effect].HitsDmg = (recap.Self[recap_temp.s][effect].HitsDmg or 0) + total
recap.Self[recap_temp.s][effect].HitsMax = math.max(total,recap.Self[recap_temp.s][effect].HitsMax or 0)
end
elseif total==0 then
recap.Combatant[source].Detail[effect].Missed = (recap.Combatant[source].Detail[effect].Missed or 0) + 1
if source==recap_temp.Player then
recap.Self[recap_temp.s][effect].Missed = (recap.Self[recap_temp.s][effect].Missed or 0) + 1
end
else
recap.Combatant[source].Detail[effect].Hits = (recap.Combatant[source].Detail[effect].Hits or 0) + 1
recap.Combatant[source].Detail[effect].TicksDmg = (recap.Combatant[source].Detail[effect].TicksDmg or 0) + total
recap.Combatant[source].Detail[effect].TicksMax = math.max(total,recap.Combatant[source].Detail[effect].TicksMax or 0)
if source==recap_temp.Player then
recap.Self[recap_temp.s][effect].Hits = (recap.Self[recap_temp.s][effect].Hits or 0) + 1
recap.Self[recap_temp.s][effect].TicksDmg = (recap.Self[recap_temp.s][effect].TicksDmg or 0) + total
recap.Self[recap_temp.s][effect].TicksMax = math.max(total,recap.Self[recap_temp.s][effect].TicksMax or 0)
end
end
end
end
function Recap_DeathEvent(arg1)
local i, victim, spot
local found = false
if recap.Opt.State.value~="Stopped" then
for i=1,recap_temp.DeathFilterSize do
found,_,recap_temp.FilterIndex[1] = string.find(arg1,recap_temp.DeathFilter[i].pattern)
if found then
victim = recap_temp.FilterIndex[recap_temp.DeathFilter[i].victim]
-- check for FD
if recap.Combatant[victim] and recap.Combatant[victim].Class=="Hunter" then
if UnitName("player")==victim then
spot = "player"
end
for j=1,4 do
if UnitName("party"..j)==victim then
spot = "party"..j
end
end
for j=1,40 do
if UnitName("raid"..j)==victim then
spot = "raid"..j
end
end
if spot then
for j=1,16 do
if UnitBuff(spot,j)=="Interface\\Icons\\Ability_Rogue_FeignDeath" then
victim = nil
end
end
end
end
if victim and recap_temp.Last[victim] then
recap_temp.Last[victim].Kills = recap_temp.Last[victim].Kills + 1
end
if recap.debug then
if not recap.debug_Filter then
recap.debug_Filter = {}
end
if not recap.debug_Filter[i+60] then
recap.debug_Filter[i+60] = { hits=1, total=1, pattern=recap_temp.DeathFilter[i].pattern }
else
recap.debug_Filter[i+60].hits = recap.debug_Filter[i+60].hits + 1
recap.debug_Filter[i+60].total = recap.debug_Filter[i+60].total + 1
end
if recap_temp.Filter[i].watch then
DEFAULT_CHAT_FRAME:AddMessage("["..i.."] \""..recap_temp.DeathFilter[i].pattern.."\" triggered!")
DEFAULT_CHAT_FRAME:AddMessage("victim="..tostring(victim))
end
end
i = recap_temp.DeathFilterSize+1
end
end
end
end
function Recap_HealEvent(arg1)
local i, source, dest, heal, effect, fullheal
local found = false
if recap.Opt.State.value~="Stopped" then
-- strip out period at end of chat line, if one exists
arg1 = string.gsub(arg1,"%.$","")
for i=1,recap_temp.HealFilterSize do
found,_,recap_temp.FilterIndex[1],recap_temp.FilterIndex[2],recap_temp.FilterIndex[3],recap_temp.FilterIndex[4],recap_temp.FilterIndex[5] = string.find(arg1,recap_temp.HealFilter[i].pattern)
if found then
if not recap.Opt.LimitFights.value then
if recap.Opt.IdleFight.value then
recap_temp.IdleTimer = 0
end
if recap.Opt.State.value=="Idle" then
Recap_StartFight()
end
end
source=recap_temp.FilterIndex[recap_temp.HealFilter[i].source]
dest=recap_temp.FilterIndex[recap_temp.HealFilter[i].dest]
if recap_temp.Local.SelfPronouns[string.lower(dest)] then
dest = recap_temp.Player
end
heal=tonumber(recap_temp.FilterIndex[recap_temp.HealFilter[i].heal])
if recap_temp.HealFilter[i].effect then
effect = recap_temp.FilterIndex[recap_temp.HealFilter[i].effect]
end
Recap_CreateCombatant(source)
if recap_temp.Last[dest] and recap_temp.Last[dest].HP then
fullheal = heal
heal = math.min(recap_temp.Last[dest].MaxHP-recap_temp.Last[dest].HP,heal)
recap_temp.Last[dest].HP = recap_temp.Last[dest].HP + heal
if recap.debug and heal~=fullheal then
ChatFrame2:AddMessage("|cff3fbfff"..source.."'s "..effect.." actually healed "..dest.." for "..heal..". ("..fullheal.." reported)")
end
end
recap_temp.Last[source].Heal = recap_temp.Last[source].Heal + heal
if recap.debug then
if not recap.debug_Filter then
recap.debug_Filter = {}
end
if not recap.debug_Filter[i+75] then
recap.debug_Filter[i+75] = { hits=1, total=heal, pattern=recap_temp.HealFilter[i].pattern }
else
recap.debug_Filter[i+75].hits = recap.debug_Filter[i+75].hits + 1
recap.debug_Filter[i+75].total = recap.debug_Filter[i+75].total + heal
end
if recap_temp.Filter[i].watch then
DEFAULT_CHAT_FRAME:AddMessage("["..i.."] \""..recap_temp.HealFilter[i].pattern.."\" triggered!")
DEFAULT_CHAT_FRAME:AddMessage("source="..tostring(source)..", dest="..tostring(dest)..", heal="..tostring(heal))
end
end
if not recap.Opt.LightData.value then
Recap_CreateEffect(source,effect,3,heal,recap_temp.HealFilter[i].crit)
if fullheal and heal~=fullheal and recap.Combatant[source].Detail["3"..effect] then
-- reuse .Missed detail to store overhealing since heals never miss
recap.Combatant[source].Detail["3"..effect].Missed = (recap.Combatant[source].Detail["3"..effect].Missed or 0) + math.max(0,fullheal-heal)
end
end
i = recap_temp.HealFilterSize+1
end
end
end
end
local function Recap_SelfDamageSort(e1,e2)
local effect1,effect2 = string.sub(e1.EName,1,1),string.sub(e2.EName,1,1)
if e1 and e2 and ( ((e1.ETotal>e2.ETotal) and (effect1==effect2)) or (effect1<effect2) ) then
return true
else
return false
end
end
local function Recap_ConstructSelf()
local idx,i,j = 1
local damage, heal = 0,0
recap_temp.SelfListSize = 1
for i in recap.Self[recap_temp.s] do
if not recap_temp.SelfList[idx] then
recap_temp.SelfList[idx] = {}
end
recap_temp.SelfList[idx].EName = i
recap_temp.SelfList[idx].ETotal = (recap.Self[recap_temp.s][i].HitsDmg or 0) + (recap.Self[recap_temp.s][i].TicksDmg or 0) + (recap.Self[recap_temp.s][i].CritsDmg or 0)
recap_temp.SelfList[idx].EHits = (recap.Self[recap_temp.s][i].CritsEvents or 0)-(recap.Self[recap_temp.s][i].Crits or 0)
recap_temp.SelfList[idx].ETicks = (recap.Self[recap_temp.s][i].Hits or 0) - recap_temp.SelfList[idx].EHits
recap_temp.SelfList[idx].ECrits = recap.Self[recap_temp.s][i].Crits or 0
recap_temp.SelfList[idx].EHitsMax = recap.Self[recap_temp.s][i].HitsMax or 0
recap_temp.SelfList[idx].ETicksMax = recap.Self[recap_temp.s][i].TicksMax or 0
recap_temp.SelfList[idx].ECritsMax = recap.Self[recap_temp.s][i].CritsMax or 0
recap_temp.SelfList[idx].EHitsAvg = string.format("%d",((recap_temp.SelfList[idx].EHits>0) and ((recap.Self[recap_temp.s][i].HitsDmg or 0)/recap_temp.SelfList[idx].EHits) or 0))
recap_temp.SelfList[idx].ETicksAvg = string.format("%d",((recap_temp.SelfList[idx].ETicks>0) and ((recap.Self[recap_temp.s][i].TicksDmg or 0)/recap_temp.SelfList[idx].ETicks) or 0))
recap_temp.SelfList[idx].ECritsAvg = string.format("%d",((recap_temp.SelfList[idx].ECrits>0) and ((recap.Self[recap_temp.s][i].CritsDmg or 0)/recap_temp.SelfList[idx].ECrits) or 0))
recap_temp.SelfList[idx].ECritsP = string.format("%.1f%%",((recap.Self[recap_temp.s][i].CritsEvents or 0)>0) and (100*recap_temp.SelfList[idx].ECrits/recap.Self[recap_temp.s][i].CritsEvents) or 0)
recap_temp.SelfList[idx].EMaxAll = math.max( recap_temp.SelfList[idx].EHitsMax, math.max(recap_temp.SelfList[idx].ETicksMax,recap_temp.SelfList[idx].ECritsMax) )
if tonumber(string.sub(i,1,1))<3 then -- damage event
recap_temp.SelfList[idx].EMiss = recap.Self[recap_temp.s][i].Missed or 0
j = recap_temp.SelfList[idx].EHits + recap_temp.SelfList[idx].ECrits + recap_temp.SelfList[idx].EMiss
recap_temp.SelfList[idx].EMissP = string.format("%.1f%%",(j>0) and (100*(recap_temp.SelfList[idx].EMiss/j)) or 0)
damage = damage + recap_temp.SelfList[idx].ETotal
else
recap_temp.SelfList[idx].EMiss = "--"
recap_temp.SelfList[idx].EMissP = "--"
heal = heal + recap_temp.SelfList[idx].ETotal
end
if recap_temp.SelfList[idx].ETicks==0 then
recap_temp.SelfList[idx].ETicks = "--"
recap_temp.SelfList[idx].ETicksAvg = "--"
recap_temp.SelfList[idx].ETicksMax = "--"
end
if not recap.Self[recap_temp.s][i].CritsEvents then
recap_temp.SelfList[idx].ECrits = "--"
recap_temp.SelfList[idx].ECritsAvg = "--"
recap_temp.SelfList[idx].ECritsMax = "--"
recap_temp.SelfList[idx].ECritsP = "--"
recap_temp.SelfList[idx].EHits = "--"
recap_temp.SelfList[idx].EHitsAvg = "--"
recap_temp.SelfList[idx].EHitsMax = "--"
end
idx = idx + 1
end
recap_temp.SelfListSize = idx
if recap_temp.SelfListSize>1 then
for i=1,recap_temp.SelfListSize-1 do
if string.sub(recap_temp.SelfList[i].EName,1,1)<"3" and damage>0 then
recap_temp.SelfList[i].ETotalP = string.format("%d%%",100*recap_temp.SelfList[i].ETotal/damage)
elseif string.sub(recap_temp.SelfList[i].EName,1,1)>"2" and heal>0 then
recap_temp.SelfList[i].ETotalP = string.format("%d%%",100*recap_temp.SelfList[i].ETotal/heal)
else
recap_temp.SelfList[i].ETotalP = "--"
end
end
end
table.sort(recap_temp.SelfList,Recap_SelfDamageSort)
end
function Recap_ConstructList()
local i, j, dpsin, dpsout, entry, duration, tempname, over
local maxhit = 0
local dmgin = 0
local dmgout = 0
local kills = 0
local heal = 0
local allover = 0
if recap.Opt.SelfView.value then
Recap_ConstructSelf()
end
recap_temp.ListSize = 1
if recap_temp.Selected~=0 then
tempname = recap_temp.List[recap_temp.Selected].Name
end
if recap.Opt.View.value=="Last" then
duration = recap[recap_temp.p].LastDuration
else
duration = recap[recap_temp.p].TotalDuration
end
for i in recap.Combatant do
if not recap_temp.List[recap_temp.ListSize] then
recap_temp.List[recap_temp.ListSize] = {}
end
entry = false
if (recap.Combatant[i].LastDmgIn==0 and recap.Combatant[i].LastDmgOut==0 and
recap.Combatant[i].TotalDmgOut==0 and recap.Combatant[i].TotalDmgIn==0) or
(recap.Opt.HideFoe.value and not recap.Combatant[i].Friend) or
(recap.Opt.HideYardTrash.value and (not recap.Combatant[i].Friend and recap.Combatant[i].TotalKills~=1)) or
(recap.Combatant[i].Ignore) then
entry = false -- strip out unwanted combatants
elseif recap.Opt.View.value=="Last" and recap.Combatant[i].WasInLast then
if not recap.Opt.HideZero.value or recap.Combatant[i].LastTime>recap_temp.MinTime then
recap_temp.List[recap_temp.ListSize].Name = i
recap_temp.List[recap_temp.ListSize].Time = recap.Combatant[i].LastTime
recap_temp.List[recap_temp.ListSize].MaxHit = recap.Combatant[i].LastMaxHit
recap_temp.List[recap_temp.ListSize].DmgIn = recap.Combatant[i].LastDmgIn
recap_temp.List[recap_temp.ListSize].DmgOut = recap.Combatant[i].LastDmgOut
recap_temp.List[recap_temp.ListSize].DPS = recap.Combatant[i].LastDPS
recap_temp.List[recap_temp.ListSize].DPSvsAll = duration>recap_temp.MinTime and recap.Combatant[i].LastDmgOut/duration or 0
recap_temp.List[recap_temp.ListSize].Kills = recap.Combatant[i].LastKills
recap_temp.List[recap_temp.ListSize].Heal = recap.Combatant[i].LastHeal
entry = true
end
elseif recap.Opt.View.value=="All" then
if not recap.Opt.HideZero.value or recap.Combatant[i].TotalTime>recap_temp.MinTime then
recap_temp.List[recap_temp.ListSize].Name = i
recap_temp.List[recap_temp.ListSize].Time = recap.Combatant[i].TotalTime
recap_temp.List[recap_temp.ListSize].MaxHit = recap.Combatant[i].TotalMaxHit
recap_temp.List[recap_temp.ListSize].DmgIn = recap.Combatant[i].TotalDmgIn
recap_temp.List[recap_temp.ListSize].DmgOut = recap.Combatant[i].TotalDmgOut
recap_temp.List[recap_temp.ListSize].DPS = recap.Combatant[i].TotalDPS
recap_temp.List[recap_temp.ListSize].DPSvsAll = duration>recap_temp.MinTime and recap.Combatant[i].TotalDmgOut/duration or 0
recap_temp.List[recap_temp.ListSize].Kills = recap.Combatant[i].TotalKills
recap_temp.List[recap_temp.ListSize].Heal = recap.Combatant[i].TotalHeal
entry = true
end
end
if entry then
recap_temp.List[recap_temp.ListSize].Over = 0 -- overhealing
if recap.Combatant[recap_temp.List[recap_temp.ListSize].Name].Friend then
if recap_temp.List[recap_temp.ListSize].MaxHit > maxhit then
maxhit = recap_temp.List[recap_temp.ListSize].MaxHit
end
dmgin = dmgin + recap_temp.List[recap_temp.ListSize].DmgIn
dmgout = dmgout + recap_temp.List[recap_temp.ListSize].DmgOut
kills = kills + recap_temp.List[recap_temp.ListSize].Kills
heal = heal + recap_temp.List[recap_temp.ListSize].Heal
if (recap_temp.List[recap_temp.ListSize].Heal>0) and not recap.Opt.LightData.value then
over = 0
for j in recap.Combatant[i].Detail do
if string.sub(j,1,1)=="3" then -- a heal
over = over + (recap.Combatant[i].Detail[j].Missed or 0)
end
end
recap_temp.List[recap_temp.ListSize].Over = math.floor(((100*over)/(over+recap.Combatant[i].TotalHeal))+.5)
allover = allover + over
end
end
recap_temp.ListSize = recap_temp.ListSize + 1
end
end
if not recap_temp.List[recap_temp.ListSize] then
recap_temp.List[recap_temp.ListSize] = {}
end
-- the final entry is the totals
recap_temp.List[recap_temp.ListSize].Name = "Totals"
recap_temp.List[recap_temp.ListSize].Time = duration
RecapTotals_Time:SetText(Recap_FormatTime(duration))
recap_temp.List[recap_temp.ListSize].MaxHit = maxhit
RecapTotals_MaxHit:SetText(maxhit)
recap_temp.List[recap_temp.ListSize].DmgIn = dmgin
RecapTotals_DmgIn:SetText(dmgin)
recap_temp.List[recap_temp.ListSize].DmgOut = dmgout
RecapTotals_DmgOut:SetText(dmgout)
recap_temp.List[recap_temp.ListSize].Kills = kills
RecapTotals_Kills:SetText(kills)
recap_temp.List[recap_temp.ListSize].Heal = heal
RecapTotals_Heal:SetText(heal)
recap_temp.List[recap_temp.ListSize].Over = recap.Opt.View.value=="All" and ((100*allover)/(allover+heal)) or 0
RecapTotals_Over:SetText(string.format("%d%%",recap_temp.List[recap_temp.ListSize].Over))
if duration > recap_temp.MinTime then
recap_temp.List[recap_temp.ListSize].DPSIn = dmgin/duration
recap_temp.List[recap_temp.ListSize].DPSOut = dmgout/duration
else
recap_temp.List[recap_temp.ListSize].DPSIn = 0
recap_temp.List[recap_temp.ListSize].DPSOut = 0
end
RecapTotals_DPS:SetText(string.format("%.1f",recap_temp.List[recap_temp.ListSize].DPSOut))
RecapTotals_DPSvsAll:SetText(string.format("%.1f",recap_temp.List[recap_temp.ListSize].DPSOut))
RecapTotals_DPSIn:SetText(string.format("%.1f",recap_temp.List[recap_temp.ListSize].DPSIn))
RecapMinDPSIn_Text:SetText(string.format("%.1f",recap_temp.List[recap_temp.ListSize].DPSIn))
RecapMinDPSOut_Text:SetText(string.format("%.1f",recap_temp.List[recap_temp.ListSize].DPSOut))
if recap.Combatant[recap_temp.Player] and recap.Opt.View.value=="Last" then
i = recap.Combatant[recap_temp.Player].LastDPS
if UnitName("pet") and UnitName("pet")~=UNKNOWNOBJECT and recap.Combatant[UnitName("pet")] then
i = i + recap.Combatant[UnitName("pet")].LastDPS
end
RecapMinYourDPS_Text:SetText(string.format("%.1f",i))
elseif recap.Combatant[recap_temp.Player] and recap.Opt.View.value=="All" then
i = recap.Combatant[recap_temp.Player].TotalDPS
if UnitName("pet") and UnitName("pet")~=UNKNOWNOBJECT and recap.Combatant[UnitName("pet")] then
i = i + recap.Combatant[UnitName("pet")].TotalDPS
end
RecapMinYourDPS_Text:SetText(string.format("%.1f",i))
else
RecapMinYourDPS_Text:SetText("n/a")
end
-- calculate percentages
for i=1,recap_temp.ListSize-1 do
recap_temp.List[i].HealP = 0
recap_temp.List[i].DmgInP = 0
recap_temp.List[i].DmgOutP = 0
if recap.Combatant[recap_temp.List[i].Name].Friend then
if recap_temp.List[recap_temp.ListSize].Heal>0 then
recap_temp.List[i].HealP = math.floor(.5+100*recap_temp.List[i].Heal/recap_temp.List[recap_temp.ListSize].Heal)
end
if recap_temp.List[recap_temp.ListSize].DmgIn>0 then
recap_temp.List[i].DmgInP = math.floor(.5+100*recap_temp.List[i].DmgIn/recap_temp.List[recap_temp.ListSize].DmgIn)
end
if recap_temp.List[recap_temp.ListSize].DmgOut>0 then
recap_temp.List[i].DmgOutP = math.floor(.5+100*recap_temp.List[i].DmgOut/recap_temp.List[recap_temp.ListSize].DmgOut)
end
end
end
Recap_SortList()
if tempname then -- follow name to pre-sort selected
recap_temp.Selected = Recap_GetSelectedByName(tempname)
if recap_temp.Selected~=0 then
RecapPanel_Show(tempname)
else
RecapPanel_Hide()
end
end
RecapScrollBar_Update()
Recap_UpdatePlugins()
end
function Recap_DefineGauges()
local i
recap_temp.GaugeMax = 0
if recap_temp.ListSize>1 then
recap_temp.GaugeBy = string.gsub(recap.Opt.SortBy.value,"P$","")
recap_temp.GaugeBy = recap_temp.GaugeBy=="DPSvsAll" and "DmgOut" or recap_temp.GaugeBy
if not gaugecolor[recap_temp.GaugeBy] then
recap_temp.GaugeBy = nil
else
for i=1,recap_temp.ListSize-1 do
recap_temp.GaugeMax = math.max(recap.Combatant[recap_temp.List[i].Name].Friend and recap_temp.List[i][recap_temp.GaugeBy] or 0,recap_temp.GaugeMax)
end
for i=1,15 do
getglobal("RecapList"..i.."_Gauge"):SetVertexColor(gaugecolor[recap_temp.GaugeBy].r,gaugecolor[recap_temp.GaugeBy].g,gaugecolor[recap_temp.GaugeBy].b)
end
end
end
end
function Recap_GetSelectedByName(arg1)
local sel,i = 0
if arg1 and recap_temp.ListSize>1 then
for i=1,recap_temp.ListSize-1 do
if recap_temp.List[i].Name==arg1 then
sel = i
end
end
end
return sel
end
--[[ Sorting functions ]]
-- initial sort by field done with table.sort for speed, then
-- friends shifted to top with an insertion sort for "stable" list
function Recap_SortList()
local temp,tempname
if recap_temp.Selected~=0 then
tempname = recap_temp.List[recap_temp.Selected].Name
end
temp = recap_temp.List[recap_temp.ListSize]
recap_temp.List[recap_temp.ListSize] = nil
if recap.Opt.SortDir.value then
table.sort(recap_temp.List,function(e1,e2) if e1 and e2 and ( e1[recap.Opt.SortBy.value] < e2[recap.Opt.SortBy.value] ) then return true else return false end end)
else
table.sort(recap_temp.List,function(e1,e2) if e1 and e2 and ( e1[recap.Opt.SortBy.value] > e2[recap.Opt.SortBy.value] ) then return true else return false end end)
end
Recap_SortFriends()
recap_temp.List[recap_temp.ListSize] = temp
Recap_DefineGauges()
recap_temp.Selected = Recap_GetSelectedByName(tempname)
end
function Recap_SortDown(e1,e2)
if e1 and e2 and ( e1[recap.Opt.SortBy.value] < e2[recap.Opt.SortBy.value] ) then
return true
else
return false
end
end
function Recap_SortUp(e1,e2)
if e1 and e2 and ( e1[recap.Opt.SortBy.value] > e2[recap.Opt.SortBy.value] ) then
return true
else
return false
end
end
-- perform stable insertion sort on the list
function Recap_SortFriends()
local i,j
local changed = true
local temp = {}
if recap_temp.ListSize>2 then
for i=2,(recap_temp.ListSize-1) do
temp = recap_temp.List[i]
j=i
while (j>1) and (not recap.Combatant[recap_temp.List[j-1].Name].Friend and recap.Combatant[temp.Name].Friend) do
recap_temp.List[j] = recap_temp.List[j-1]
j = j - 1
end
recap_temp.List[j] = temp
end
end
end
--[[ Window movement functions ]]
function Recap_OnMouseDown(arg1)
if recap_temp.Loaded and arg1=="LeftButton" and not recap.Opt.Pinned.value then
RecapFrame:StartMoving()
end
end
function Recap_OnMouseUp(arg1)
if recap_temp.Loaded and arg1=="LeftButton" and not recap.Opt.Pinned.value then
RecapFrame:StopMovingOrSizing()
Recap_CheckWindowBounds()
elseif arg1=="RightButton" and recap.Opt.Minimized.value then
RecapCreateMenu(recap_temp.MinMenu)
end
end
-- repositions RecapFrame if any part of it goes off the screen
function Recap_CheckWindowBounds()
local x1, y1, x2, y2, cx, cy
local needs_moved = false
if recap_temp.Loaded and RecapFrame then
x1 = RecapFrame:GetLeft()
y1 = RecapFrame:GetTop()
cx = RecapFrame:GetWidth()
cy = RecapFrame:GetHeight()
if x1 and y1 and cx and cy then
x2 = RecapFrame:GetRight()
y2 = RecapFrame:GetBottom()
uix2 = UIParent:GetRight()
uix1 = UIParent:GetLeft()
uiy1 = UIParent:GetTop()
uiy2 = UIParent:GetBottom()
if x2 and uix2 and x2 > uix2 then
x1 = x1 + uix2 - x2
needs_moved = true
elseif uix1 and uix1 > x1 then
x1 = x1 + uix1 - x1
needs_moved = true
end
if y1 and y1 > uiy1 then
y1 = y1 + uiy1 - y1
needs_moved = true
elseif uiy2 and uiy2 > y2 then
y1 = y1 + uiy2 - y2
needs_moved = true
end
if needs_moved then
RecapFrame:ClearAllPoints()
RecapFrame:SetPoint("TOPLEFT","UIParent","BOTTOMLEFT",x1,y1)
end
recap[recap_temp.p].WindowTop = RecapFrame:GetTop()
recap[recap_temp.p].WindowLeft = RecapFrame:GetLeft()
recap[recap_temp.p].WindowHeight = RecapFrame:GetHeight()
recap[recap_temp.p].WindowWidth = RecapFrame:GetWidth()
end
end
end
--[[ Dialog control functions ]]
function Recap_OnClick(arg1)
if not recap_temp.Loaded then
return
end
local fight_count = 0
local total_fight_count = 0
local filen = RecapSetEditBox:GetText()
local set_friend, set_dmgin, set_dmgout, set_maxhit, set_kills, set_heal, set_time
PlaySound("GAMEGENERICBUTTONPRESS")
if arg1=="Close" then
RecapFrame_Hide()
elseif arg1=="Minimize" then
if recap.Opt.Minimized.value then
Recap_Maximize()
else
Recap_Minimize()
end
RecapFrame:SetAlpha(1)
recap_temp.FadeTimer = -1
Recap_SetButtons()
Recap_OnTooltip("Minimize")
elseif arg1=="Pin" then
recap.Opt.Pinned.value = not recap.Opt.Pinned.value
Recap_SetButtons()
Recap_OnTooltip("Pin")
elseif arg1=="Pause" then
if recap.Opt.Paused.value then
recap.Opt.Paused.value = false
Recap_SetState("Idle")
else
recap.Opt.Paused.value = true
Recap_EndFight()
Recap_SetState("Stopped")
end
Recap_SetButtons()
Recap_OnTooltip("Pause")
elseif arg1=="ShowAll" then
if recap.Opt.SelfView.value then
recap.Opt.SelfView.value = false
if not recap.Opt.Minimized.value then
Recap_SetColumns()
end
end
if recap.Opt.View.value=="Last" then
Recap_SetView("All")
else
Recap_SetView("Last")
end
Recap_OnTooltip("ShowAll")
elseif arg1=="Options" then
if RecapOptFrame:IsShown() then
RecapOptFrame:Hide()
else
RecapOptFrame:Show()
end
elseif arg1=="Reset" then
if recap.Opt.SelfView.value then
recap.Self[recap_temp.s] = {}
Recap_SetView()
elseif recap.Opt.View.value=="All" then
-- wipe everything --
Recap_ResetAllCombatants()
Recap_SetView()
Recap_MakeFriends()
elseif recap.Opt.View.value=="Last" then
-- remove just the last fight --
for i in recap.Combatant do
if recap.Combatant[i].WasInLast then
Recap_ResetLastFight(i)
end
end
recap[recap_temp.p].TotalDuration = recap[recap_temp.p].TotalDuration - recap[recap_temp.p].LastDuration
recap[recap_temp.p].LastDuration = 0
Recap_SetView()
end
elseif arg1=="SaveSet" then
RecapSetEditBox:ClearFocus()
if filen and filen~="" then
filen = string.gsub(filen,"\"","'") -- convert "s to 's
filen = string.gsub(filen,"%[","(") -- convert [s to (s
filen = string.gsub(filen,"%]",")") -- convert ]s to )s
end
RecapSetEditBox:SetText("")
Recap_SaveCombatants(filen,recap.Opt.ReplaceSet.value)
Recap_BuildFightSets()
recap_temp.FightSetSelected = 0
RecapFightSetsScrollBar_Update()
elseif arg1=="LoadSet" then
RecapSetEditBox:SetText("")
RecapSetEditBox:ClearFocus()
Recap_LoadCombatants(filen,recap.Opt.ReplaceSet.value)
Recap_MakeFriends()
Recap_SetView("All")
elseif arg1=="DeleteSet" then
RecapSetEditBox:SetText("")
RecapSetEditBox:ClearFocus()
recap_set[filen] = nil
Recap_BuildFightSets()
elseif arg1=="SelfView" then
recap.Opt.SelfView.value = not recap.Opt.SelfView.value
RecapPanel_Hide(1)
Recap_SetColumns()
Recap_OnTooltip("SelfView")
end
end
-- removes combatant i from last fight
function Recap_ResetLastFight(i)
recap.Combatant[i].TotalTime = recap.Combatant[i].TotalTime - recap.Combatant[i].LastTime
recap.Combatant[i].TotalDmgIn = recap.Combatant[i].TotalDmgIn - recap.Combatant[i].LastDmgIn
recap.Combatant[i].TotalDmgOut = recap.Combatant[i].TotalDmgOut - recap.Combatant[i].LastDmgOut
recap.Combatant[i].TotalHeal = recap.Combatant[i].TotalHeal - recap.Combatant[i].LastHeal
recap.Combatant[i].TotalKills = recap.Combatant[i].TotalKills - recap.Combatant[i].LastKills
if recap.Combatant[i].TotalTime> recap_temp.MinTime then
recap.Combatant[i].TotalDPS = recap.Combatant[i].TotalDmgOut/recap.Combatant[i].TotalTime
else
recap.Combatant[i].TotalDPS = 0
end
recap.Combatant[i].WasInLast = false
recap.Combatant[i].LastTime = 0
recap.Combatant[i].LastDmgIn = 0
recap.Combatant[i].LastDmgOut = 0
recap.Combatant[i].LastDPS = 0
recap.Combatant[i].LastMaxHit = 0
recap.Combatant[i].LastKills = 0
recap.Combatant[i].LastHeal = 0
end
function RecapHeader_OnEnter()
local msg=string.gsub(this:GetName(),"RecapHeader_","Header")
Recap_OnTooltip(msg)
end
function RecapHeader_OnMouseUp(arg1)
if arg1=="RightButton" then
RecapCreateMenu(recap_temp.ColumnMenu)
end
end
-- sort column, toggle dir for new headers, name=ascending, rest=descending
function RecapHeader_OnClick()
local text=""
local channel = "" -- "Guild" "Say" etc or "Channel"
local chatnumber = 0 -- if channel is "Channel", this is the channel numbers
local arg1= string.gsub(this:GetName(),"RecapHeader_","")
if not IsShiftKeyDown() then
if recap.Opt.SortBy.value==string.gsub(arg1,"P$","") then
recap.Opt.SortDir.value = not recap.Opt.SortDir.value
else
recap.Opt.SortBy.value = string.gsub(arg1,"P$","")
if arg1=="Name" then
recap.Opt.SortDir.value = true
else
recap.Opt.SortDir.value = false
end
end
Recap_SortList()
RecapScrollBar_Update()
elseif ChatFrameEditBox:IsVisible() and recap_temp.ListSize>1 and arg1~="Name" then
recap.Opt.SortBy.value = arg1
recap.Opt.SortDir.value = false
Recap_SortList()
RecapScrollBar_Update()
if recap.Opt.SpamRows.value then
channel = ChatFrameEditBox.chatType
chatnumber = nil
if channel=="WHISPER" then
chatnumber = ChatFrameEditBox.tellTarget
elseif channel=="CHANNEL" then
chatnumber = ChatFrameEditBox.channelTarget
end
Recap_PostSpamRows(arg1,channel,chatnumber)
else
Recap_InsertChat(Recap_PostSpamLine(arg1))
end
elseif not ChatFrameEditBox:IsVisible() then
DEFAULT_CHAT_FRAME:AddMessage(recap_temp.Local.RankUsage)
end
end
function Recap_List_OnClick(arg1)
local id, index
local text = ""
id = this:GetID()
index = id + FauxScrollFrame_GetOffset(RecapScrollBar)
if index<recap_temp.ListSize then
recap_temp.DetailSelected = 0
if recap_temp.Selected==index and arg1=="LeftButton" then
recap_temp.Selected = 0
getglobal("RecapList"..id):UnlockHighlight()
RecapPanel_Hide()
else
recap_temp.Selected = index
RecapScrollBar_Update()
RecapPanel_Show(recap_temp.List[index].Name)
end
end
if arg1=="RightButton" and index<recap_temp.ListSize and IsShiftKeyDown() and ChatFrameEditBox:IsVisible() then
ChatFrameEditBox:Insert(recap_temp.List[index].Name.." "..getglobal("RecapList"..id.."_DPS"):GetText().." DPS ")
elseif arg1=="LeftButton" and index<recap_temp.ListSize and IsShiftKeyDown() and ChatFrameEditBox:IsVisible() then
ChatFrameEditBox:Insert(string.format(recap_temp.Local.VerboseLinkStart,
recap_temp.List[index].Name,
getglobal("RecapList"..id.."_DmgIn"):GetText(),
getglobal("RecapList"..id.."_DmgOut"):GetText(),
getglobal("RecapList"..id.."_Time"):GetText(),
getglobal("RecapList"..id.."_DPS"):GetText(),
getglobal("RecapList"..id.."_MaxHit"):GetText() ).." for "..
recap_temp.Local.LastAll[recap.Opt.View.value])
elseif arg1=="RightButton" and index<recap_temp.ListSize and not IsShiftKeyDown() then
if recap.Combatant[recap_temp.List[index].Name].Friend then
RecapCreateMenu(recap_temp.DropMenu,1)
else
RecapCreateMenu(recap_temp.AddMenu,1)
end
end
end
--[[ Tooltip functions ]]
function Recap_Tooltip(arg1,arg2)
if recap_temp.Loaded and recap.Opt.ShowTooltips.value then
if not recap.Opt.TooltipFollow.value then
GameTooltip_SetDefaultAnchor(GameTooltip,this)
else
GameTooltip:SetOwner(this,Recap_TooltipAnchor())
end
GameTooltip:SetText(arg1)
GameTooltip:AddLine(arg2, .75, .75, .75, 1)
GameTooltip:Show()
end
end
-- returns line1,line2 of a tooltip for arg1 in OptList (for generic static tooltips)
function Recap_GetTooltip(arg1)
local i
if arg1 then
for i in recap_temp.OptList do
if recap_temp.OptList[i][1]==arg1 then
return recap_temp.OptList[i][2],recap_temp.OptList[i][3]
end
end
end
end
-- arg1=tooltip index, arg2=optional addition to header
function Recap_OnTooltip(arg1,arg2)
local line1, line2
if arg1=="Status" then
Recap_Tooltip("Recap Status: "..recap.Opt.State.value,recap_temp.Local.StatusTooltip)
elseif arg1=="Close" then
if recap.Opt.State.value=="Stopped" then
Recap_OnTooltip("ExitRecap")
else
Recap_OnTooltip("HideWindow")
end
elseif arg1=="Minimize" then
if recap.Opt.Minimized.value then
Recap_OnTooltip("ExpandWindow")
else
Recap_OnTooltip("MinimizeWindow")
end
elseif arg1=="Pin" then
if recap.Opt.Pinned.value then
Recap_OnTooltip("UnPinWindow")
else
Recap_OnTooltip("PinWindow")
end
elseif arg1=="Pause" then
if recap.Opt.State.value=="Stopped" then
Recap_OnTooltip("Resume")
else
Recap_OnTooltip("PauseMonitoring")
end
elseif arg1=="ShowAll" then
if recap.Opt.View.value=="Last" then
Recap_OnTooltip("ShowAllFights")
else
Recap_OnTooltip("ShowLastFight")
end
elseif arg1=="HeaderName" then
if recap.Opt.View.value=="Last" then
Recap_OnTooltip("CombatLast")
else
Recap_OnTooltip("CombatAll")
end
elseif arg1=="Reset" then
if recap.Opt.SelfView.value then
Recap_OnTooltip("ResetSelfView")
elseif recap.Opt.View.value=="Last" then
Recap_OnTooltip("ResetLastFight")
else
Recap_OnTooltip("ResetAllTotals")
end
elseif arg1=="SelfView" then
if recap.Opt.SelfView.value then
Recap_OnTooltip("HideSelfView")
else
Recap_OnTooltip("ShowSelfView")
end
else
line1,line2 = Recap_GetTooltip(arg1)
if line1 and line2 then
if arg2 then
Recap_Tooltip(line1..": "..arg2,line2)
else
Recap_Tooltip(line1, line2)
end
end
end
end
function Recap_List_OnEnter()
local index, id
id = this:GetID()
index = id + FauxScrollFrame_GetOffset(RecapScrollBar)
if getglobal("RecapList"..id.."_Name"):GetStringWidth()>110 then
Recap_Tooltip(recap_temp.List[index].Name)
end
if (index<recap_temp.ListSize) and recap_temp.Selected==0 then
RecapPanel_Show(recap_temp.List[index].Name)
end
end
function Recap_Totals_OnEnter()
local r = recap_temp.ColorWhite.r
local g = recap_temp.ColorWhite.g
local b = recap_temp.ColorWhite.b
local other_kills = 0
if recap.Opt.ShowTooltips.value then
if recap.Opt.TooltipFollow.value then
GameTooltip:SetOwner(this,Recap_TooltipAnchor())
else
GameTooltip_SetDefaultAnchor(GameTooltip,this)
end
GameTooltip:AddLine("Totals for "..recap_temp.Local.LastAll[recap.Opt.View.value])
if recap_temp.ListSize>1 then
for i=1,(recap_temp.ListSize-1) do
if not recap.Combatant[recap_temp.List[i].Name].Friend then
other_kills = other_kills + recap_temp.List[i].Kills
end
end
GameTooltip:AddDoubleLine("Combatants:",recap_temp.ListSize-1,r,g,b,r,g,b)
GameTooltip:AddDoubleLine("Time Fighting:",Recap_FormatTime(recap_temp.List[recap_temp.ListSize].Time),r,g,b,r,g,b)
GameTooltip:AddDoubleLine("Max Hit:",recap_temp.List[recap_temp.ListSize].MaxHit,r,g,b,r,g,b)
GameTooltip:AddDoubleLine("Deaths:",recap_temp.List[recap_temp.ListSize].Kills,r,g,b,r,g,b)
GameTooltip:AddDoubleLine("Kills:",other_kills,r,g,b,r,g,b)
GameTooltip:AddDoubleLine("Heals:",recap_temp.List[recap_temp.ListSize].Heal,r,g,b,r,g,b)
GameTooltip:AddDoubleLine("Damage In:",recap_temp.List[recap_temp.ListSize].DmgIn,recap_temp.ColorDmgIn.r,recap_temp.ColorDmgIn.g,recap_temp.ColorDmgIn.b,recap_temp.ColorDmgIn.r,recap_temp.ColorDmgIn.g,recap_temp.ColorDmgIn.b)
GameTooltip:AddDoubleLine("DPS In:",string.format("%.1f",recap_temp.List[recap_temp.ListSize].DPSIn),recap_temp.ColorDmgIn.r,recap_temp.ColorDmgIn.g,recap_temp.ColorDmgIn.b,recap_temp.ColorDmgIn.r,recap_temp.ColorDmgIn.g,recap_temp.ColorDmgIn.b)
GameTooltip:AddDoubleLine("Damage Out:",recap_temp.List[recap_temp.ListSize].DmgOut,recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b,recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
GameTooltip:AddDoubleLine("DPS Out:",string.format("%.1f",recap_temp.List[recap_temp.ListSize].DPSOut),recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b,recap_temp.ColorDmgOut.r,recap_temp.ColorDmgOut.g,recap_temp.ColorDmgOut.b)
else
GameTooltip:AddLine("Combatants: none",r,g,b)
end
GameTooltip:Show()
end
end
function Recap_TooltipAnchor()
local anchor = "ANCHOR_LEFT"
if GetCursorPosition("UIParent")<(UIParent:GetWidth()/2) then
anchor = "ANCHOR_RIGHT"
end
return anchor
end
--[[ Plug-in functions ]]
function Recap_GetIB_Tooltip()
return recap_temp.Local.LastAll[recap.Opt.View.value]..":\nYour DPS: "..RecapMinYourDPS_Text:GetText().."\nMax hit: "..RecapTotals_MaxHit:GetText().."\nTotal DPS Out: "..RecapTotals_DPS:GetText().."\nTotal DPS In: "..RecapTotals_DPSIn:GetText()
end
function Recap_UpdatePlugins()
local yourdps = RecapMinYourDPS_Text:GetText()
local dpsin = RecapMinDPSIn_Text:GetText()
local dpsout = RecapMinDPSOut_Text:GetText()
if IB_Recap_Update then
IB_Recap_Update("DPS: "..yourdps)
end
if TitanPanelRecap_Update then
TitanPanelRecap_Update(recap.Opt.State.value,yourdps,dpsin,dpsout)
end
end
--[[ Misc functions ]]
-- if this is a pet, pass owner's name to ownedby
function Recap_AddFriend(arg1,ownedby)
if arg1 and arg~=UNKNOWNOBJECT and recap.Combatant[arg1] then
recap.Combatant[arg1].Friend = true
if recap.Combatant[arg1] and ownedby then
-- pet could potentially do damage without owner, add owner if so
if not recap.Combatant[ownedby] then
Recap_CreateBlankCombatant(ownedby)
recap.Combatant[ownedby].Friend = true
end
if not recap_temp.Last[ownedby] then
recap_temp.Last[ownedby] = { Start = 0, End = 0, DmgIn = 0, DmgOut = 0, MaxHit = 0, Kills = 0, Heal = 0 }
end
recap.Combatant[arg1].OwnedBy = ownedby
recap.Combatant[ownedby].OwnsPet = arg1
end
end
end
function Recap_MakeFriends()
local i,item,u
Recap_GetUnitInfo("player")
Recap_AddFriend(recap_temp.Player)
if UnitExists("pet") then
Recap_GetUnitInfo("pet")
Recap_AddFriend(UnitName("pet"),UnitName("player"))
end
for i=1,4 do
if UnitExists("party"..i) then
Recap_GetUnitInfo("party"..i)
Recap_AddFriend(UnitName("party"..i))
if UnitExists("partypet"..i) then
Recap_GetUnitInfo("partypet"..i)
Recap_AddFriend(UnitName("partypet"..i),UnitName("party"..i))
end
end
end
if (GetNumRaidMembers()>0) then
for i=1,40 do
if UnitExists("raid"..i) then
Recap_GetUnitInfo("raid"..i)
Recap_AddFriend(UnitName("raid"..i))
if UnitExists("raidpet"..i) then
Recap_GetUnitInfo("raidpet"..i)
Recap_AddFriend(UnitName("raidpet"..i),UnitName("raid"..i))
end
end
end
end
end
-- returns a string of seconds converted to 0:00:00 format
function Recap_FormatTime(arg1)
local hours, minutes, seconds
local text
seconds = math.floor(arg1+.5)
hours = math.floor(seconds/3600)
seconds = seconds - hours*3600
minutes = math.floor(seconds/60)
seconds = seconds - minutes*60
return ((hours>0) and (hours..":") or "") .. string.format("%02d:",minutes) .. string.format("%02d",seconds)
end
function Recap_SetClassIcon(id,class)
if class and recap_temp.ClassIcons[class] then
getglobal("RecapList"..id.."_Class"):SetTexCoord(recap_temp.ClassIcons[class].left,recap_temp.ClassIcons[class].right,recap_temp.ClassIcons[class].top,recap_temp.ClassIcons[class].bottom)
else
getglobal("RecapList"..id.."_Class"):SetTexCoord(.9,1,.9,1)
end
end
function Recap_SetFactionIcon(id,faction)
item = getglobal("RecapList"..id.."_Faction")
if faction and recap_temp.FactionIcons[faction] then
item:SetTexture(recap_temp.FactionIcons[faction])
else
item:SetTexture("")
end
end
function Recap_GetUnitInfo(unit)
local u=UnitName(unit)
if u then
if recap.Combatant[u] then
_,recap.Combatant[u].Class = UnitClass(unit)
_,recap.Combatant[u].Faction = UnitFactionGroup(unit)
if UnitCreatureFamily(unit) and recap.Combatant[u].Faction then
recap.Combatant[u].Class = "Pet"
end
recap.Combatant[u].Level = UnitLevel(unit)
end
end
if unit~="target" and unit~="mouseover" and recap_temp.Last[u] then
if UnitIsVisible(unit) then
recap_temp.Last[u].HP = UnitHealth(unit)
recap_temp.Last[u].MaxHP = UnitHealthMax(unit)
else
recap_temp.Last[u].HP = nil -- discredit
end
end
end
-- creates a new .Combatant[arg1] that is a copy of DefaultCombatant
function Recap_CreateBlankCombatant(arg1)
if not recap.Combatant[arg1] then
recap.Combatant[arg1] = {
TotalTime = 0,
TotalDmgIn = 0,
TotalDmgOut = 0,
TotalDPS = 0,
TotalMaxHit = 0,
TotalKills = 0,
TotalHeal = 0,
LastTime = 0,
LastDmgIn = 0,
LastDmgOut = 0,
LastDPS = 0,
LastMaxHit = 0,
LastKills = 0,
LastHeal = 0,
WasInLast = false,
Friend = false,
Ignore = nil,
Owner = nil,
Incoming = {},
Detail = {}
}
end
end
-- populates .Opt with a copy of DefaultOpt
function Recap_LoadDefaultOpt()
recap.Opt = {}
for i in recap_temp.DefaultOpt do
recap.Opt[i] = {}
for j in recap_temp.DefaultOpt[i] do
recap.Opt[i][j] = recap_temp.DefaultOpt[i][j]
end
end
end
function Recap_SaveOpt(user)
if user and string.len(user)>0 then
recap[user].Opt = {}
for i in recap.Opt do
text = ""
for j in recap.Opt[i] do
text = text..tostring(j).."="..tostring(recap.Opt[i][j]).." "
end
recap[user].Opt[i] = text
end
end
end
function Recap_LoadOpt(user)
if user and recap[user] and recap[user].Opt then
for i in recap[user].Opt do
if recap_temp.DefaultOpt[i] then
for t,v in string.gfind(recap[user].Opt[i],"(%w+)=(%d-%--%w+) ") do
if v=="true" then
v = true
elseif v=="false" then
v = false
elseif tonumber(v) then
v = tonumber(v)
end
if t=="type" and recap_temp.DefaultOpt[i][t] then
v = recap_temp.DefaultOpt[i][t]
end
if recap.Opt[i] then
recap.Opt[i][t] = v
end
end
end
end
end
end
-- saves current data to data set "filen", overwrite~=nil to overwrite existing data
function Recap_SaveCombatants(filen,overwrite)
local sd = {}
if not filen or string.len(filen)<1 then
return
end
if not recap_set[filen] then
recap_set[filen] = {}
recap_set[filen].TimeStamp = date()
recap_set[filen].TotalDuration = 0
recap_set[filen].Combatant = {}
end
recap_set[filen] = {}
recap_set[filen].TimeStamp = date()
recap_set[filen].TotalDuration = recap[recap_temp.p].TotalDuration
recap_set[filen].Combatant = {}
for i in recap.Combatant do
if (not recap.Opt.SaveFriends.value or recap.Combatant[i].Friend) then
recap_set[filen].Combatant[i] = string.format("%s %d %d %d %d %d %.3f ~%d %d %d",
tostring(recap.Combatant[i].Friend),
recap.Combatant[i].TotalDmgIn,
recap.Combatant[i].TotalDmgOut,
recap.Combatant[i].TotalMaxHit,
recap.Combatant[i].TotalHeal,
recap.Combatant[i].TotalKills,
recap.Combatant[i].TotalTime,
Recap_MakeKey(recap.Combatant[i].Faction),
Recap_MakeKey(recap.Combatant[i].Class),
recap.Combatant[i].Level or 0)
if recap.Opt.LightData and not recap.Opt.LightData.value then
-- save .Incoming
recap_set[filen].Combatant[i] = recap_set[filen].Combatant[i].."^"
for k in recap.Combatant[i].Incoming do
if recap.Combatant[i].Incoming[k]>0 then
recap_set[filen].Combatant[i] = recap_set[filen].Combatant[i]..inckey[k]..recap.Combatant[i].Incoming[k]
end
end
recap_set[filen].Combatant[i] = recap_set[filen].Combatant[i].."^"
for j in recap.Combatant[i].Detail do
recap_set[filen].Combatant[i] = recap_set[filen].Combatant[i].."["..j..">"
for k in recap.Combatant[i].Detail[j] do
recap_set[filen].Combatant[i] = recap_set[filen].Combatant[i]..detkey[k]..recap.Combatant[i].Detail[j][k]
end
recap_set[filen].Combatant[i] = recap_set[filen].Combatant[i].."]"
end
end
end
end
fight_count = 0
for i in recap_set[filen].Combatant do
fight_count = fight_count + 1
end
recap_set[filen].ListSize = fight_count
end
function Recap_MakeKey(arg1)
local key = 0
for i in recap_temp.Keys do
if arg1==recap_temp.Keys[i] then
key = i
end
end
return key
end
function Recap_GetKey(arg1)
local key = nil
if not arg1 or not tonumber(arg1) or arg1==0 then
key=nil
else
key=recap_temp.Keys[tonumber(arg1)]
end
return key
end
function Recap_LoadCombatants(filen,overwrite)
local sd = {} -- temp holding place for fields that may not exist
local found,set_friend,set_dmgin,set_dmgout,set_maxhit,set_heal,set_kills,set_time,set_faction,set_class,set_level
if not filen or string.len(filen)<1 or not recap_set[filen] then
return
end
Recap_ResetAllCombatants()
recap[recap_temp.p].TotalDuration = recap[recap_temp.p].TotalDuration + recap_set[filen].TotalDuration
for i in recap_set[filen].Combatant do
if not recap.Combatant[i] then
Recap_CreateBlankCombatant(i)
end
found,_,set_friend,set_dmgin,set_dmgout,set_maxhit,set_heal,set_kills,set_time = string.find(recap_set[filen].Combatant[i],"(%w+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+%.?%d+)")
if found then
if set_friend == "true" then
recap.Combatant[i].Friend = true
end
if tonumber(set_maxhit) > recap.Combatant[i].TotalMaxHit then
recap.Combatant[i].TotalMaxHit = tonumber(set_maxhit)
end
recap.Combatant[i].TotalDmgIn = recap.Combatant[i].TotalDmgIn + tonumber(set_dmgin)
recap.Combatant[i].TotalDmgOut = recap.Combatant[i].TotalDmgOut + tonumber(set_dmgout)
recap.Combatant[i].TotalKills = recap.Combatant[i].TotalKills + tonumber(set_kills)
recap.Combatant[i].TotalHeal = recap.Combatant[i].TotalHeal + tonumber(set_heal)
recap.Combatant[i].TotalTime = recap.Combatant[i].TotalTime + tonumber(set_time)
if recap.Combatant[i].TotalTime > recap_temp.MinTime then
recap.Combatant[i].TotalDPS = recap.Combatant[i].TotalDmgOut/recap.Combatant[i].TotalTime
else
recap.Combatant[i].TotalDPS = 0
end
end
found,_,set_faction,set_class,set_level = string.find(recap_set[filen].Combatant[i],"~(%d+) (%d+) (%d+)")
if not found then
found,_,set_faction,set_class = string.find(recap_set[filen].Combatant[i],"~(%d+) (%d+)")
end
if found then
recap.Combatant[i].Faction = Recap_GetKey(set_faction)
recap.Combatant[i].Class = Recap_GetKey(set_class)
recap.Combatant[i].Level = recap.Combatant[i].Level or set_level or 0
end
if not recap.Opt.LightData.value then
-- process incoming: ^a000b000c000^
for k in sd do sd[k] = nil end -- wipe temp buffer
found,_,j = string.find(recap_set[filen].Combatant[i],"%^(.-)%^")
if found then
for k in inckey do
_,_,sd[k] = string.find(j,inckey[k].."(%d+)")
end
elseif string.find(recap_set[filen].Combatant[i],"%^%d+ %d+ %d+ %d+ %d+ %d+ %d+ %d+ %d+ %d+ %d+ %d+ %d+") then
found,_,sd.MeleeDamage,sd.MeleeMax,sd.MeleeHits,sd.MeleeCrits,sd.MeleeMissed,sd.MeleeDodged,sd.MeleeParried,sd.MeleeBlocked,
sd.NonMeleeDamage,sd.NonMeleeMax,sd.NonMeleeHits,sd.NonMeleeCrits,sd.NonMeleeMissed =
string.find(recap_set[filen].Combatant[i],"%^(%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+)")
end
if found then
for k in sd do
if sd[k] and tonumber(sd[k])>0 then
recap.Combatant[i].Incoming[k] = tonumber(sd[k])
end
end
end
-- process details: [name:a000b000c000]
for j in string.gfind(recap_set[filen].Combatant[i],"%[.-%]") do
for k in sd do sd[k] = nil end -- wipe temp buffer
found,_,set_name = string.find(j,"%[(.-)%>")
if found then -- new saved method
recap.Combatant[i].Detail[set_name] = {}
for k in detkey do
_,_,sd[k] = string.find(j,detkey[k].."(%d+)")
end
else
found,_,set_name = string.find(j,"%[(.-) %d")
if found then -- old saved method
recap.Combatant[i].Detail[set_name] = {}
_,_,sd.HitsDmg,sd.Hits,sd.HitsMax,sd.CritsDmg,sd.Crits,sd.CritsMax,sd.CritsEvents,sd.Missed =
string.find(j,"%[.+ (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+)") -- old method
end
end
if found then
for k in sd do
if sd[k] and tonumber(sd[k])>0 then
recap.Combatant[i].Detail[set_name][k] = tonumber(sd[k])
end
end
end
end
end
end
end
function Recap_ResetAllCombatants()
local current_state = recap.Opt.State.value
recap.Opt.State.value = "Stopped"
recap.Combatant = {}
recap_temp.IdleTimer = -1
recap_temp.Last = {}
recap[recap_temp.p].LastDuration = 0
recap[recap_temp.p].TotalDuration = 0
recap_temp.FightStart = 0
recap_temp.FightEnd = 0
recap_temp.ListSize = 0
recap.Opt.State.value = current_state
end
local function Recap_LoadSelf()
recap.Self = recap.Self or {}
recap.Self[recap_temp.s] = recap.Self[recap_temp.s] or {}
recap_temp.SelfList = {}
recap_temp.SelfListSize = 1
end
function Recap_InitializeData()
local i,j,k,l,m
local temp_user = recap_temp.p
local oldkeys = { ["Krieger"]="WARRIOR", ["Magier"]="MAGE", ["Schurke"]="ROGUE", ["Druide"]="DRUID",
["J\195\164ger"]="HUNTER", ["Schamane"]="SHAMAN", ["Priester"]="PRIEST", ["Hexenmeister"]="WARLOCK",
["Guerrier"]="WARRIOR", ["Voleur"]="ROGUE", ["Chasseur"]="HUNTER", ["Chaman"]="SHAMAN",
["PrĂȘtre"]="PRIEST", ["DĂ©moniste"]="WARLOCK", ["Familier"]="Pet" }
if not recap.DataVersion then
-- wipe all pre-2.6 data
recap = {}
recap.DataVersion = 3.2
elseif recap.DataVersion < 3.0 then
-- convert 2.6 to 3.0, make classes uppercase
for i in recap.Combatant do
if recap.Combatant[i].Faction=="Allianz" then
recap.Combatant[i].Faction = "Alliance"
end
if recap.Combatant[i].Class then
-- convert classes to english, which all locales will use for icon reference
if oldkeys[recap.Combatant[i].Class] then
recap.Combatant[i].Class = oldkeys[recap.Combatant[i].Class]
end
recap.Combatant[i].Class = string.upper(recap.Combatant[i].Class)
end
end
recap.DataVersion = 3.0
end
-- if this user hasn't been made before
if not recap[recap_temp.p] then
recap[recap_temp.p] = {}
recap[recap_temp.p].TotalDuration = 0
recap[recap_temp.p].LastDuration = 0
end
-- if this is a different/first-time user, or if this is first run of a new version,
-- save the current combatants and options and then load them based on default.
-- any changes in combatant or option format must come with a version change
if (recap.User ~= recap_temp.p) or recap.DataVersion<Recap_Version then
-- if we have data from previous user, save them
if recap.User then
recap_temp.p = recap.User
Recap_SaveCombatants("UserData:"..recap.User,1)
Recap_SaveOpt(recap.User)
recap_temp.p = temp_user
end
recap.User = recap_temp.p
-- wipe slate, load defaults and overlay saved data ontop
Recap_LoadDefaultOpt()
Recap_ResetAllCombatants()
-- convert data sets to new format (see readme)
if recap.DataVersion < 3.2 then
for i in recap_set do
if recap_set[i].Combatant then
j = recap_set[i].TimeStamp
Recap_LoadCombatants(i,1)
for k in recap_set[i].Combatant do
l = (l or 0) + string.len(recap_set[i].Combatant[k])
end
Recap_SaveCombatants(i,1)
for k in recap_set[i].Combatant do
m = (m or 0) + string.len(recap_set[i].Combatant[k])
end
recap_set[i].TimeStamp = j
end
end
recap.DataVersion = 3.2
end
Recap_LoadCombatants("UserData:"..recap_temp.p,1)
Recap_LoadOpt(recap_temp.p)
recap.DataVersion = Recap_Version
else
for i in recap.Combatant do
recap_temp.Last[i] = { Start = 0, End = 0, DmgIn = 0, DmgOut = 0, MaxHit = 0, Kills = 0, Heal = 0 }
end
end
-- remove current UserData: - it's now "live" in recap.Combatant
if recap_set and recap_set["UserData:"..recap_temp.p] then
recap_set["UserData:"..recap_temp.p] = nil
end
Recap_LoadSelf()
end
--[[ Context menu functions ]]
function RecapMenu_OnUpdate(arg1)
local i
if not recap_temp.MenuTimer or MouseIsOver(RecapMenu) then
recap_temp.MenuTimer = 0
end
recap_temp.MenuTimer = recap_temp.MenuTimer + arg1
if recap_temp.MenuTimer > .2 then
recap_temp.MenuTimer = 0
RecapMenu:Hide()
if recap_temp.SelectedEffect then
for i=1,15 do
getglobal("RecapSelf"..i):UnlockHighlight()
end
end
end
end
--[[ Fight report functions ]]
function Recap_AutoPostGetStatID(arg1)
if arg1=="Damage" then
return "DmgOut"
elseif arg1=="Tanking" then
return "DmgIn"
elseif arg1=="Healing" then
return "Heal"
end
return "DPS"
end
function Recap_PostFight()
local print_chat = SendChatMessage
local chatchan, chatnum, text
if recap.Opt.SpamRows.value then
Recap_PostSpamRows(Recap_AutoPostGetStatID(recap.Opt.AutoPost.Stat),"recap auto")
else
chatchan = recap.Opt.AutoPost.Channel
_,_,chatnum = string.find(chatchan,"(%d+)")
if chatnum then
chatchan = "CHANNEL"
end
if chatchan=="Self" then
print_chat = Recap_Print
end
text = Recap_PostSpamLine(Recap_AutoPostGetStatID(recap.Opt.AutoPost.Stat))
if string.find(text,"%d") then
print_chat(Recap_PostSpamLine(Recap_AutoPostGetStatID(recap.Opt.AutoPost.Stat)),chatchan,nil,chatnum)
end
end
end
function Recap_PostLeader()
local print_chat = SendChatMessage
local chatchan, chatnum, leader, statid, i
if recap_temp.ListSize>2 then
chatchan = recap.Opt.AutoPost.Channel
_,_,chatnum = string.find(chatchan,"(%d+)")
if chatnum then
chatchan = "CHANNEL"
end
if chatchan=="Self" then
print_chat = Recap_Print
end
statid = Recap_AutoPostGetStatID(recap.Opt.AutoPost.Stat)
if not recap.Combatant[recap_temp.Leader] then -- in case leader reset
recap_temp.Leader = nil
end
if not recap_temp.Leader and recap.Combatant[recap_temp.List[1].Name].Friend then
recap_temp.Leader = recap_temp.List[1].Name
leader = recap_temp.Leader -- spam initial leader
end
if recap_temp.Leader then
for i in recap.Combatant do
if (recap.Combatant[i]["Total"..statid] > recap.Combatant[recap_temp.Leader]["Total"..statid]) and recap.Combatant[i].Friend then
leader = i
end
end
if leader then
recap_temp.Leader = leader
print_chat(string.format("New leader for %s: %s with %s",recap.Opt.AutoPost.Stat,leader,Recap_FormatStat(statid,leader)),chatchan,nil,chatnum)
end
end
end
end
-- returns 'text' to be spammed in autopost or linked in chat
function Recap_PostSpamLine(arg1)
local text,i
text = recap_temp.Local.LinkRank[arg1].." for "..recap_temp.Local.LastAll[recap.Opt.View.value]..":"
for i=1,recap.Opt.MaxRank.value do
if i<recap_temp.ListSize and recap.Combatant[recap_temp.List[i].Name].Friend then
if recap_temp.List[i][arg1]>0 then
text = text.." ["..i.."."..recap_temp.List[i].Name.." "..Recap_FormatStat(arg1,i).."]"
end
end
end
return text
end
-- arg1 = stat to report by (DPS, DmgOut, etc)
function Recap_PostSpamRows(arg1,chatchan,chatnum)
local headertext = nil
local print_chat = SendChatMessage
if chatchan=="recap auto" then
chatchan = recap.Opt.AutoPost.Channel
end
arg1 = string.gsub(arg1,"P$","") -- strip trailing P from % id's
if not chatnum then
_,_,chatnum = string.find(chatchan,"(%d+)")
if chatnum then
chatchan = "CHANNEL"
end
end
if chatchan=="Self" then
print_chat = Recap_Print
end
headertext = "__ "..recap_temp.Local.LinkRank[arg1].." for "..recap_temp.Local.LastAll[recap.Opt.View.value].." __"
for i=1,recap.Opt.MaxRank.value do
if i<recap_temp.ListSize and recap.Combatant[recap_temp.List[i].Name].Friend then
text = i..". "..recap_temp.List[i].Name..": "..Recap_FormatStat(arg1,i)
if recap_temp.List[i][arg1] > 0 then
if headertext then
print_chat(headertext,chatchan,nil,chatnum)
headertext = nil
end
print_chat(text,chatchan,nil,chatnum)
end
end
end
end
-- returns a formatted string for arg1 stat ("DPS" "Time" etc) for combatant arg2 (number is .List[], non-number is name)
function Recap_FormatStat(arg1,arg2)
local i
arg1 = string.gsub(arg1,"P$","")
if not tonumber(arg2) then
for i=1,(recap_temp.ListSize-1) do
if recap_temp.List[i].Name==arg2 then
arg2 = i
i = recap_temp.ListSize
end
end
end
if tonumber(arg2) then
if arg1=="DPS" then
return string.format("%.1f",recap_temp.List[arg2].DPS)
elseif arg1=="DPSvsAll" then
return string.format("%.1f",recap_temp.List[arg2].DPSvsAll)
elseif arg1=="Time" then
return Recap_FormatTime(recap_temp.List[arg2].Time)
elseif arg1=="DmgOut" then
return recap_temp.List[arg2].DmgOut.." ("..recap_temp.List[arg2].DmgOutP.."%)"
elseif arg1=="DmgIn" then
return recap_temp.List[arg2].DmgIn.." ("..recap_temp.List[arg2].DmgInP.."%)"
elseif arg1=="Heal" then
return recap_temp.List[arg2].Heal.." ("..recap_temp.List[arg2].HealP.."%)"
elseif arg1=="Over" then
return recap_temp.List[arg2].Over.."%"
else
return recap_temp.List[arg2][arg1]
end
end
return ""
end
function Recap_Print(arg1)
DEFAULT_CHAT_FRAME:AddMessage(tostring(arg1))
end
--[[ Debug ]]
function Recap_DebugUnusedFilters(filter)
local i,j,found
for i in recap_temp[filter] do
found = false
for j in recap.debug_Filter do
if recap_temp[filter][i].pattern==recap.debug_Filter[j].pattern then
found = true
end
end
if not found then
DEFAULT_CHAT_FRAME:AddMessage(filter..": "..recap_temp[filter][i].pattern)
end
end
end
function Recap_MoveMinimize()
RecapCloseButton:ClearAllPoints()
RecapCloseButton:SetPoint("TOPRIGHT","RecapFrame","TOPRIGHT",-6,-6)
RecapMinStatus:ClearAllPoints()
RecapMinStatus:SetPoint("TOPLEFT", "RecapFrame", "TOPLEFT", 6,-7)
RecapResetButton:ClearAllPoints()
RecapResetButton:SetPoint("BOTTOMLEFT", "RecapFrame", "BOTTOMLEFT", 5,4)
RecapMinimizeButton:ClearAllPoints()
if recap.Opt.GrowLeftwards.value and not recap.Opt.GrowUpwards.value then -- topright
RecapMinimizeButton:SetPoint("TOPRIGHT", "RecapFrame", "TOPRIGHT", -6, -6)
RecapCloseButton:SetPoint("TOPRIGHT", "RecapMinimizeButton", "TOPLEFT", -2, 0)
elseif recap.Opt.GrowLeftwards.value and recap.Opt.GrowUpwards.value then -- bottomright
RecapMinimizeButton:SetPoint("BOTTOMRIGHT", "RecapFrame", "BOTTOMRIGHT", -6, 6)
if recap.Opt.Minimized.value then
RecapCloseButton:SetPoint("TOPRIGHT", "RecapMinimizeButton", "TOPLEFT", -2, 0)
end
elseif not recap.Opt.GrowLeftwards.value and not recap.Opt.GrowUpwards.value then -- topleft
RecapMinimizeButton:SetPoint("TOPLEFT", "RecapFrame", "TOPLEFT", 6, -6)
RecapMinStatus:SetPoint("TOPLEFT", "RecapMinimizeButton", "TOPRIGHT", 2, -1)
else -- bottomleft
RecapMinimizeButton:SetPoint("BOTTOMLEFT", "RecapFrame", "BOTTOMLEFT", 6, 6)
RecapResetButton:SetPoint("BOTTOMLEFT", "RecapFrame", "BOTTOMLEFT", 23, 4)
end
if recap.Opt.Minimized.value and not recap.Opt.GrowLeftwards.value then
RecapMinStatus:SetPoint("TOPLEFT", "RecapMinimizeButton", "TOPRIGHT", 2, -1)
end
if recap.Opt.AutoMinimize.value then
RecapMinimizeButton:SetWidth(1)
RecapMinimizeButton:Hide()
else
RecapMinimizeButton:SetWidth(16)
RecapMinimizeButton:Show()
end
end
function RecapMenu_SetCheck(id,arg1)
if arg1 then
getglobal("RecapMenu"..id.."_Check"):Show()
else
getglobal("RecapMenu"..id.."_Check"):Hide()
end
end
function RecapMenu_OnClick()
local id,index = this:GetID()
if recap_temp.Menu==recap_temp.ColumnMenu or recap_temp.Menu==recap_temp.MinMenu or recap_temp.Menu==recap_temp.EffectOptMenu then
index = recap_temp.Menu[id].Info -- .Info of menu item selected
if recap.Opt[index] then
recap.Opt[index].value = not recap.Opt[index].value
getglobal("RecapOptCheck_"..recap_temp.Menu[id].Info):SetChecked(0)
if recap.Opt[index].value then
getglobal("RecapOptCheck_"..recap_temp.Menu[id].Info):SetChecked(1)
end
RecapMenu_SetCheck(id,recap.Opt[index].value)
if recap.Opt.Minimized.value then
Recap_Minimize()
else
Recap_Maximize()
end
elseif index=="Pin" then
recap.Opt.Pinned.value = not recap.Opt.Pinned.value
Recap_SetButtons()
RecapMenu:Hide()
end
end
if recap_temp.Menu==recap_temp.AddMenu or recap_temp.Menu==recap_temp.DropMenu then
RecapMenu:Hide()
index = recap_temp.List[recap_temp.Selected].Name -- name selected
if id==1 and recap_temp.Menu==recap_temp.DropMenu and index~=recap_temp.Player then
recap.Combatant[index].Friend = false
elseif id==1 and index~=recap_temp.Player then
recap.Combatant[index].Friend = not recap.Combatant[index].Friend
elseif id==2 and recap.Opt.View.value=="All" then -- reset
recap.Combatant[index] = nil
Recap_CreateBlankCombatant(index)
elseif id==2 and recap.Opt.View.value=="Last" then
if recap.Combatant[index].WasInLast then
Recap_ResetLastFight(index)
end
elseif id==3 and index~=recap_temp.Player then
recap.Combatant[index] = nil
Recap_CreateBlankCombatant(index)
recap.Combatant[index].Ignore = true
end
Recap_SetView()
end
if recap_temp.Menu==recap_temp.EffectMenu then
RecapMenu:Hide()
for i=1,15 do
getglobal("RecapSelf"..i):UnlockHighlight()
end
if recap_temp.SelectedEffect and recap.Self[recap_temp.s][recap_temp.SelectedEffect] then
recap.Self[recap_temp.s][recap_temp.SelectedEffect] = nil
recap_temp.SelectedEffect = nil
Recap_SetView()
end
end
if recap_temp.Menu==recap_temp.DetailMenu then
if recap_temp.DetailsList and recap_temp.DetailsList[1][recap_temp.Menu[id].Info] then
recap.Opt.PanelDetail.value = recap_temp.Menu[id].Info
RecapPanel_Populate(recap_temp.List[recap_temp.Selected].Name)
end
RecapMenu:Hide()
end
end
-- offset=1 to move window so it's under pointer
function RecapCreateMenu(menu,offset)
local i,cy,x,y,lines
recap_temp.Menu = menu
if recap_temp.Menu==recap_temp.ColumnMenu or recap_temp.Menu==recap_temp.MinMenu or recap_temp.Menu==recap_temp.EffectOptMenu then
for i in recap_temp.Menu do
if recap.Opt[recap_temp.Menu[i].Info] then
recap_temp.Menu[i].Check = recap.Opt[recap_temp.Menu[i].Info].value
end
end
end
if recap_temp.Menu==recap_temp.MinMenu then
recap_temp.Menu[1].Check = recap.Opt.Pinned.value
end
if recap_temp.Menu==recap_temp.DetailMenu then
for i in recap_temp.Menu do
recap_temp.Menu[i].Check = recap.Opt.PanelDetail.value==recap_temp.Menu[i].Info
end
end
lines = min(table.getn(recap_temp.Menu),16)
cy = 44 -- 12+32
for i=1,lines do
getglobal("RecapMenu"..i.."_Text"):SetText(recap_temp.Menu[i].Text)
RecapMenu_SetCheck(i,recap_temp.Menu[i].Check)
getglobal("RecapMenu"..i):Show()
cy = cy + 14
end
for i=(lines+1),16 do
getglobal("RecapMenu"..i):Hide()
end
RecapMenu:SetHeight(cy)
RecapDropSubFrame:SetHeight(cy-32)
RecapMenu:ClearAllPoints()
x,y = GetCursorPosition()
if recap.Opt.GrowUpwards.value and not offset then
y = this:GetBottom()*UIParent:GetScale()
RecapMenu:SetPoint("BOTTOMRIGHT","UIParent","BOTTOMLEFT",(x/UIParent:GetScale())+20,(y/UIParent:GetScale())-4)
else
y = this:GetTop()*UIParent:GetScale()
RecapMenu:SetPoint("TOPRIGHT","UIParent","BOTTOMLEFT",(x/UIParent:GetScale())+20,(y/UIParent:GetScale())+(offset and 16 or 4))
end
RecapMenu:Show()
end
function RecapMenu_OnEnter()
id = this:GetID()
if recap_temp.Menu[id] and recap_temp.Menu[id].Info then
if recap_temp.Menu==recap_temp.AddMenu or recap_temp.Menu==recap_temp.DropMenu then
Recap_OnTooltip(recap_temp.Menu[id].Info,recap_temp.List[recap_temp.Selected].Name)
elseif recap_temp.Menu==recap_temp.EffectMenu and recap_temp.SelectedEffect then
Recap_OnTooltip(recap_temp.Menu[id].Info,string.sub(recap_temp.SelectedEffect,2))
else
Recap_OnTooltip(recap_temp.Menu[id].Info)
end
end
end
function RecapEffectsHeader_OnEnter()
local s
_,_,s = string.find(this:GetName(),"RecapHeader_(.+)")
if s then
Recap_OnTooltip("Header"..s)
end
end
function RecapSelf_OnMouseUp(arg1)
local index,i
recap_temp.SelectedEffect = nil
Recap_OnMouseUp(arg1)
if arg1=="RightButton" then
_,_,i = string.find(this:GetName(),"(%d+)")
if i and tonumber(i) then
i = tonumber(i)
index = i + FauxScrollFrame_GetOffset(RecapScrollBar)
if index < recap_temp.SelfListSize then
this:LockHighlight()
recap_temp.SelectedEffect = recap_temp.SelfList[index].EName
end
end
RecapCreateMenu(recap_temp.EffectMenu,1)
end
end
function RecapEffectsHeader_OnMouseUp(arg1)
if arg1=="RightButton" then
RecapCreateMenu(recap_temp.EffectOptMenu)
end
end
function RecapEffectsHeader_OnClick()
local idx,i
local alltext,text = ""
local channel,chatnumber = ChatFrameEditBox.chatType
local hasdata
if IsShiftKeyDown() and ChatFrameEditBox:IsVisible() then
if channel=="WHISPER" then
chatnumber = ChatFrameEditBox.tellTarget
elseif channel=="CHANNEL" then
chatnumber = ChatFrameEditBox.channelTarget
end
_,_,idx = string.find(tostring(this:GetName()),"RecapHeader_(.+)")
if idx and idx~="EName" then
alltext = (recap.Opt.SpamRows.value and "__ " or "")..recap_temp.Player.."'s "..Recap_GetTooltip("Header"..idx)..(recap.Opt.SpamRows.value and " __" or ":")
for i=1,recap_temp.SelfListSize-1 do
if recap_temp.SelfList[i][idx]~="0.0%" and recap_temp.SelfList[i][idx]~="--" and tostring(recap_temp.SelfList[i][idx])~="0" then
if not hasdata and recap.Opt.SpamRows.value then
SendChatMessage(alltext,channel,nil,chatnumber)
end
hasdata = true
text = string.sub(recap_temp.SelfList[i].EName,2)..(string.sub(recap_temp.SelfList[i].EName,1,1)=="3" and "*" or "")..(recap.Opt.SpamRows.value and ": " or " ")..recap_temp.SelfList[i][idx]..(idx=="ETotal" and (" ("..recap_temp.SelfList[i].ETotalP..")") or "")
if not recap.Opt.SpamRows.value then
alltext = alltext.." ["..text.."]"
else
SendChatMessage(text,channel,nil,chatnumber)
end
end
end
if not recap.Opt.SpamRows.value and hasdata then
Recap_InsertChat(alltext)
end
end
end
end
function RecapSelf_OnClick()
local id = this:GetID()
local index = id + FauxScrollFrame_GetOffset(RecapScrollBar)
local linkformat = recap_temp.Local.DamageDetailLink
local text = ""
if IsShiftKeyDown() and index<recap_temp.SelfListSize and ChatFrameEditBox:IsVisible() then
if string.sub(recap_temp.SelfList[index].EName,1,1)=="3" then
linkformat = recap_temp.Local.HealDetailLink
end
text = string.format(linkformat,recap_temp.Player,string.sub(recap_temp.SelfList[index].EName,2),recap_temp.SelfList[index].ETotal,recap_temp.SelfList[index].ETotalP )..", Max: "..recap_temp.SelfList[index].EMaxAll..((recap_temp.SelfList[index].ECritsP~="--") and (", Crit Rate: "..recap_temp.SelfList[index].ECritsP) or "")
Recap_InsertChat(text," ")
end
end
function Recap_Combat_OnEvent()
if event=="CHAT_MSG_COMBAT_FRIENDLY_DEATH" or event=="CHAT_MSG_COMBAT_HOSTILE_DEATH" then
Recap_DeathEvent(arg1)
elseif event=="UPDATE_MOUSEOVER_UNIT" then
Recap_GetUnitInfo("mouseover")
elseif event=="PLAYER_TARGET_CHANGED" then
Recap_GetUnitInfo("target")
elseif event=="SPELLCAST_START" then
if (not recap.Opt.LightData.value) and recap.Combatant[recap_temp.Player] and recap.Combatant[recap_temp.Player].Detail["1"..arg1] then
if not recap.Opt.LimitFights.value then
if recap.Opt.IdleFight.value then
recap_temp.IdleTimer = 0
end
if recap.Opt.State.value=="Idle" then
Recap_StartFight()
end
end
Recap_CreateCombatant(recap_temp.Player,1) -- if this was a cast that's done damage before, start timer
end
elseif string.find(event,"BUFF") then
Recap_HealEvent(arg1)
else
Recap_DamageEvent(arg1)
end
end
function Recap_Register_CombatEvents()
if not recap_temp.CombatEventsRegistered then
-- register damage events
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_PARTY_HITS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_PARTY_MISSES")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_PET_HITS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_PET_MISSES")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_SELF_HITS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_SELF_MISSES")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PARTY_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PET_DAMAGE")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_SELF_DAMAGE")
-- register death events
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLY_DEATH")
RecapCombatEvents:RegisterEvent("CHAT_MSG_COMBAT_HOSTILE_DEATH")
-- register healing events
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PARTY_BUFF")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_PET_BUFF")
RecapCombatEvents:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF")
RecapCombatEvents:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
RecapCombatEvents:RegisterEvent("PLAYER_TARGET_CHANGED")
RecapCombatEvents:RegisterEvent("SPELLCAST_START")
recap_temp.CombatEventsRegistered = 1
end
end
function Recap_Unregister_CombatEvents()
if recap_temp.CombatEventsRegistered then
RecapCombatEvents:UnregisterAllEvents()
recap_temp.CombatEventsRegistered = nil
end
end
Generated by GNU Enscript 1.6.5.90.