You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3594 lines
129 KiB

--lua locals
local _cstr = string.format
local _math_floor = math.floor
local tinsert = table.insert
local ipairs = ipairs
local pairs = pairs
local min = math.min
local unpack = unpack
local type = type
--api locals
local _GetSpellInfo = Details.getspellinfo
local GameTooltip = GameTooltip
local IsInRaid = IsInRaid
local IsInGroup = IsInGroup
local GetNumGroupMembers = GetNumGroupMembers
local UnitGUID = UnitGUID
local _UnitName = UnitName
local format = _G.format
local GetSpellLink = GetSpellLink or C_Spell.GetSpellLink --api local
local UnitIsUnit = UnitIsUnit
local _string_replace = Details.string.replace --details api
local Details = _G.Details
local AceLocale = LibStub("AceLocale-3.0")
local Loc = AceLocale:GetLocale( "Details" )
---@type detailsframework
local detailsFramework = DetailsFramework
local addonName, Details222 = ...
local gump = Details.gump
local _
local container_habilidades = Details.container_habilidades
local atributo_misc = Details.atributo_misc
local container_misc = Details.container_type.CONTAINER_MISC_CLASS
local modo_GROUP = Details.modos.group
local modo_ALL = Details.modos.all
local class_type = Details.atributos.misc
local ToKFunctions = Details.ToKFunctions
local UsingCustomLeftText = false
local UsingCustomRightText = false
local TooltipMaximizedMethod = 1
local breakdownWindowFrame = Details.BreakdownWindowFrame
local keyName
local headerColor = "yellow"
function Details.SortIfHaveKey(table1, table2)
if (table1[keyName] and table2[keyName]) then
return table1[keyName] > table2[keyName]
elseif (table1[keyName] and not table2[keyName]) then
return true
else
return false
end
end
function Details.SortGroupIfHaveKey(table1, table2)
if (table1.grupo and table2.grupo) then
if (table1[keyName] and table2[keyName]) then
return table1[keyName] > table2[keyName]
elseif (table1[keyName] and not table2[keyName]) then
return true
else
return false
end
elseif (table1.grupo and not table2.grupo) then
return true
elseif (not table1.grupo and table2.grupo) then
return false
else
if (table1[keyName] and table2[keyName]) then
return table1[keyName] > table2[keyName]
elseif (table1[keyName] and not table2[keyName]) then
return true
else
return false
end
end
end
function Details.SortGroupMisc(container, keyName2)
keyName = keyName2
return table.sort(container, Details.SortKeyGroupMisc)
end
function Details.SortKeyGroupMisc(table1, table2)
if (table1.grupo and table2.grupo) then
return table1[keyName] > table2[keyName]
elseif (table1.grupo and not table2.grupo) then
return true
elseif (not table1.grupo and table2.grupo) then
return false
else
return table1[keyName] > table2[keyName]
end
end
function Details.SortKeySimpleMisc(table1, table2)
return table1[keyName] > table2[keyName]
end
function Details:ContainerSortMisc(container, amount, keyName2)
keyName = keyName2
table.sort(container, Details.SortKeySimpleMisc)
if (amount) then
for i = amount, 1, -1 do
if (container[i][keyName] < 1) then
amount = amount-1
else
break
end
end
return amount
end
end
---attempt to get the amount of casts of a spell
---@param combat table the combat object
---@param actorName string name of the actor
---@param spellName string
function Details:GetSpellCastAmount(combat, actorName, spellName) --[[exported]]
return combat:GetSpellCastAmount(actorName, spellName)
end
function atributo_misc:NovaTabela(serial, nome, link)
local newUtilityActor = {
last_event = 0,
tipo = class_type,
pets = {}
}
setmetatable(newUtilityActor, atributo_misc)
detailsFramework:Mixin(newUtilityActor, Details222.Mixins.ActorMixin)
return newUtilityActor
end
function atributo_misc:CreateBuffTargetObject()
return {
uptime = 0,
actived = false,
activedamt = 0,
refreshamt = 0,
appliedamt = 0,
}
end
local statusBarBackgroundTable_ForDeathTooltip = {
value = 100,
texture = [[Interface\AddOns\Details\images\bar_serenity]],
color = {DetailsFramework:GetDefaultBackdropColor()}
}
--expose in case someone want to customize the death tooltip background
Details.StatusBarBackgroundTable_ForDeathTooltip = statusBarBackgroundTable_ForDeathTooltip
function Details.ShowDeathTooltip(instance, lineFrame, combatObject, deathTable) --~death
local events = deathTable[1]
local timeOfDeath = deathTable[2]
local maxHP = max(deathTable[5], 0.001)
local battleress = false
local lastcooldown = false
local gameCooltip = GameCooltip
local showSpark = Details.death_tooltip_spark
local barTypeColors = Details.death_log_colors
local statusbarTexture = Details.death_tooltip_texture
local tooltipWidth = Details.death_tooltip_width
local damageSourceColor = "FFFFFFFF" --FFC6B0D9
local healingSourceColor = "FF988EA0" --FFC6B0D9
local damageAmountColor = "FFFFFFFF"
local healingAmountColor = "FF988EA0"
local lineHeight = Details.deathlog_line_height
gameCooltip:Reset()
gameCooltip:SetType("tooltipbar")
gameCooltip:AddLine(Loc ["STRING_REPORT_LEFTCLICK"], nil, 1, unpack(Details.click_to_report_color))
gameCooltip:AddIcon([[Interface\TUTORIALFRAME\UI-TUTORIAL-FRAME]], 1, 1, 12, 16, 0.015625, 0.13671875, 0.4375, 0.59765625)
--death parser
for i, event in ipairs(events) do
--local currentHP = event[5] * 100
--local healthPercent = floor(currentHP / maxHP * 100)
local healthPercent = floor((event[5] or 0) * 100)
if (healthPercent > 100) then
healthPercent = 100
end
local evType = event[1]
local spellName, _, spellIcon = _GetSpellInfo(event[2])
if (not spellName) then
spellName = _G.UNKNOWN
end
if (not spellIcon) then
spellIcon = [[Interface\ICONS\INV_MISC_QUESTIONMARK]]
end
local amount = event[3]
local eventTime = event[4]
local source = Details:GetOnlyName(event[6] or "")
local eventFrom = event[6]
if (eventTime + 10 > timeOfDeath) then
if (type(evType) == "boolean") then
--is damage or heal?
if (evType) then --bool true
--damage
local overkill = event[10] or 0
local critical = event[11] and (" " .. TEXT_MODE_A_STRING_RESULT_CRITICAL) or "" --(Critical)
local crushing = event[12] and (" " .. TEXT_MODE_A_STRING_RESULT_CRUSHING) or "" --(Crushing)
local critOrCrush = critical .. crushing
if (overkill > 0) then
--deprecated as the parser now removes the overkill damage from total damage
--this should now sum the overkill from [10] with the damage from [3]
--check the type of overkill that should be shown
--if show_totalhitdamage_on_overkill is true it'll show the total damage of the hit
--if false it shows the total damage of the hit minus the overkill
--if (not Details.show_totalhitdamage_on_overkill) then
-- amount = amount - overkill
--end
overkill = " (" .. Details:ToK(overkill) .. " |cFFFF8800overkill|r)"
gameCooltip:AddLine("" .. format("%.1f", eventTime - timeOfDeath) .. "s |cFFFFFF00" .. spellName .. "|r(|c" .. damageSourceColor .. eventFrom .. "|r)", "|c" .. damageAmountColor .. "-" .. Details:ToK(amount) .. critOrCrush .. overkill .. " (" .. healthPercent .. "%)", 1, "white", "white")
else
overkill = ""
gameCooltip:AddLine("" .. format("%.1f", eventTime - timeOfDeath) .. "s " .. spellName .. " (|c" .. damageSourceColor .. eventFrom .. "|r)", "|c" .. damageAmountColor .. "-" .. Details:ToK(amount) .. critOrCrush .. overkill .. " (" .. healthPercent .. "%)", 1, "white", "white")
end
gameCooltip:AddIcon(spellIcon, nil, nil, lineHeight, lineHeight, .1, .9, .1, .9)
if (event[9]) then
--friendly fire
gameCooltip:AddStatusBar(healthPercent, 1, barTypeColors.friendlyfire, showSpark, statusBarBackgroundTable_ForDeathTooltip)
else
--from a enemy
gameCooltip:AddStatusBar(healthPercent, 1, barTypeColors.damage, showSpark, statusBarBackgroundTable_ForDeathTooltip)
end
else
--heal
if (amount > Details.deathlog_healingdone_min) then
if (combatObject.is_arena) then
if (amount > Details.deathlog_healingdone_min_arena) then
gameCooltip:AddLine("" .. format("%.1f", eventTime - timeOfDeath) .. "s " .. spellName .. " (|c" .. healingSourceColor .. source .. "|r)", "|c" .. healingAmountColor .. "+" .. Details:ToK(amount) .. " (" .. healthPercent .. "%)", 1, "white", "white")
gameCooltip:AddIcon(spellIcon, nil, nil, lineHeight, lineHeight, .1, .9, .1, .9)
gameCooltip:AddStatusBar(healthPercent, 1, barTypeColors.heal, showSpark, statusBarBackgroundTable_ForDeathTooltip)
end
else
gameCooltip:AddLine("" .. format("%.1f", eventTime - timeOfDeath) .. "s " .. spellName .. " (|c" .. healingSourceColor .. source .. "|r)",(event[11] and ("x" .. event[11] .. " ") or "") .. "|c" .. healingAmountColor .. "+" .. Details:ToK(amount) .. " (" .. healthPercent .. "%)", 1, "white", "white")
gameCooltip:AddIcon(spellIcon, nil, nil, lineHeight, lineHeight, .1, .9, .1, .9)
gameCooltip:AddStatusBar(healthPercent, 1, barTypeColors.heal, showSpark, statusBarBackgroundTable_ForDeathTooltip)
end
end
end
elseif (type(evType) == "number") then
if (evType == 1) then
--cooldown
gameCooltip:AddLine("" .. format("%.1f", eventTime - timeOfDeath) .. "s " .. spellName .. " (" .. source .. ")", "cooldown(" .. healthPercent .. "%)", 1, "white", "white")
gameCooltip:AddIcon(spellIcon, nil, nil, lineHeight, lineHeight, .1, .9, .1, .9)
gameCooltip:AddStatusBar(100, 1, barTypeColors.cooldown, showSpark)
elseif (evType == 2 and not battleress) then
--battle ress
battleress = event
elseif (evType == 3) then
--last cooldown used
lastcooldown = event
elseif (evType == 4) then
--debuff
gameCooltip:AddLine("" .. format("%.1f", eventTime - timeOfDeath) .. "s " .. spellName .. " (" .. source .. ")", "x" .. amount .. " " .. AURA_TYPE_DEBUFF .. " (" .. healthPercent .. "%)", 1, "white", "white")
gameCooltip:AddIcon(spellIcon, nil, nil, lineHeight, lineHeight, .1, .9, .1, .9)
gameCooltip:AddStatusBar(100, 1, barTypeColors.debuff, showSpark)
elseif (evType == 5) then
--buff
gameCooltip:AddLine("" .. format("%.1f", eventTime - timeOfDeath) .. "s " .. spellName .. " (" .. source .. ")", "x" .. amount .. " " .. AURA_TYPE_BUFF .. " (" .. healthPercent .. "%)", 1, "white", "white")
gameCooltip:AddIcon(spellIcon, nil, nil, lineHeight, lineHeight, .1, .9, .1, .9)
gameCooltip:AddStatusBar(100, 1, barTypeColors.buff, showSpark)
elseif (evType == 6) then
--enemy cast
gameCooltip:AddLine("" .. format("%.1f", eventTime - timeOfDeath) .. "s " .. spellName .. " (" .. source .. ")", "x" .. amount .. "", 1, "white", "white")
gameCooltip:AddIcon(spellIcon, nil, nil, lineHeight, lineHeight, .1, .9, .1, .9)
local r, g, b, a = DetailsFramework:ParseColors("honeydew")
gameCooltip:AddStatusBar(100, 1, {r, g, b, 0.6}, showSpark)
end
end
end
end
gameCooltip:AddLine(deathTable[6] .. " " .. Loc["STRING_TIME_OF_DEATH"] , "-- -- -- ", 1, "white")
gameCooltip:AddIcon("Interface\\AddOns\\Details\\images\\small_icons", 1, 1, nil, nil, .75, 1, 0, 1)
gameCooltip:AddStatusBar(0, 1, .5, .5, .5, .5, false, {value = 100, color = {.5, .5, .5, 1}, specialSpark = false, texture = [[Interface\AddOns\Details\images\bar4_vidro]]})
if (battleress) then
local spellName, _, spellIcon = _GetSpellInfo(battleress[2])
gameCooltip:AddLine("+" .. format("%.1f", battleress[4] - timeOfDeath) .. "s " .. spellName .. " (" .. battleress[6] .. ")", "", 1, "white")
gameCooltip:AddIcon("Interface\\Glues\\CharacterSelect\\Glues-AddOn-Icons", 1, 1, lineHeight, lineHeight, .75, 1, 0, 1)
gameCooltip:AddStatusBar(0, 1, .5, .5, .5, .5, false, {value = 100, color = {.5, .5, .5, 1}, specialSpark = false, texture = [[Interface\AddOns\Details\images\bar4_vidro]]})
end
if (lastcooldown) then
if (lastcooldown[3] == 1) then
local spellName, _, spellIcon = _GetSpellInfo(lastcooldown[2])
gameCooltip:AddLine(format("%.1f", lastcooldown[4] - timeOfDeath) .. "s " .. spellName .. " (" .. Loc ["STRING_LAST_COOLDOWN"] .. ")")
gameCooltip:AddIcon(spellIcon, 1, 1, lineHeight, lineHeight, .1, .9, .1, .9)
else
gameCooltip:AddLine(Loc ["STRING_NOLAST_COOLDOWN"])
gameCooltip:AddIcon([[Interface\CHARACTERFRAME\UI-Player-PlayTimeUnhealthy]], 1, 1, 18, 18)
end
gameCooltip:AddStatusBar(0, 1, 1, 1, 1, 1, false, {value = 100, color = {.3, .3, .3, 1}, specialSpark = false, texture = [[Interface\AddOns\Details\images\bar_serenity]]})
end
--set the font and size of the text as defined in the options panel
gameCooltip:SetOption("TextSize", Details.tooltip.fontsize)
gameCooltip:SetOption("TextFont", Details.tooltip.fontface)
--move the left and right texts more close to the tooltip border
gameCooltip:SetOption("LeftPadding", -4)
gameCooltip:SetOption("RightPadding", 7)
--space between each line, positive values make the lines be closer
gameCooltip:SetOption("LinePadding", -2)
--move each line in the Y axis(vertical offsett)
gameCooltip:SetOption("LineYOffset", 0)
--tooltip width
gameCooltip:SetOption("FixedWidth",(type(tooltipWidth) == "number" and tooltipWidth) or 300)
--progress bar texture
gameCooltip:SetOption("StatusBarTexture", statusbarTexture)
return true
end
function Details:ToolTipDead(instance, deathTable, barFrame)
local gameCooltip = GameCooltip
local builtTooltip = Details.ShowDeathTooltipFunction(instance, barFrame, instance:GetShowingCombat(), deathTable)
if (builtTooltip) then
local myPoint = Details.tooltip.anchor_point
local anchorPoint = Details.tooltip.anchor_relative
local xOffset = Details.tooltip.anchor_offset[1]
local yOffset = Details.tooltip.anchor_offset[2]
if (Details.tooltip.anchored_to == 1) then
gameCooltip:SetHost(barFrame, myPoint, anchorPoint, xOffset, yOffset)
else
gameCooltip:SetHost(DetailsTooltipAnchor, myPoint, anchorPoint, xOffset, yOffset)
end
gameCooltip:ShowCooltip()
end
end
local function RefreshBarraMorte(morte, barra, instancia)
atributo_misc:UpdateDeathRow(morte, morte.minha_barra, barra.colocacao, instancia)
end
--object death:
--[1] tabela [2] time [3] nome [4] classe [5] maxhealth [6] time of death
--[1] true damage/ false heal [2] spellid [3] amount [4] time [5] current health [6] source
local reportTable = {}
local ReportSingleDeathFunc = function(IsCurrent, IsReverse, AmtLines)
AmtLines = AmtLines + 1
local t = {}
for i = 1, min(#reportTable, AmtLines) do
local table = reportTable [i]
t [#t+1] = table [1] .. table [4] .. table [2] .. table [3]
end
local title = table.remove(t, 1)
t = Details.table.reverse(t)
tinsert(t, 1, title)
Details:SendReportLines(t)
end
function atributo_misc:ReportSingleDeadLine(morte, instancia)
local barra = instancia.barras [morte.minha_barra]
local max_health = morte [5]
local time_of_death = morte [2]
do
if (not Details.fontstring_len) then
Details.fontstring_len = Details.listener:CreateFontString(nil, "background", "GameFontNormal")
end
local _, fontSize = FCF_GetChatWindowInfo(1)
if (fontSize < 1) then
fontSize = 10
end
local fonte, _, flags = Details.fontstring_len:GetFont()
Details.fontstring_len:SetFont(fonte, fontSize, flags)
Details.fontstring_len:SetText("thisisspacement")
end
local default_len = Details.fontstring_len:GetStringWidth()
Details:Destroy(reportTable)
local report_array = reportTable
report_array[1] = {"Details! " .. Loc ["STRING_REPORT_SINGLE_DEATH"] .. " " .. morte [3] .. " " .. Loc ["STRING_ACTORFRAME_REPORTAT"] .. " " .. morte [6], "", "", ""}
for index, evento in ipairs(Details.table.reverse(morte [1])) do
if (evento [1] and type(evento [1]) == "boolean") then --damage
if (evento [3]) then
local elapsed = _cstr("%.1f", evento [4] - time_of_death) .."s"
local spellname, _, spellicon = _GetSpellInfo(evento [2])
local spelllink
if (evento [2] == 1) then
spelllink = GetSpellLink(6603)
elseif (evento [2] > 10) then
spelllink = GetSpellLink(evento [2])
else
spelllink = spellname
end
local source = Details:GetOnlyName(evento [6])
local amount = evento [3]
local hp = _math_floor(evento [5] / max_health * 100)
if (hp > 100) then
hp = 100
end
tinsert(report_array, {elapsed .. " ", spelllink, " (" .. source .. ")", "-" .. Details:ToK(amount) .. " (" .. hp .. "%) "})
end
elseif (not evento [1] and type(evento [1]) == "boolean") then --heal
local amount = evento [3]
if (amount > Details.deathlog_healingdone_min) then
local elapsed = _cstr("%.1f", evento [4] - time_of_death) .."s"
local spelllink = GetSpellLink(evento [2])
local source = Details:GetOnlyName(evento [6])
local spellname, _, spellicon = _GetSpellInfo(evento [2])
local hp = _math_floor(evento [5] / max_health * 100)
if (hp > 100) then
hp = 100
end
if (Details.report_heal_links) then
tinsert(report_array, {elapsed .. " ", spelllink, " (" .. source .. ")", "+" .. Details:ToK(amount) .. " (" .. hp .. "%) "})
else
tinsert(report_array, {elapsed .. " ", spellname, " (" .. source .. ")", "+" .. Details:ToK(amount) .. " (" .. hp .. "%) "})
end
end
elseif (type(evento [1]) == "number" and evento [1] == 4) then --debuff
local elapsed = _cstr("%.1f", evento [4] - time_of_death) .."s"
local spelllink = GetSpellLink(evento [2])
local source = Details:GetOnlyName(evento [6])
local spellname, _, spellicon = _GetSpellInfo(evento [2])
local stacks = evento [3]
local hp = _math_floor(evento [5] / max_health * 100)
if (hp > 100) then
hp = 100
end
tinsert(report_array, {elapsed .. " ", "x" .. stacks .. "" .. spelllink, " (" .. source .. ")", " (" .. hp .. "%) "})
end
end
Details:SendReportWindow(ReportSingleDeathFunc, nil, nil, true)
end
function atributo_misc:ReportSingleCooldownLine(misc_actor, instancia)
local reportar
if (instancia.segmento == -1) then --overall
reportar = {"Details!: " .. misc_actor.nome .. " - " .. Loc ["STRING_OVERALL"] .. " " .. Loc ["STRING_ATTRIBUTE_MISC_DEFENSIVE_COOLDOWNS"]}
else
reportar = {"Details!: " .. misc_actor.nome .. " - " .. Loc ["STRING_ATTRIBUTE_MISC_DEFENSIVE_COOLDOWNS"]}
end
local meu_total = _math_floor(misc_actor.cooldowns_defensive)
local cooldowns = misc_actor.cooldowns_defensive_spells._ActorTable
local cooldowns_used = {}
for spellid, spell in pairs(cooldowns) do
cooldowns_used [#cooldowns_used+1] = {spellid, spell.counter, spell}
end
table.sort(cooldowns_used, Details.Sort2)
for i, spell in ipairs(cooldowns_used) do
local spelllink = GetSpellLink(spell [1])
reportar [#reportar+1] = spelllink .. ": " .. spell [2]
for target_name, amount in pairs(spell[3].targets) do
if (target_name ~= misc_actor.nome and target_name ~= Loc ["STRING_RAID_WIDE"] and amount > 0) then
reportar [#reportar+1] = " -" .. target_name .. ": " .. amount
end
end
end
return Details:Reportar(reportar, {_no_current = true, _no_inverse = true, _custom = true})
end
local buff_format_name = function(spellid)
if (type(spellid) == "string") then
return spellid
end
return Details:GetSpellLink(spellid)
end
local buff_format_amount = function(t)
local total, percent = unpack(t)
local m, s = _math_floor(total / 60), _math_floor(total % 60)
return _cstr("%.1f", percent) .. "%(" .. m .. "m " .. s .. "s)"
end
local sort_buff_report = function(t1, t2)
return t1[2][1] > t2[2][1]
end
function atributo_misc:ReportSingleBuffUptimeLine(misc_actor, instance)
local report_table = {"Details!: " .. misc_actor.nome .. " - " .. Loc ["STRING_ATTRIBUTE_MISC_BUFF_UPTIME"]}
local buffs = {}
local combat_time = floor(instance.showing:GetCombatTime())
for spellid, spellTable in pairs(misc_actor.buff_uptime_spells._ActorTable) do
if (spellTable.uptime and spellTable.uptime > 0) then -- and percent < 99.5
local percent = spellTable.uptime / combat_time * 100
buffs [#buffs+1] = {spellid, {spellTable.uptime, percent}}
end
end
table.sort(buffs, sort_buff_report)
Details:FormatReportLines(report_table, buffs, buff_format_name, buff_format_amount)
return Details:Reportar(report_table, {_no_current = true, _no_inverse = true, _custom = true})
end
function atributo_misc:ReportSingleDebuffUptimeLine(misc_actor, instance)
local report_table = {"Details!: " .. misc_actor.nome .. " - " .. Loc ["STRING_ATTRIBUTE_MISC_DEBUFF_UPTIME"]}
local debuffs = {}
local combat_time = instance.showing:GetCombatTime()
for spellid, spellTable in pairs(misc_actor.debuff_uptime_spells._ActorTable) do
if (spellTable.uptime) then
local percent = spellTable.uptime / combat_time * 100
debuffs [#debuffs+1] = {spellid, {spellTable.uptime, percent}}
end
end
table.sort(debuffs, sort_buff_report)
Details:FormatReportLines(report_table, debuffs, buff_format_name, buff_format_amount)
return Details:Reportar(report_table, {_no_current = true, _no_inverse = true, _custom = true})
end
---index[1] is the death log
---index[2] is the death time
---index[3] is the name of the player
---index[4] is the class of the player
---index[5] is the max health
---index[6] is the time of the fight as string
---update a row in an instance(window) showing death logs
---@param deathTable table
---@param whichRowLine number
---@param rankPosition number
---@param instanceObject table
function atributo_misc:UpdateDeathRow(deathTable, whichRowLine, rankPosition, instanceObject) --todo: change this function name
local playerName, playerClass, deathTime, deathCombatTime, deathTimeString, playerMaxHealth, deathEvents, lastCooldown, spec = Details:UnpackDeathTable(deathTable)
deathTable["dead"] = true
local thisRow = instanceObject.barras[whichRowLine]
if (not thisRow) then
print("DEBUG: problema com <instancia.esta_barra> "..whichRowLine.." "..rankPosition)
return
end
thisRow.minha_tabela = deathTable
deathTable.nome = playerName
deathTable.minha_barra = whichRowLine
thisRow.colocacao = rankPosition
if (not getmetatable(deathTable)) then
setmetatable(deathTable, {__call = RefreshBarraMorte})
deathTable._custom = true
end
local bUseCustomLeftText = instanceObject.row_info.textL_enable_custom_text
local actorObject = instanceObject:GetCombat():GetContainer(DETAILS_ATTRIBUTE_MISC):GetActor(playerName)
if (actorObject) then
actorObject:SetBarLeftText(thisRow, instanceObject, false, false, false, bUseCustomLeftText)
else
Details:SetBarLeftText(thisRow, instanceObject, false, false, false, bUseCustomLeftText)
end
if (instanceObject.row_info.textL_class_colors) then
local textColor_Red, textColor_Green, textColor_Blue = actorObject:GetTextColor(instanceObject, "left")
thisRow.lineText1:SetTextColor(textColor_Red, textColor_Green, textColor_Blue) --the r, g, b color passed are the color used on the bar, so if the bar is not using class color, the text is painted with the fixed color for the bar
end
if (instanceObject.row_info.textR_class_colors) then
local textColor_Red, textColor_Green, textColor_Blue = actorObject:GetTextColor(instanceObject, "right")
thisRow.lineText4:SetTextColor(textColor_Red, textColor_Green, textColor_Blue) --the r, g, b color passed are the color used on the bar, so if the bar is not using class color, the text is painted with the fixed color for the bar
end
thisRow.lineText2:SetText("")
thisRow.lineText3:SetText("")
thisRow.lineText4:SetText(deathTimeString)
local r, g, b, a = actorObject:GetBarColor()
actorObject:SetBarColors(thisRow, instanceObject, r, g, b, a)
thisRow:SetValue(100)
if (thisRow.hidden or thisRow.fading_in or thisRow.faded) then
Details.FadeHandler.Fader(thisRow, "out")
end
if (instanceObject.row_info.use_spec_icons) then
local nome = deathTable[3]
local spec = instanceObject.showing(1, nome) and instanceObject.showing(1, nome).spec or(instanceObject.showing(2, nome) and instanceObject.showing(2, nome).spec)
if (spec and spec ~= 0) then
thisRow.icone_classe:SetTexture(instanceObject.row_info.spec_file)
thisRow.icone_classe:SetTexCoord(unpack(Details.class_specs_coords[spec]))
else
if (CLASS_ICON_TCOORDS [deathTable[4]]) then
thisRow.icone_classe:SetTexture(instanceObject.row_info.icon_file)
thisRow.icone_classe:SetTexCoord(unpack(CLASS_ICON_TCOORDS [deathTable[4]]))
else
local texture, l, r, t, b = Details:GetUnknownClassIcon()
thisRow.icone_classe:SetTexture(texture)
thisRow.icone_classe:SetTexCoord(l, r, t, b)
end
end
else
if (CLASS_ICON_TCOORDS [deathTable[4]]) then
thisRow.icone_classe:SetTexture(instanceObject.row_info.icon_file)
thisRow.icone_classe:SetTexCoord(unpack(CLASS_ICON_TCOORDS [deathTable[4]]))
else
local texture, l, r, t, b = Details:GetUnknownClassIcon()
thisRow.icone_classe:SetTexture(texture)
thisRow.icone_classe:SetTexCoord(l, r, t, b)
end
end
thisRow.icone_classe:SetVertexColor(1, 1, 1)
if (thisRow.mouse_over and not instanceObject.baseframe.isMoving) then --precisa atualizar o tooltip
gump:UpdateTooltip(whichRowLine, thisRow, instanceObject)
end
thisRow.lineText1:SetSize(thisRow:GetWidth() - thisRow.lineText4:GetStringWidth() - 20, 15)
end
function atributo_misc:RefreshWindow(instance, combatObject, bIsForceRefresh, bIsExport)
---@type actorcontainer
local utilityActorContainer = combatObject[class_type]
if (#utilityActorContainer._ActorTable < 1) then --n�o h� barras para mostrar
return Details:HideBarsNotInUse(instance, utilityActorContainer), "", 0, 0
end
local total = 0
instance.top = 0
--the main attribute is utility, the sub attribute is the type of utility(cc break, ress, etc)
local subAttribute = instance.sub_atributo
local conteudo = utilityActorContainer._ActorTable
local amount = #conteudo
local modo = instance.modo
if (bIsExport) then
if (type(bIsExport) == "boolean") then
if (subAttribute == 1) then --CC BREAKS
keyName = "cc_break"
elseif (subAttribute == 2) then --RESS
keyName = "ress"
elseif (subAttribute == 3) then --INTERRUPT
keyName = "interrupt"
elseif (subAttribute == 4) then --DISPELLS
keyName = "dispell"
elseif (subAttribute == 5) then --DEATHS
keyName = "dead"
elseif (subAttribute == 6) then --DEFENSIVE COOLDOWNS
keyName = "cooldowns_defensive"
elseif (subAttribute == 7) then --BUFF UPTIME
keyName = "buff_uptime"
elseif (subAttribute == 8) then --DEBUFF UPTIME
keyName = "debuff_uptime"
end
else
keyName = bIsExport.key
modo = bIsExport.modo
end
elseif (instance.atributo == 5) then --custom
keyName = "custom"
total = combatObject.totals [instance.customName]
else
--pega qual a sub key que ser� usada
if (subAttribute == 1) then --CC BREAKS
keyName = "cc_break"
elseif (subAttribute == 2) then --RESS
keyName = "ress"
elseif (subAttribute == 3) then --INTERRUPT
keyName = "interrupt"
elseif (subAttribute == 4) then --DISPELLS
keyName = "dispell"
elseif (subAttribute == 5) then --DEATHS
keyName = "dead"
elseif (subAttribute == 6) then --DEFENSIVE COOLDOWNS
keyName = "cooldowns_defensive"
elseif (subAttribute == 7) then --BUFF UPTIME
keyName = "buff_uptime"
elseif (subAttribute == 8) then --DEBUFF UPTIME
keyName = "debuff_uptime"
end
end
if (keyName == "dead") then
local allDeathsInTheCombat = combatObject.last_events_tables
instance.top = 1
total = #allDeathsInTheCombat
if (bIsExport) then
return allDeathsInTheCombat
end
if (total < 1) then
instance:EsconderScrollBar()
return Details:EndRefresh(instance, total, combatObject, utilityActorContainer)
end
instance:RefreshScrollBar(total)
local whichRowLine = 1
local bIsRaidCombat = combatObject:GetCombatType() == DETAILS_SEGMENTTYPE_RAID_BOSS
local bIsMythicDungeonOverall = combatObject:IsMythicDungeonOverall()
local bIsOverallData = instance:GetSegmentId() == DETAILS_SEGMENTID_OVERALL
local bReverseDeathLog = false
if (bIsRaidCombat and Details.combat_log.inverse_deathlog_raid) then
bReverseDeathLog = true
elseif (bIsMythicDungeonOverall and Details.combat_log.inverse_deathlog_mplus) then
bReverseDeathLog = true
elseif (bIsOverallData and Details.combat_log.inverse_deathlog_overalldata) then
bReverseDeathLog = true
end
if (bReverseDeathLog) then
--reverse the table
local tempTable = {}
for i = #allDeathsInTheCombat, 1, -1 do
tempTable[#tempTable+1] = allDeathsInTheCombat[i]
end
--update only the lines shown
for i = instance.barraS[1], instance.barraS[2], 1 do
if (tempTable[i]) then
atributo_misc:UpdateDeathRow(tempTable[i], whichRowLine, i, instance)
whichRowLine = whichRowLine+1
end
end
else
--update only the lines shown
for i = instance.barraS[1], instance.barraS[2], 1 do
if (allDeathsInTheCombat[i]) then
atributo_misc:UpdateDeathRow(allDeathsInTheCombat[i], whichRowLine, i, instance)
whichRowLine = whichRowLine+1
end
end
end
return Details:EndRefresh(instance, total, combatObject, utilityActorContainer)
else
if (instance.atributo == 5) then --custom
table.sort(conteudo, Details.SortIfHaveKey)
--strip results with zero
for i = amount, 1, -1 do
if (not conteudo[i][keyName] or conteudo[i][keyName] < 1) then
amount = amount - 1
else
break
end
end
--get the total done from the combat total data
total = combatObject.totals[class_type][keyName]
instance.top = conteudo[1][keyName]
elseif (modo == modo_ALL) then --mostrando ALL
table.sort(conteudo, Details.SortIfHaveKey)
--strip results with zero
for i = amount, 1, -1 do
if (not conteudo[i][keyName] or conteudo[i][keyName] < 1) then
amount = amount - 1
else
break
end
end
--get the total done from the combat total data
total = combatObject.totals[class_type][keyName]
instance.top = conteudo[1][keyName]
elseif (modo == modo_GROUP) then
table.sort(conteudo, Details.SortGroupIfHaveKey)
for index, player in ipairs(conteudo) do
if (player.grupo) then --is a player and is in the player group
--stop when the amount is zero
if (not player[keyName] or player[keyName] < 1) then
amount = index - 1
break
elseif (index == 1) then --esse IF aqui, precisa mesmo ser aqui? n�o daria pra pega-lo com uma chave [1] nad grupo == true?
instance.top = conteudo[1][keyName]
end
total = total + player[keyName]
else
amount = index-1
break
end
end
end
end
--refresh the container map
utilityActorContainer:remapear()
if (bIsExport) then
return total, keyName, instance.top, amount
end
--check if there's nothing to show
if (amount < 1) then
instance:EsconderScrollBar() --precisaria esconder a scroll bar
return Details:EndRefresh(instance, total, combatObject, utilityActorContainer)
end
instance:RefreshScrollBar(amount)
local whichRowLine = 1
local barras_container = instance.barras
local percentage_type = instance.row_info.percent_type
local bars_show_data = instance.row_info.textR_show_data
local bars_brackets = instance:GetBarBracket()
local bars_separator = instance:GetBarSeparator()
local bUseAnimations = Details.is_using_row_animations and (not instance.baseframe.isStretching and not bIsForceRefresh)
if (total == 0) then
total = 0.00000001
end
UsingCustomLeftText = instance.row_info.textL_enable_custom_text
UsingCustomRightText = instance.row_info.textR_enable_custom_text
if (instance.bars_sort_direction == 1) then --top to bottom
for i = instance.barraS[1], instance.barraS[2], 1 do --vai atualizar s� o range que esta sendo mostrado
conteudo[i]:RefreshLine(instance, barras_container, whichRowLine, i, total, subAttribute, bIsForceRefresh, keyName, nil, percentage_type, bUseAnimations, bars_show_data, bars_brackets, bars_separator)
whichRowLine = whichRowLine+1
end
elseif (instance.bars_sort_direction == 2) then --bottom to top
for i = instance.barraS[2], instance.barraS[1], -1 do --vai atualizar s� o range que esta sendo mostrado
if (conteudo[i]) then
conteudo[i]:RefreshLine(instance, barras_container, whichRowLine, i, total, subAttribute, bIsForceRefresh, keyName, nil, percentage_type, bUseAnimations, bars_show_data, bars_brackets, bars_separator)
whichRowLine = whichRowLine+1
end
end
end
if (bUseAnimations) then
instance:PerformAnimations(whichRowLine-1)
end
if (instance.atributo == 5) then --custom
--zerar o .custom dos_ Actors
for index, player in ipairs(conteudo) do
if (player.custom > 0) then
player.custom = 0
else
break
end
end
end
--beta, hidar barras n�o usadas durante um refresh for�ado
if (bIsForceRefresh) then
if (instance.modo == 2) then --group
for i = whichRowLine, instance.rows_fit_in_window do
Details.FadeHandler.Fader(instance.barras [i], "in", Details.fade_speed)
end
end
end
return Details:EndRefresh(instance, total, combatObject, utilityActorContainer) --retorna a tabela que precisa ganhar o refresh
end
local actor_class_color_r, actor_class_color_g, actor_class_color_b
function atributo_misc:RefreshLine(instancia, barras_container, whichRowLine, lugar, total, sub_atributo, forcar, keyName, is_dead, percentage_type, use_animations, bars_show_data, bars_brackets, bars_separator)
local esta_barra = instancia.barras[whichRowLine] --pega a refer�ncia da barra na janela
if (not esta_barra) then
print("DEBUG: problema com <instancia.esta_barra> "..whichRowLine.." "..lugar)
return
end
local tabela_anterior = esta_barra.minha_tabela
---@cast instancia instance
---@type combat
local combatObject = instancia:GetCombat()
esta_barra.minha_tabela = self
esta_barra.colocacao = lugar
self.minha_barra = esta_barra
self.colocacao = lugar
local meu_total = _math_floor(self [keyName] or 0) --total
if (not meu_total) then
return
end
--local porcentagem = meu_total / total * 100
local porcentagem = ""
if (not percentage_type or percentage_type == 1) then
porcentagem = _cstr("%.1f", meu_total / total * 100)
elseif (percentage_type == 2) then
porcentagem = _cstr("%.1f", meu_total / instancia.top * 100)
end
local esta_porcentagem = _math_floor((meu_total/instancia.top) * 100)
if (not bars_show_data [1]) then
meu_total = ""
end
if (not bars_show_data [3]) then
porcentagem = ""
else
porcentagem = porcentagem .. "%"
end
if (instancia.show_interrupt_casts) then
if (sub_atributo == DETAILS_SUBATTRIBUTE_INTERRUPT) then --interrupts
--get the interrupt spell for this actor class from libOpenRaid
if (LIB_OPEN_RAID_SPELL_INTERRUPT_BYCLASS) then
---@type table<spellname, table>
local classInterrupts = LIB_OPEN_RAID_SPELL_INTERRUPT_BYCLASS[self.classe]
if (classInterrupts) then
---@type table<spellname, number> number is the amount of casts
local spellCasts = combatObject.amountCasts[self.nome]
local amountOfInterruptsCasted = 0
--iterating between the spells that are interrupts for this class
for spellNameOrId in pairs(classInterrupts) do
--if the actor casted this spell
if (spellCasts[spellNameOrId]) then
amountOfInterruptsCasted = amountOfInterruptsCasted + spellCasts[spellNameOrId]
end
end
if (amountOfInterruptsCasted > 0) then
meu_total = meu_total .. " (" .. tostring(amountOfInterruptsCasted) .. ")"
end
end
end
end
end
local rightText = meu_total .. bars_brackets[1] .. porcentagem .. bars_brackets[2]
if (UsingCustomRightText) then
esta_barra.lineText4:SetText(_string_replace(instancia.row_info.textR_custom_text, meu_total, "", porcentagem, self, instancia.showing, instancia, rightText))
else
if (instancia.use_multi_fontstrings) then
instancia:SetInLineTexts(esta_barra, "", meu_total, porcentagem)
else
esta_barra.lineText4:SetText(rightText)
end
end
if (esta_barra.mouse_over and not instancia.baseframe.isMoving) then --precisa atualizar o tooltip
gump:UpdateTooltip(whichRowLine, esta_barra, instancia)
end
actor_class_color_r, actor_class_color_g, actor_class_color_b = self:GetBarColor()
return self:RefreshBarra2(esta_barra, instancia, tabela_anterior, forcar, esta_porcentagem, whichRowLine, barras_container, use_animations)
end
function atributo_misc:RefreshBarra2(esta_barra, instancia, tabela_anterior, forcar, esta_porcentagem, whichRowLine, barras_container, use_animations)
--primeiro colocado
if (esta_barra.colocacao == 1) then
if (not tabela_anterior or tabela_anterior ~= esta_barra.minha_tabela or forcar) then
esta_barra:SetValue(100)
if (esta_barra.hidden or esta_barra.fading_in or esta_barra.faded) then
Details.FadeHandler.Fader(esta_barra, "out")
end
return self:RefreshBarra(esta_barra, instancia)
else
return
end
else
if (esta_barra.hidden or esta_barra.fading_in or esta_barra.faded) then
if (use_animations) then
esta_barra.animacao_fim = esta_porcentagem
else
esta_barra:SetValue(esta_porcentagem)
esta_barra.animacao_ignorar = true
end
Details.FadeHandler.Fader(esta_barra, "out")
if (instancia.row_info.texture_class_colors) then
esta_barra.textura:SetVertexColor(actor_class_color_r, actor_class_color_g, actor_class_color_b)
end
if (instancia.row_info.texture_background_class_color) then
esta_barra.background:SetVertexColor(actor_class_color_r, actor_class_color_g, actor_class_color_b)
end
return self:RefreshBarra(esta_barra, instancia)
else
--agora esta comparando se a tabela da barra � diferente da tabela na atualiza��o anterior
if (not tabela_anterior or tabela_anterior ~= esta_barra.minha_tabela or forcar) then --aqui diz se a barra do jogador mudou de posi��o ou se ela apenas ser� atualizada
if (use_animations) then
esta_barra.animacao_fim = esta_porcentagem
else
esta_barra:SetValue(esta_porcentagem)
esta_barra.animacao_ignorar = true
end
esta_barra.last_value = esta_porcentagem --reseta o ultimo valor da barra
return self:RefreshBarra(esta_barra, instancia)
elseif (esta_porcentagem ~= esta_barra.last_value) then --continua mostrando a mesma tabela ent�o compara a porcentagem
--apenas atualizar
if (use_animations) then
esta_barra.animacao_fim = esta_porcentagem
else
esta_barra:SetValue(esta_porcentagem)
end
esta_barra.last_value = esta_porcentagem
return self:RefreshBarra(esta_barra, instancia)
end
end
end
end
function atributo_misc:RefreshBarra(esta_barra, instancia, from_resize)
local class, enemy, arena_enemy, arena_ally = self.classe, self.enemy, self.arena_enemy, self.arena_ally
if (from_resize) then
actor_class_color_r, actor_class_color_g, actor_class_color_b = self:GetBarColor()
end
--icon
self:SetClassIcon(esta_barra.icone_classe, instancia, class)
if (esta_barra.mouse_over) then
local classIcon = esta_barra:GetClassIcon()
esta_barra.iconHighlight:SetTexture(classIcon:GetTexture())
esta_barra.iconHighlight:SetTexCoord(classIcon:GetTexCoord())
esta_barra.iconHighlight:SetVertexColor(classIcon:GetVertexColor())
end
--texture color
self:SetBarColors(esta_barra, instancia, actor_class_color_r, actor_class_color_g, actor_class_color_b)
--left text
self:SetBarLeftText(esta_barra, instancia, enemy, arena_enemy, arena_ally, UsingCustomLeftText)
esta_barra.lineText1:SetSize(esta_barra:GetWidth() - esta_barra.lineText4:GetStringWidth() - 20, 15)
end
--------------------------------------------- // TOOLTIPS // ---------------------------------------------
--~tooltips
function atributo_misc:ToolTip(instance, numero, barFrame, keydown)
GameTooltip:ClearLines()
GameTooltip:AddLine(barFrame.colocacao .. ". " .. self.nome)
if (instance.sub_atributo == 3) then --interrupt
return self:ToolTipInterrupt(instance, numero, barFrame, keydown)
elseif (instance.sub_atributo == 1) then --cc_break
return self:ToolTipCC(instance, numero, barFrame, keydown)
elseif (instance.sub_atributo == 2) then --ress
return self:ToolTipRess(instance, numero, barFrame, keydown)
elseif (instance.sub_atributo == 4) then --dispell
return self:ToolTipDispell(instance, numero, barFrame, keydown)
elseif (instance.sub_atributo == 5) then --mortes
return self:ToolTipDead(instance, numero, barFrame, keydown)
elseif (instance.sub_atributo == 6) then --defensive cooldowns
return self:ToolTipDefensiveCooldowns(instance, numero, barFrame, keydown)
elseif (instance.sub_atributo == 7) then --buff uptime
return self:ToolTipBuffUptime(instance, barFrame)
elseif (instance.sub_atributo == 8) then --debuff uptime
return self:ToolTipDebuffUptime(instance, numero, barFrame, keydown)
end
end
--tooltip locals
local r, g, b
local barAlha = .6
function atributo_misc:ToolTipDead(instancia, numero, barra)
--is this even called?
local last_dead = self.dead_log [#self.dead_log]
Details:Msg("utility class called ToolTipDead, a deprecated function.")
end
function atributo_misc:ToolTipCC(instancia, numero, barra)
local owner = self.owner
if (owner and owner.classe) then
r, g, b = unpack(Details.class_colors [owner.classe])
else
r, g, b = unpack(Details.class_colors [self.classe])
end
local meu_total = self ["cc_break"]
local habilidades = self.cc_break_spells._ActorTable
--habilidade usada para tirar o CC
local icon_size = Details.tooltip.icon_size
local icon_border = Details.tooltip.icon_border_texcoord
local lineHeight = Details.tooltip.line_height
local icon_border = Details.tooltip.icon_border_texcoord
for _spellid, _tabela in pairs(habilidades) do
--quantidade
local nome_magia, _, icone_magia = _GetSpellInfo(_spellid)
GameCooltip:AddLine(nome_magia, _tabela.cc_break .. " (" .. _cstr("%.1f", _tabela.cc_break / meu_total * 100) .. "%)")
GameCooltip:AddIcon(icone_magia, nil, nil, lineHeight, lineHeight, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
--o que quebrou
local quebrou_oque = _tabela.cc_break_oque
for spellid_quebrada, amt_quebrada in pairs(_tabela.cc_break_oque) do
local nome_magia, _, icone_magia = _GetSpellInfo(spellid_quebrada)
GameCooltip:AddLine(nome_magia, amt_quebrada .. " ")
GameCooltip:AddIcon([[Interface\Buttons\UI-GroupLoot-Pass-Down]], nil, 1, 14, 14)
GameCooltip:AddIcon(icone_magia, nil, 2, icon_size.W, icon_size.H, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
GameCooltip:AddStatusBar(100, 1, 1, 0, 0, .2)
end
--em quem quebrou
for target_name, amount in pairs(_tabela.targets) do
GameCooltip:AddLine(target_name .. ": ", amount .. " ")
local classe = Details:GetClass(target_name)
GameCooltip:AddIcon([[Interface\AddOns\Details\images\espadas]], nil, 1, lineHeight, lineHeight)
if (classe) then
GameCooltip:AddIcon([[Interface\AddOns\Details\images\classes_small]], nil, 2, lineHeight, lineHeight, unpack(Details.class_coords [classe]))
else
GameCooltip:AddIcon("Interface\\LFGFRAME\\LFGROLE_BW", nil, 2, lineHeight, lineHeight, .25, .5, 0, 1)
end
Details:AddTooltipBackgroundStatusbar()
end
end
return true
end
function atributo_misc:ToolTipDispell(instancia, numero, barra)
local owner = self.owner
if (owner and owner.classe) then
r, g, b = unpack(Details.class_colors[owner.classe])
else
r, g, b = unpack(Details.class_colors[self.classe])
end
local totalDispels = math.floor(self["dispell"])
local habilidades = self.dispell_spells._ActorTable
--habilidade usada para dispelar
local spellsUsedToDispel = {}
for spellId, spellTable in pairs(habilidades) do
if (spellTable.dispell) then
spellsUsedToDispel[#spellsUsedToDispel+1] = {spellId, math.floor(spellTable.dispell)}
else
--happens when druid uses shapeshift to break root
--Details:Msg("D! table.dispell is invalid. spellId:", spellId)
spellsUsedToDispel[#spellsUsedToDispel+1] = {spellId, math.floor(-1)}
end
end
table.sort(spellsUsedToDispel, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELLS"], headerColor, #spellsUsedToDispel, [[Interface\ICONS\Spell_Arcane_ArcaneTorrent]], 0.078125, 0.9375, 0.078125, 0.953125)
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
local icon_size = Details.tooltip.icon_size
local icon_border = Details.tooltip.icon_border_texcoord
if (#spellsUsedToDispel > 0) then
for i = 1, math.min(25, #spellsUsedToDispel) do
local spellInfo = spellsUsedToDispel[i]
local spellId = spellInfo[1]
local amountDispels = spellInfo[2]
local spellName, _, spellicon = _GetSpellInfo(spellId)
local amountOfDispelsStr = "" .. amountDispels
if (amountDispels == -1) then
amountOfDispelsStr = _G["UNKNOWN"]
end
GameCooltip:AddLine(spellName, amountOfDispelsStr .. " (" .. string.format("%.1f", amountDispels / totalDispels * 100) .. "%)")
GameCooltip:AddIcon(spellicon, nil, nil, icon_size.W, icon_size.H, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
Details:AddTooltipBackgroundStatusbar()
end
else
GameTooltip:AddLine(Loc ["STRING_NO_SPELL"])
end
--quais habilidades foram dispaladas
local dispelledSpells = {}
for spellId, amount in pairs(self.dispell_oque) do
dispelledSpells[#dispelledSpells+1] = {spellId, amount}
end
table.sort(dispelledSpells, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_DISPELLED"], headerColor, #dispelledSpells, [[Interface\ICONS\Spell_Arcane_ManaTap]], 0.078125, 0.9375, 0.078125, 0.953125)
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
if (#dispelledSpells > 0) then
for i = 1, math.min(25, #dispelledSpells) do
local spellInfo = dispelledSpells[i]
local spellId = spellInfo[1]
local amountDispels = spellInfo[2]
local spellName, _, spellIcon = _GetSpellInfo(spellId)
GameCooltip:AddLine(spellName, amountDispels .. " (" .. string.format("%.1f", amountDispels / totalDispels * 100) .. "%)")
GameCooltip:AddIcon(spellIcon, nil, nil, icon_size.W, icon_size.H, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
Details:AddTooltipBackgroundStatusbar()
end
end
--alvos dispelados
local alvos_dispelados = {}
for target_name, amount in pairs(self.dispell_targets) do
alvos_dispelados [#alvos_dispelados + 1] = {target_name, _math_floor(amount), amount / totalDispels * 100}
end
table.sort(alvos_dispelados, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_TARGETS"], headerColor, #alvos_dispelados, [[Interface\ICONS\ACHIEVEMENT_GUILDPERK_EVERYONES A HERO_RANK2]], 0.078125, 0.9375, 0.078125, 0.953125)
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
for i = 1, min(25, #alvos_dispelados) do
if (alvos_dispelados[i][2] < 1) then
break
end
GameCooltip:AddLine(alvos_dispelados[i][1], Details:comma_value(alvos_dispelados[i][2]) .." (".._cstr("%.1f", alvos_dispelados[i][3]).."%)")
Details:AddTooltipBackgroundStatusbar()
local targetActor = instancia.showing[4]:PegarCombatente(_, alvos_dispelados[i][1])
if (targetActor) then
local classe = targetActor.classe
if (not classe) then
classe = "UNKNOW"
end
if (classe == "UNKNOW") then
GameCooltip:AddIcon("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, 14, 14, .25, .5, 0, 1)
else
GameCooltip:AddIcon("Interface\\AddOns\\Details\\images\\classes_small", nil, nil, 14, 14, unpack(Details.class_coords [classe]))
end
end
end
--Pet
local meus_pets = self.pets
if (#meus_pets > 0) then --teve ajudantes
local quantidade = {} --armazena a quantidade de pets iguais
local interrupts = {} --armazena as habilidades
local alvos = {} --armazena os alvos
local totais = {} --armazena o dano total de cada objeto
for index, nome in ipairs(meus_pets) do
if (not quantidade [nome]) then
quantidade [nome] = 1
local my_self = instancia.showing[class_type]:PegarCombatente(nil, nome)
if (my_self and my_self.dispell) then
totais [#totais+1] = {nome, my_self.dispell}
end
else
quantidade [nome] = quantidade [nome]+1
end
end
local _quantidade = 0
local added_logo = false
table.sort(totais, Details.Sort2)
local ismaximized = false
if (keydown == "alt" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 5) then
ismaximized = true
end
for index, _table in ipairs(totais) do
if (_table [2] > 0 and (index < 3 or ismaximized)) then
if (not added_logo) then
added_logo = true
Details:AddTooltipSpellHeaderText(Loc ["STRING_PETS"], headerColor, #totais, [[Interface\COMMON\friendship-heart]], 0.21875, 0.78125, 0.09375, 0.6875)
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
end
local n = _table [1]:gsub(("%s%<.*"), "")
GameCooltip:AddLine(n, _table [2] .. " (" .. _math_floor(_table [2]/self.dispell*100) .. "%)")
Details:AddTooltipBackgroundStatusbar()
GameCooltip:AddIcon([[Interface\AddOns\Details\images\classes_small]], 1, 1, 14, 14, 0.25, 0.49609375, 0.75, 1)
end
end
end
return true
end
local UnitReaction = UnitReaction
function Details:CloseEnemyDebuffsUptime()
local combat = Details:GetCurrentCombat()
local utilityContainer = combat:GetContainer(DETAILS_ATTRIBUTE_MISC)
for _, actor in utilityContainer:ListActors() do
if (actor.boss_debuff) then
for targetName, target in ipairs(actor.debuff_uptime_targets) do
if (target.actived and target.actived_at) then
target.uptime = target.uptime + Details._tempo - target.actived_at
actor.debuff_uptime = actor.debuff_uptime + Details._tempo - target.actived_at
target.actived = false
target.actived_at = nil
end
end
end
end
end
function Details:CatchRaidDebuffUptime(sOperationType) -- "DEBUFF_UPTIME_IN" ~scan
if (sOperationType == "DEBUFF_UPTIME_OUT") then
local combatObject = Details:GetCurrentCombat()
local utilityContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_MISC)
for _, actorObject in utilityContainer:ListActors() do
if (actorObject.debuff_uptime) then
---@type spellcontainer
local debuffUptimeSpellContainer = actorObject.debuff_uptime_spells
for spellId, spellTable in debuffUptimeSpellContainer:ListSpells() do
if (spellTable.actived and spellTable.actived_at) then
spellTable.uptime = spellTable.uptime + Details._tempo - spellTable.actived_at
actorObject.debuff_uptime = actorObject.debuff_uptime + Details._tempo - spellTable.actived_at
spellTable.actived = false
spellTable.actived_at = nil
end
end
end
end
return
elseif (sOperationType == "DEBUFF_UPTIME_IN") then
local cacheGetTime = GetTime()
if (IsInRaid()) then
local checked = {}
local unitIdCache = Details222.UnitIdCache.RaidTargets
for raidIndex = 1, GetNumGroupMembers() do
local target = unitIdCache[raidIndex]
local targetGUID = UnitGUID(target)
if (targetGUID and not checked[targetGUID]) then
local rect = UnitReaction(target, "player")
if (rect and rect <= 4) then
checked [targetGUID] = true
for debuffIndex = 1, 41 do
---@type aurainfo
local auraInfo = C_UnitAuras.GetAuraDataByIndex(target, debuffIndex, "HARMFUL")
if (auraInfo) then
local auraName, unitCaster, spellId = auraInfo.name, auraInfo.sourceUnit, auraInfo.spellId
if (auraName and unitCaster) then
local playerGUID = UnitGUID(unitCaster)
if (playerGUID) then
local playerName, realmName = _UnitName(unitCaster)
if (realmName and realmName ~= "") then
playerName = playerName .. "-" .. realmName
end
Details.parser:add_debuff_uptime(nil, cacheGetTime, playerGUID, playerName, 0x00000417, targetGUID, _UnitName(target), 0x842, nil, spellId, auraName, sOperationType)
end
end
else
break
end
end
end
end
end
elseif (IsInGroup()) then
local checked = {}
for raidIndex = 1, GetNumGroupMembers()-1 do
local his_target = UnitGUID("party"..raidIndex.."target")
local rect = UnitReaction("party"..raidIndex.."target", "player")
if (his_target and not checked[his_target] and rect and rect <= 4) then
checked [his_target] = true
for debuffIndex = 1, 40 do
---@type aurainfo
local auraInfo = C_UnitAuras.GetAuraDataByIndex("party"..raidIndex.."target", debuffIndex, "HARMFUL")
if (auraInfo) then
local auraName, unitCaster, spellId = auraInfo.name, auraInfo.sourceUnit, auraInfo.spellId
if (auraName and unitCaster) then
local playerName, realmName = _UnitName(unitCaster)
local playerGUID = UnitGUID(unitCaster)
if (playerGUID) then
if (realmName and realmName ~= "") then
playerName = playerName .. "-" .. realmName
end
Details.parser:add_debuff_uptime(nil, GetTime(), playerGUID, playerName, 0x00000417, his_target, _UnitName("party"..raidIndex.."target"), 0x842, nil, spellId, auraName, sOperationType)
end
end
else
break
end
end
end
end
local his_target = UnitGUID("playertarget")
local rect = UnitReaction("playertarget", "player")
if (his_target and not checked [his_target] and rect and rect <= 4) then
for debuffIndex = 1, 40 do
---@type aurainfo
local auraInfo = C_UnitAuras.GetAuraDataByIndex("playertarget", debuffIndex, "HARMFUL")
if (auraInfo) then
local auraName, unitCaster, spellId = auraInfo.name, auraInfo.sourceUnit, auraInfo.spellId
if (auraName and unitCaster) then
local playerName, realmName = _UnitName(unitCaster)
local playerGUID = UnitGUID(unitCaster)
if (playerGUID) then
if (realmName and realmName ~= "") then
playerName = playerName .. "-" .. realmName
end
Details.parser:add_debuff_uptime(nil, GetTime(), playerGUID, playerName, 0x00000417, his_target, _UnitName("playertarget"), 0x842, nil, spellId, auraName, sOperationType)
end
end
else
break
end
end
end
else
local his_target = UnitGUID("playertarget")
if (his_target) then
local reaction = UnitReaction("playertarget", "player")
if (reaction and reaction <= 4) then
for debuffIndex = 1, 40 do
---@type aurainfo
local auraInfo = C_UnitAuras.GetAuraDataByIndex("playertarget", debuffIndex, "HARMFUL")
if (auraInfo) then
local auraName, unitCaster, spellId = auraInfo.name, auraInfo.sourceUnit, auraInfo.spellId
if (auraName and unitCaster) then
local playerName, realmName = _UnitName(unitCaster)
local playerGUID = UnitGUID(unitCaster)
if (playerGUID) then
if (realmName and realmName ~= "") then
playerName = playerName .. "-" .. realmName
end
Details.parser:add_debuff_uptime(nil, GetTime(), playerGUID, playerName, 0x00000417, his_target, _UnitName("playertarget"), 0x842, nil, spellId, auraName, sOperationType)
end
end
else
break
end
end
end
end
end
end
end
--this shouldn't be hardcoded
local runeIds = {
[175457] = true, -- focus
[175456] = true, --hyper
[175439] = true, --stout
}
--called from control on leave / enter combat
function Details:CatchRaidBuffUptime(sOperationType) -- ~scan
if (IsInRaid()) then
local potUsage = {}
local focusAugmentation = {}
--raid groups
local cacheGetTime = GetTime()
local unitIdCache = Details222.UnitIdCache.Raid
for raidIndex = 1, GetNumGroupMembers() do
local unitId = unitIdCache[raidIndex]
local playerGUID = UnitGUID(unitId)
if (playerGUID) then
local playerName, realmName = _UnitName(unitId)
if (realmName and realmName ~= "") then
playerName = playerName .. "-" .. realmName
end
for buffIndex = 1, 41 do
---@type aurainfo
local auraInfo = C_UnitAuras.GetAuraDataByIndex(unitId, buffIndex, "HELPFUL")
if (auraInfo) then
local auraName, unitCaster, spellId = auraInfo.name, auraInfo.sourceUnit, auraInfo.spellId
if (unitCaster and UnitExists(unitCaster) and UnitExists(unitId) and UnitIsUnit(unitCaster, unitId)) then
if (auraInfo.duration == 3600) then
Details222.OneHourAuras[spellId] = true
end
Details.parser:add_buff_uptime(nil, cacheGetTime, playerGUID, playerName, 0x00000514, playerGUID, playerName, 0x00000514, 0x0, spellId, auraName, sOperationType)
if (sOperationType == "BUFF_UPTIME_IN") then
if (Details.PotionList[spellId]) then
potUsage[playerName] = spellId
elseif (runeIds[spellId]) then
focusAugmentation[playerName] = true
end
end
end
else
break
end
end
end
end
if (sOperationType == "BUFF_UPTIME_IN") then
local string_output = "pre-potion: " --localize-me
for playername, potspellid in pairs(potUsage) do
local name, _, icon = _GetSpellInfo(potspellid)
local unitClass = Details:GetUnitClass(playername)
local class_color = ""
if (unitClass and RAID_CLASS_COLORS[unitClass]) then
class_color = RAID_CLASS_COLORS[unitClass].colorStr
end
string_output = string_output .. "|c" .. class_color .. playername .. "|r |T" .. icon .. ":14:14:0:0:64:64:0:64:0:64|t "
end
Details.pre_pot_used = string_output
Details:SendEvent("COMBAT_PREPOTION_UPDATED", nil, potUsage, focusAugmentation)
end
elseif (IsInGroup()) then
local potUsage = {}
local focusAugmentation = {}
--party members
for groupIndex = 1, GetNumGroupMembers() - 1 do
local unitId = "party" .. groupIndex
for buffIndex = 1, 41 do
if (UnitExists(unitId)) then
---@type aurainfo
local auraInfo = C_UnitAuras.GetAuraDataByIndex(unitId, buffIndex, "HELPFUL")
if (auraInfo) then
local auraName, unitCaster, spellId = auraInfo.name, auraInfo.sourceUnit, auraInfo.spellId
if (UnitExists(unitCaster)) then
local bBuffIsPlacedOnTarget = Details.CreditBuffToTarget[spellId]
local bUnitIsTheCaster = UnitIsUnit(unitCaster, unitId)
if (bUnitIsTheCaster or bBuffIsPlacedOnTarget) then
if (bBuffIsPlacedOnTarget and not bUnitIsTheCaster) then
--could be prescince, ebom might or power infusion; casted on a target instead of the caster
local sourceSerial = UnitGUID(unitCaster)
local sourceName = Details:GetFullName(unitCaster)
local sourceFlags = 0x514
local targetSerial = UnitGUID(unitId)
local targetName = Details:GetFullName(unitId)
local targetFlags = 0x514
local targetFlags2 = 0x0
local spellName = auraName
Details.parser:buff("SPELL_AURA_APPLIED", time(), sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, 0x4, "BUFF", 0)
elseif (bUnitIsTheCaster) then
local playerGUID = UnitGUID(unitId)
if (playerGUID) then
if (auraInfo.duration == 3600) then
Details222.OneHourAuras[spellId] = true
end
local playerName = Details:GetFullName(unitId)
if (sOperationType == "BUFF_UPTIME_IN") then
if (Details.PotionList[spellId]) then
potUsage[playerName] = spellId
elseif (runeIds[spellId]) then
focusAugmentation [playerName] = true
end
end
Details.parser:add_buff_uptime(nil, GetTime(), playerGUID, playerName, 0x00000417, playerGUID, playerName, 0x00000417, 0x0, spellId, auraName, sOperationType)
end
end
end
end
else
break
end
end
end
end
--player it self(while in a party that isn't a raid group)
local unitId = "player"
for buffIndex = 1, 41 do
---@type aurainfo
local auraInfo = C_UnitAuras.GetAuraDataByIndex(unitId, buffIndex, "HELPFUL")
if (auraInfo) then
local auraName, unitCaster, spellId = auraInfo.name, auraInfo.sourceUnit, auraInfo.spellId
if (auraName and UnitExists(unitCaster)) then -- and unitCaster and UnitExists(unitCaster) and UnitIsUnit(unitCaster, unitId)
local bBuffIsPlacedOnTarget = Details.CreditBuffToTarget[spellId] --give credits to evoker
if (UnitIsUnit(unitCaster, unitId) or bBuffIsPlacedOnTarget) then
if (bBuffIsPlacedOnTarget and not UnitIsUnit(unitCaster, unitId)) then
--could be prescince, ebom might or power infusion; casted on a target instead of the caster
--possible bug: the sOperationType could be BUFF_UP_TIME_OUT and it is calling aura applied, which shoud call aura_removed
local sourceSerial = UnitGUID(unitCaster)
local sourceName = Details:GetFullName(unitCaster)
local sourceFlags = 0x514
local targetSerial = UnitGUID(unitId)
local targetName = Details:GetFullName(unitId)
local targetFlags = 0x514
local targetFlags2 = 0x0
local spellName = auraName
Details.parser:buff("SPELL_AURA_APPLIED", time(), sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags, targetFlags2, spellId, spellName, 0x4, "BUFF", 0)
else
local playerName = Details:GetFullName(unitId)
local playerGUID = UnitGUID(unitId)
if (playerGUID) then
if (auraInfo.duration == 3600) then
Details222.OneHourAuras[spellId] = true
end
if (sOperationType == "BUFF_UPTIME_IN") then
if (Details.PotionList[spellId]) then
potUsage [playerName] = spellId
elseif (runeIds[spellId]) then
focusAugmentation[playerName] = true
end
end
Details.parser:add_buff_uptime(nil, GetTime(), playerGUID, playerName, 0x00000417, playerGUID, playerName, 0x00000417, 0x0, spellId, auraName, sOperationType)
end
end
end
end
else
break
end
end
if (sOperationType == "BUFF_UPTIME_IN") then
local string_output = "pre-potion: "
for playername, potspellid in pairs(potUsage) do
local auraName, _, icon = _GetSpellInfo(potspellid)
local unitClass = Details:GetUnitClass(playername)
local class_color = ""
if (unitClass and RAID_CLASS_COLORS[unitClass]) then
class_color = RAID_CLASS_COLORS[unitClass].colorStr
end
string_output = string_output .. "|c" .. class_color .. playername .. "|r |T" .. icon .. ":14:14:0:0:64:64:0:64:0:64|t "
end
Details.pre_pot_used = string_output
Details:SendEvent("COMBAT_PREPOTION_UPDATED", nil, potUsage, focusAugmentation)
end
else --end of IsInGroup
--player alone
local pot_usage = {}
local focus_augmentation = {}
--print("Combat Ended - details - classutility, OPMODE:", sOperationType)
for buffIndex = 1, 41 do
---@type aurainfo
local auraInfo = C_UnitAuras.GetAuraDataByIndex("player", buffIndex, "HELPFUL")
if (auraInfo) then
local auraName, unitCaster, spellId = auraInfo.name, auraInfo.sourceUnit, auraInfo.spellId
if (auraName and unitCaster and UnitExists(unitCaster) and UnitIsUnit(unitCaster, "player")) then
local playerName = Details.playername
local playerGUID = UnitGUID("player")
if (playerGUID) then
if (auraInfo.duration == 3600) then --1hr buffs, record auras which has 1 hr of duration, hence they can be checked for 100% at the end of the combat
Details222.OneHourAuras[spellId] = true
end
if (sOperationType == "BUFF_UPTIME_IN") then
if (Details.PotionList[spellId]) then
pot_usage[playerName] = spellId
elseif (runeIds[spellId]) then
focus_augmentation[playerName] = true
end
end
--add the uptime, closing the aura time if passing 'BUFF_UPTIME_OUT' on sOperationType
Details.parser:add_buff_uptime(nil, GetTime(), playerGUID, playerName, 0x00000417, playerGUID, playerName, 0x00000417, 0x0, spellId, auraName, sOperationType)
end
end
else
break
end
end
--[
if (sOperationType == "BUFF_UPTIME_IN") then
local string_output = "pre-potion: "
for playername, potspellid in pairs(pot_usage) do
local auraName, _, icon = _GetSpellInfo(potspellid)
local unitClass = Details:GetUnitClass(playername)
local class_color = ""
if (unitClass and RAID_CLASS_COLORS[unitClass]) then
class_color = RAID_CLASS_COLORS[unitClass].colorStr
end
string_output = string_output .. "|c" .. class_color .. playername .. "|r |T" .. icon .. ":14:14:0:0:64:64:0:64:0:64|t "
end
Details.pre_pot_used = string_output
Details:SendEvent("COMBAT_PREPOTION_UPDATED", nil, pot_usage, focus_augmentation)
end
--]]
-- Details:Msg(string_output)
end
if (sOperationType == "BUFF_UPTIME_OUT") then
end
end
local Sort2Reverse = function(a, b)
return a[2] < b[2]
end
function atributo_misc:ToolTipDebuffUptime(instancia, numero, barra)
local owner = self.owner
if (owner and owner.classe) then
r, g, b = unpack(Details.class_colors [owner.classe])
else
r, g, b = unpack(Details.class_colors [self.classe])
end
local meu_total = self ["debuff_uptime"]
local minha_tabela = self.debuff_uptime_spells._ActorTable
--habilidade usada para interromper
local debuffs_usados = {}
local _combat_time = instancia.showing:GetCombatTime()
for _spellid, _tabela in pairs(minha_tabela) do
if (_tabela.uptime and _tabela.uptime > 0) then
debuffs_usados [#debuffs_usados+1] = {_spellid, _tabela.uptime}
end
end
table.sort(debuffs_usados, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELLS"], headerColor, #debuffs_usados, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
local icon_size = Details.tooltip.icon_size
local icon_border = Details.tooltip.icon_border_texcoord
if (#debuffs_usados > 0) then
for i = 1, min(30, #debuffs_usados) do
local esta_habilidade = debuffs_usados[i]
if (esta_habilidade[2] > 0) then
local nome_magia, _, icone_magia = _GetSpellInfo(esta_habilidade[1])
local minutos, segundos = _math_floor(esta_habilidade[2]/60), _math_floor(esta_habilidade[2]%60)
if (esta_habilidade[2] >= _combat_time) then
--GameCooltip:AddLine(nome_magia, minutos .. "m " .. segundos .. "s" .. " (" .. _cstr("%.1f", esta_habilidade[2] / _combat_time * 100) .. "%)", nil, "gray", "gray")
--GameCooltip:AddStatusBar(100, nil, 1, 0, 1, .3, false)
elseif (minutos > 0) then
GameCooltip:AddLine(nome_magia, minutos .. "m " .. segundos .. "s" .. " (" .. _cstr("%.1f", esta_habilidade[2] / _combat_time * 100) .. "%)")
Details:AddTooltipBackgroundStatusbar(false, esta_habilidade[2] / _combat_time * 100)
else
GameCooltip:AddLine(nome_magia, segundos .. "s" .. " (" .. _cstr("%.1f", esta_habilidade[2] / _combat_time * 100) .. "%)")
Details:AddTooltipBackgroundStatusbar(false, esta_habilidade[2] / _combat_time * 100)
end
GameCooltip:AddIcon(icone_magia, nil, nil, icon_size.W, icon_size.H, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
end
end
else
GameCooltip:AddLine(Loc ["STRING_NO_SPELL"])
end
return true
end
function atributo_misc:ToolTipBuffUptime(instance, barFrame)
---@cast instance instance
local owner = self.owner
if (owner and owner.classe) then
r, g, b = unpack(Details.class_colors[owner.classe])
else
r, g, b = unpack(Details.class_colors[self.classe])
end
local combatTime = instance:GetCombat():GetCombatTime()
combatTime = floor(combatTime) --aura update is registered as integers and combat time as float, rouding it to avoid 99.8% uptime issue.
local buffUptimeSpells = self:GetSpellContainer("buff")
local buffUptimeTable = {}
if (buffUptimeSpells) then
for spellId, spellTable in buffUptimeSpells:ListSpells() do
if (not Details.BuffUptimeSpellsToIgnore[spellId]) then
local uptime = spellTable.uptime or 0
if (uptime > 0) then
buffUptimeTable[#buffUptimeTable+1] = {spellId, uptime}
end
end
end
--check if this player has a augmentation buff container
local augmentedBuffContainer = self.received_buffs_spells
if (augmentedBuffContainer) then
for sourceNameSpellId, spellTable in augmentedBuffContainer:ListSpells() do
local sourceName, spellId = strsplit("@", sourceNameSpellId)
spellId = tonumber(spellId)
local spellName, _, spellIcon = Details.GetSpellInfo(spellId)
if (spellName) then
sourceName = detailsFramework:RemoveRealmName(sourceName)
local uptime = spellTable.uptime or 0
buffUptimeTable[#buffUptimeTable+1] = {spellId, uptime, sourceName}
end
end
end
table.sort(buffUptimeTable, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELLS"], headerColor, #buffUptimeTable, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
local iconSizeInfo = Details.tooltip.icon_size
local iconBorderInfo = Details.tooltip.icon_border_texcoord
if (#buffUptimeTable > 0) then
for i = 1, min(30, #buffUptimeTable) do
local uptimeTable = buffUptimeTable[i]
local spellId = uptimeTable[1]
local uptime = uptimeTable[2]
local sourceName = uptimeTable[3]
local uptimePercent = uptime / combatTime * 100
if (uptime > 0) then -- and uptimePercent < 99.5, removed this check to show all buffs, the check was previously added to avoid showing buff that stayed up for the entire fight like stamina, intellect buffs.
local spellName, _, spellIcon = _GetSpellInfo(spellId)
if (sourceName) then
spellName = spellName .. " [" .. sourceName .. "]"
end
if (uptime <= combatTime) then
local minutes, seconds = math.floor(uptime / 60), math.floor(uptime % 60)
if (minutes > 0) then
GameCooltip:AddLine(spellName, minutes .. "m " .. seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)")
Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "green")
else
GameCooltip:AddLine(spellName, seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)")
Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "green")
end
GameCooltip:AddIcon(spellIcon, nil, nil, iconSizeInfo.W, iconSizeInfo.H, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B)
end
end
end
else
GameCooltip:AddLine(Loc ["STRING_NO_SPELL"])
end
else
Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELLS"], headerColor, #buffUptimeTable, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
GameCooltip:AddLine(Loc ["STRING_NO_SPELL"])
end
return true
end
function atributo_misc:ToolTipDefensiveCooldowns(instancia, numero, barra)
local owner = self.owner
if (owner and owner.classe) then
r, g, b = unpack(Details.class_colors [owner.classe])
else
r, g, b = unpack(Details.class_colors [self.classe])
end
local meu_total = _math_floor(self ["cooldowns_defensive"])
local minha_tabela = self.cooldowns_defensive_spells._ActorTable
--spells
local cooldowns_usados = {}
for _spellid, _tabela in pairs(minha_tabela) do
cooldowns_usados [#cooldowns_usados+1] = {_spellid, _tabela.counter}
end
table.sort(cooldowns_usados, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELLS"], headerColor, #cooldowns_usados, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
local icon_size = Details.tooltip.icon_size
local icon_border = Details.tooltip.icon_border_texcoord
local lineHeight = Details.tooltip.line_height
if (#cooldowns_usados > 0) then
for i = 1, min(25, #cooldowns_usados) do
local esta_habilidade = cooldowns_usados[i]
local nome_magia, _, icone_magia = _GetSpellInfo(esta_habilidade[1])
GameCooltip:AddLine(nome_magia, esta_habilidade[2].." (".._cstr("%.1f", esta_habilidade[2]/meu_total*100).."%)")
GameCooltip:AddIcon(icone_magia, nil, nil, icon_size.W, icon_size.H, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
Details:AddTooltipBackgroundStatusbar()
end
else
GameCooltip:AddLine(Loc ["STRING_NO_SPELL"])
end
--targets
local meus_alvos = self.cooldowns_defensive_targets
local alvos = {}
for target_name, amount in pairs(meus_alvos) do
alvos [#alvos+1] = {target_name, amount}
end
table.sort(alvos, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_TARGETS"], headerColor, #alvos, Details.tooltip_target_icon.file, unpack(Details.tooltip_target_icon.coords))
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
if (#alvos > 0) then
for i = 1, min(25, #alvos) do
GameCooltip:AddLine(Details:GetOnlyName(alvos[i][1]) .. ": ", alvos[i][2], 1, "white", "white")
Details:AddTooltipBackgroundStatusbar()
GameCooltip:AddIcon("Interface\\Icons\\PALADIN_HOLY", nil, nil, icon_size.W, icon_size.H, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
local targetActor = instancia.showing[4]:PegarCombatente(_, alvos[i][1])
if (targetActor) then
local classe = targetActor.classe
if (not classe) then
classe = "UNKNOW"
end
if (classe == "UNKNOW") then
GameCooltip:AddIcon("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, 14, 14, .25, .5, 0, 1)
else
local specID = Details:GetSpec(alvos[i][1])
if (specID) then
local texture, l, r, t, b = Details:GetSpecIcon(specID, false)
GameCooltip:AddIcon(texture, 1, 1, lineHeight, lineHeight, l, r, t, b)
else
GameCooltip:AddIcon("Interface\\AddOns\\Details\\images\\classes_small", nil, nil, 14, 14, unpack(Details.class_coords [classe]))
end
end
end
end
end
return true
end
function atributo_misc:ToolTipRess(instancia, numero, barra)
local owner = self.owner
if (owner and owner.classe) then
r, g, b = unpack(Details.class_colors [owner.classe])
else
r, g, b = unpack(Details.class_colors [self.classe])
end
local meu_total = self ["ress"]
local minha_tabela = self.ress_spells._ActorTable
local lineHeight = Details.tooltip.line_height
local icon_border = Details.tooltip.icon_border_texcoord
--habilidade usada para interromper
local meus_ress = {}
for _spellid, _tabela in pairs(minha_tabela) do
meus_ress [#meus_ress+1] = {_spellid, _tabela.ress}
end
table.sort(meus_ress, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELLS"], headerColor, #meus_ress, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
if (#meus_ress > 0) then
for i = 1, min(3, #meus_ress) do
local esta_habilidade = meus_ress[i]
local nome_magia, _, icone_magia = _GetSpellInfo(esta_habilidade[1])
GameCooltip:AddLine(nome_magia, esta_habilidade[2] .. " (" .. _cstr("%.1f", floor(esta_habilidade[2]) / floor(meu_total) * 100).."%)")
GameCooltip:AddIcon(icone_magia, nil, nil, lineHeight, lineHeight, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
Details:AddTooltipBackgroundStatusbar()
end
else
GameCooltip:AddLine(Loc ["STRING_NO_SPELL"])
end
--quem foi que o cara reviveu
local meus_alvos = self.ress_targets
local alvos = {}
for target_name, amount in pairs(meus_alvos) do
alvos [#alvos+1] = {target_name, amount}
end
table.sort(alvos, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_TARGETS"], headerColor, #alvos, Details.tooltip_target_icon.file, unpack(Details.tooltip_target_icon.coords))
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
if (#alvos > 0) then
for i = 1, min(3, #alvos) do
GameCooltip:AddLine(alvos[i][1], alvos[i][2])
Details:AddTooltipBackgroundStatusbar()
local targetActor = instancia.showing[4]:PegarCombatente(_, alvos[i][1])
if (targetActor) then
local classe = targetActor.classe
if (not classe) then
classe = "UNKNOW"
end
if (classe == "UNKNOW") then
GameCooltip:AddIcon("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, lineHeight, lineHeight, .25, .5, 0, 1)
else
local specID = Details:GetSpec(alvos[i][1])
if (specID) then
local texture, l, r, t, b = Details:GetSpecIcon(specID, false)
GameCooltip:AddIcon(texture, 1, 1, lineHeight, lineHeight, l, r, t, b)
else
GameCooltip:AddIcon("Interface\\AddOns\\Details\\images\\classes_small", nil, nil, lineHeight, lineHeight, unpack(Details.class_coords [classe]))
end
end
end
end
end
return true
end
function atributo_misc:ToolTipInterrupt(instancia, numero, barra)
local owner = self.owner
if (owner and owner.classe) then
r, g, b = unpack(Details.class_colors [owner.classe])
else
r, g, b = unpack(Details.class_colors [self.classe])
end
local meu_total = self ["interrupt"]
local minha_tabela = self.interrupt_spells._ActorTable
local icon_size = Details.tooltip.icon_size
local icon_border = Details.tooltip.icon_border_texcoord
local lineHeight = Details.tooltip.line_height
--habilidade usada para interromper
local actorInterrupts = {}
for _spellid, _tabela in pairs(minha_tabela) do
actorInterrupts [#actorInterrupts+1] = {_spellid, _tabela.counter}
end
table.sort(actorInterrupts, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELLS"], headerColor, #actorInterrupts, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
if (#actorInterrupts > 0) then
for i = 1, min(25, #actorInterrupts) do
local esta_habilidade = actorInterrupts[i]
local nome_magia, _, icone_magia = _GetSpellInfo(esta_habilidade[1])
GameCooltip:AddLine(nome_magia, esta_habilidade[2].." (".._cstr("%.1f", floor(esta_habilidade[2])/floor(meu_total)*100).."%)")
GameCooltip:AddIcon(icone_magia, nil, nil, icon_size.W, icon_size.H, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
Details:AddTooltipBackgroundStatusbar()
end
else
GameTooltip:AddLine(Loc ["STRING_NO_SPELL"])
end
--quais habilidades foram interrompidas
local interruptedSpells = {}
for _spellid, amt in pairs(self.interrompeu_oque) do
interruptedSpells [#interruptedSpells+1] = {_spellid, amt}
end
table.sort(interruptedSpells, Details.Sort2)
Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELL_INTERRUPTED"] .. ":", headerColor, #interruptedSpells, Details.tooltip_target_icon.file, unpack(Details.tooltip_target_icon.coords))
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
if (#interruptedSpells > 0) then
for i = 1, min(25, #interruptedSpells) do
local esta_habilidade = interruptedSpells[i]
local nome_magia, _, icone_magia = _GetSpellInfo(esta_habilidade[1])
GameCooltip:AddLine(nome_magia, esta_habilidade[2].." (".._cstr("%.1f", floor(esta_habilidade[2])/floor(meu_total)*100).."%)")
GameCooltip:AddIcon(icone_magia, nil, nil, icon_size.W, icon_size.H, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
Details:AddTooltipBackgroundStatusbar()
end
end
--Pet
local allActorPets = self.pets
if (#allActorPets > 0) then --teve ajudantes
local quantidade = {} --armazena a quantidade de pets iguais
local interrupts = {} --armazena as habilidades
local alvos = {} --armazena os alvos
local totais = {} --armazena o dano total de cada objeto
for index, nome in ipairs(allActorPets) do
if (not quantidade [nome]) then
quantidade [nome] = 1
local my_self = instancia.showing[class_type]:PegarCombatente(nil, nome)
if (my_self and my_self.interrupt) then
totais [#totais+1] = {nome, my_self.interrupt}
end
else
quantidade [nome] = quantidade [nome]+1
end
end
local _quantidade = 0
local added_logo = false
table.sort(totais, Details.Sort2)
local ismaximized = false
if (keydown == "alt" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 5) then
ismaximized = true
end
for index, _table in ipairs(totais) do
if (_table [2] > 0 and (index < 3 or ismaximized)) then
if (not added_logo) then
added_logo = true
Details:AddTooltipSpellHeaderText(Loc ["STRING_PETS"], headerColor, #totais, [[Interface\COMMON\friendship-heart]], 0.21875, 0.78125, 0.09375, 0.6875)
Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
end
local n = _table [1]:gsub(("%s%<.*"), "")
GameCooltip:AddLine(n, _table [2] .. " (" .. _math_floor(_table [2]/self.interrupt*100) .. "%)")
Details:AddTooltipBackgroundStatusbar()
GameCooltip:AddIcon([[Interface\AddOns\Details\images\classes_small]], 1, 1, 14, 14, 0.25, 0.49609375, 0.75, 1)
end
end
end
return true
end
--------------------------------------------- // JANELA DETALHES // ---------------------------------------------
---------DETALHES BIFURCA��O
function atributo_misc:MontaInfo()
if (breakdownWindowFrame.sub_atributo == 3) then --interrupt
return self:MontaInfoInterrupt()
end
end
---------DETALHES bloco da direita BIFURCA��O
function atributo_misc:MontaDetalhes(spellid, barra)
if (breakdownWindowFrame.sub_atributo == 3) then --interrupt
return self:MontaDetalhesInterrupt(spellid, barra)
end
end
------ Interrupt
function atributo_misc:MontaInfoInterrupt()
local meu_total = self ["interrupt"]
if (not self.interrupt_spells) then
return
end
local minha_tabela = self.interrupt_spells._ActorTable
local barras = breakdownWindowFrame.barras1
local instancia = breakdownWindowFrame.instancia
local meus_interrupts = {}
--player
for _spellid, _tabela in pairs(minha_tabela) do --da foreach em cada spellid do container
local nome, _, icone = _GetSpellInfo(_spellid)
tinsert(meus_interrupts, {_spellid, _tabela.counter, _tabela.counter/meu_total*100, nome, icone})
end
--pet
local ActorPets = self.pets
local class_color = "FFDDDDDD"
for _, PetName in ipairs(ActorPets) do
local PetActor = instancia.showing(class_type, PetName)
if (PetActor and PetActor.interrupt and PetActor.interrupt > 0) then
local PetSkillsContainer = PetActor.interrupt_spells._ActorTable
for _spellid, _skill in pairs(PetSkillsContainer) do --da foreach em cada spellid do container
local nome, _, icone = _GetSpellInfo(_spellid)
tinsert(meus_interrupts, {_spellid, _skill.counter, _skill.counter/meu_total*100, nome .. " (|c" .. class_color .. PetName:gsub((" <.*"), "") .. "|r)", icone, PetActor})
end
end
end
table.sort(meus_interrupts, Details.Sort2)
local amt = #meus_interrupts
gump:JI_AtualizaContainerBarras(amt)
local max_ = meus_interrupts [1][2] --dano que a primeiro magia vez
local barra
for index, tabela in ipairs(meus_interrupts) do
barra = barras [index]
if (not barra) then --se a barra n�o existir, criar ela ent�o
barra = gump:CriaNovaBarraInfo1(instancia, index)
barra.textura:SetStatusBarColor(1, 1, 1, 1) --isso aqui � a parte da sele��o e descele��o
barra.on_focus = false --isso aqui � a parte da sele��o e descele��o
end
--isso aqui � tudo da sele��o e descele��o das barras
if (not breakdownWindowFrame.mostrando_mouse_over) then
if (tabela[1] == self.detalhes) then --tabela [1] = spellid = spellid que esta na caixa da direita
if (not barra.on_focus) then --se a barra n�o tiver no foco
barra.textura:SetStatusBarColor(129/255, 125/255, 69/255, 1)
barra.on_focus = true
if (not breakdownWindowFrame.mostrando) then
breakdownWindowFrame.mostrando = barra
end
end
else
if (barra.on_focus) then
barra.textura:SetStatusBarColor(1, 1, 1, 1) --volta a cor antiga
barra:SetAlpha(.9) --volta a alfa antiga
barra.on_focus = false
end
end
end
if (index == 1) then
barra.textura:SetValue(100)
else
barra.textura:SetValue(tabela[2]/max_*100) --muito mais rapido...
end
barra.lineText1:SetText(index..instancia.divisores.colocacao..tabela[4]) --seta o texto da esqueda
barra.lineText4:SetText(tabela[2] .." ".. instancia.divisores.abre .._cstr("%.1f", tabela[3]) .."%".. instancia.divisores.fecha) --seta o texto da direita
barra.icone:SetTexture(tabela[5])
barra.minha_tabela = self --grava o jogador na barrinho... � estranho pq todas as barras v�o ter o mesmo valor do jogador
barra.show = tabela[1] --grava o spellid na barra
barra:Show() --mostra a barra
if (self.detalhes and self.detalhes == barra.show) then
self:MontaDetalhes(self.detalhes, barra) --poderia deixar isso pro final e montar uma tail call??
end
end
--Alvos do interrupt
local meus_alvos = {}
for target_name, amount in pairs(self.interrupt_targets) do
meus_alvos [#meus_alvos+1] = {target_name, amount}
end
table.sort(meus_alvos, Details.Sort2)
local amt_alvos = #meus_alvos
if (amt_alvos < 1) then
return
end
gump:JI_AtualizaContainerAlvos(amt_alvos)
local max_alvos = meus_alvos[1][2]
local barra
for index, tabela in ipairs(meus_alvos) do
barra = breakdownWindowFrame.barras2 [index]
if (not barra) then
barra = gump:CriaNovaBarraInfo2(instancia, index)
barra.textura:SetStatusBarColor(1, 1, 1, 1)
end
if (index == 1) then
barra.textura:SetValue(100)
else
barra.textura:SetValue(tabela[2]/max_alvos*100)
end
barra.lineText1:SetText(index..instancia.divisores.colocacao..tabela[1]) --seta o texto da esqueda
barra.lineText4:SetText(tabela[2] .." ".. instancia.divisores.abre .._cstr("%.1f", tabela[2]/meu_total*100) .. instancia.divisores.fecha) --seta o texto da direita
if (barra.mouse_over) then --atualizar o tooltip
if (barra.isAlvo) then
GameTooltip:Hide()
GameTooltip:SetOwner(barra, "ANCHOR_TOPRIGHT")
if (not barra.minha_tabela:MontaTooltipAlvos(barra, index)) then
return
end
GameTooltip:Show()
end
end
barra.minha_tabela = self --grava o jogador na tabela
barra.nome_inimigo = tabela [1] --salva o nome do inimigo na barra --isso � necess�rio?
barra:Show()
end
end
------ Detalhe Info Interrupt
function atributo_misc:MontaDetalhesInterrupt(spellid, barra)
local esta_magia = self.interrupt_spells._ActorTable [spellid]
if (not esta_magia) then
return
end
--icone direito superior
local nome, _, icone = _GetSpellInfo(spellid)
local infospell = {nome, nil, icone}
Details.BreakdownWindowFrame.spell_icone:SetTexture(infospell[3])
local total = self.interrupt
local meu_total = esta_magia.counter
local index = 1
local data = {}
local barras = breakdownWindowFrame.barras3
local instancia = breakdownWindowFrame.instancia
local habilidades_alvos = {}
for spellid, amt in pairs(esta_magia.interrompeu_oque) do
habilidades_alvos [#habilidades_alvos+1] = {spellid, amt}
end
table.sort(habilidades_alvos, Details.Sort2)
local max_ = habilidades_alvos[1][2]
local lastIndex = 1
local barra
for index, tabela in ipairs(habilidades_alvos) do
lastIndex = index
barra = barras [index]
if (not barra) then --se a barra n�o existir, criar ela ent�o
barra = gump:CriaNovaBarraInfo3(instancia, index)
barra.textura:SetStatusBarColor(1, 1, 1, 1) --isso aqui � a parte da sele��o e descele��o
end
barra.show = tabela[1]
if (index == 1) then
barra.textura:SetValue(100)
else
barra.textura:SetValue(tabela[2]/max_*100) --muito mais rapido...
end
local nome, _, icone = _GetSpellInfo(tabela[1])
barra.lineText1:SetText(index..instancia.divisores.colocacao..nome) --seta o texto da esqueda
barra.lineText4:SetText(tabela[2] .." ".. instancia.divisores.abre .._cstr("%.1f", tabela[2]/total*100) .."%".. instancia.divisores.fecha) --seta o texto da direita
barra.icone:SetTexture(icone)
barra:Show() --mostra a barra
if (index == 15) then
break
end
end
for i = lastIndex+1, #barras do
barras[i]:Hide()
end
end
function atributo_misc:MontaTooltipAlvos(esta_barra, index)
local inimigo = esta_barra.nome_inimigo
local container
if (breakdownWindowFrame.instancia.sub_atributo == 3) then --interrupt
container = self.interrupt_spells._ActorTable
end
local habilidades = {}
local total = self.interrupt
for spellid, tabela in pairs(container) do
--tabela = classe_damage_habilidade
local alvos = tabela.targets
for target_name, amount in ipairs(alvos) do
--tabela = classe_target
if (target_name == inimigo) then
habilidades [#habilidades+1] = {spellid, amount}
end
end
end
table.sort(habilidades, Details.Sort2)
GameTooltip:AddLine(index..". "..inimigo)
GameTooltip:AddLine(Loc ["STRING_SPELL_INTERRUPTED"] .. ":")
GameTooltip:AddLine(" ")
for index, tabela in ipairs(habilidades) do
local nome, rank, icone = _GetSpellInfo(tabela[1])
if (index < 8) then
GameTooltip:AddDoubleLine(index..". |T"..icone..":0|t "..nome, tabela[2].." (".._cstr("%.1f", tabela[2]/total*100).."%)", 1, 1, 1, 1, 1, 1)
else
GameTooltip:AddDoubleLine(index..". "..nome, tabela[2].." (".._cstr("%.1f", tabela[2]/total*100).."%)", .65, .65, .65, .65, .65, .65)
end
end
return true
end
--controla se o dps do jogador esta travado ou destravado
function atributo_misc:GetOrChangeActivityStatus(iniciar)
return false --retorna se o dps esta aberto ou fechado para este jogador
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--core functions
--atualize a funcao de abreviacao
function atributo_misc:UpdateSelectedToKFunction()
SelectedToKFunction = ToKFunctions [Details.ps_abbreviation]
FormatTooltipNumber = ToKFunctions [Details.tooltip.abbreviation]
TooltipMaximizedMethod = Details.tooltip.maximize_method
headerColor = Details.tooltip.header_text_color
end
local sub_list = {"cc_break", "ress", "interrupt", "cooldowns_defensive", "dispell", "dead"}
--subtract total from a combat table
function atributo_misc:subtract_total(combat_table)
for _, sub_attribute in ipairs(sub_list) do
if (self [sub_attribute]) then
combat_table.totals [class_type][sub_attribute] = combat_table.totals [class_type][sub_attribute] - self [sub_attribute]
if (self.grupo) then
combat_table.totals_grupo [class_type][sub_attribute] = combat_table.totals_grupo [class_type][sub_attribute] - self [sub_attribute]
end
end
end
end
function atributo_misc:add_total(combat_table)
for _, sub_attribute in ipairs(sub_list) do
if (self [sub_attribute]) then
combat_table.totals [class_type][sub_attribute] = combat_table.totals [class_type][sub_attribute] + self [sub_attribute]
if (self.grupo) then
combat_table.totals_grupo [class_type][sub_attribute] = combat_table.totals_grupo [class_type][sub_attribute] + self [sub_attribute]
end
end
end
end
local refresh_alvos = function(container1, container2)
for target_name, amount in pairs(container2) do
container1 [target_name] = container1 [target_name] or 0
end
end
local refresh_habilidades = function(container1, container2)
for spellid, habilidade in pairs(container2._ActorTable) do
local habilidade_shadow = container1:PegaHabilidade(spellid, true, nil, true)
refresh_alvos(habilidade_shadow.targets , habilidade.targets)
end
end
function atributo_misc:r_onlyrefresh_shadow(actor)
local overall_misc = Details.tabela_overall [4]
local shadow = overall_misc._ActorTable [overall_misc._NameIndexTable [actor.nome]]
if (not actor.nome) then
actor.nome = "unknown"
end
if (not shadow) then
shadow = overall_misc:PegarCombatente(actor.serial, actor.nome, actor.flag_original, true)
shadow.classe = actor.classe
shadow:SetSpecId(actor.spec)
shadow.grupo = actor.grupo
shadow.pvp = actor.pvp
shadow.isTank = actor.isTank
shadow.boss = actor.boss
shadow.boss_fight_component = actor.boss_fight_component
shadow.fight_component = actor.fight_component
end
Details.refresh:r_atributo_misc(actor, shadow)
--cc done
if (actor.cc_done) then
refresh_alvos(shadow.cc_done_targets, actor.cc_done_targets)
refresh_habilidades(shadow.cc_done_spells, actor.cc_done_spells)
end
--cooldowns
if (actor.cooldowns_defensive) then
refresh_alvos(shadow.cooldowns_defensive_targets, actor.cooldowns_defensive_targets)
refresh_habilidades(shadow.cooldowns_defensive_spells, actor.cooldowns_defensive_spells)
end
--buff uptime
if (actor.buff_uptime) then
refresh_alvos(shadow.buff_uptime_targets, actor.buff_uptime_targets)
refresh_habilidades(shadow.buff_uptime_spells, actor.buff_uptime_spells)
if (actor.received_buffs_spells) then
if (not shadow.received_buffs_spells) then
shadow.received_buffs_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
refresh_habilidades(shadow.received_buffs_spells, actor.received_buffs_spells)
end
end
--debuff uptime
if (actor.debuff_uptime) then
refresh_habilidades(shadow.debuff_uptime_spells, actor.debuff_uptime_spells)
if (actor.boss_debuff) then
--
else
refresh_alvos(shadow.debuff_uptime_targets, actor.debuff_uptime_targets)
end
end
--interrupt
if (actor.interrupt) then
refresh_alvos(shadow.interrupt_targets, actor.interrupt_targets)
refresh_habilidades(shadow.interrupt_spells, actor.interrupt_spells)
for spellid, habilidade in pairs(actor.interrupt_spells._ActorTable) do
local habilidade_shadow = shadow.interrupt_spells:PegaHabilidade(spellid, true, nil, true)
habilidade_shadow.interrompeu_oque = habilidade_shadow.interrompeu_oque or {}
end
end
--ress
if (actor.ress) then
refresh_alvos(shadow.ress_targets, actor.ress_targets)
refresh_habilidades(shadow.ress_spells, actor.ress_spells)
end
--dispell
if (actor.dispell) then
refresh_alvos(shadow.dispell_targets, actor.dispell_targets)
refresh_habilidades(shadow.dispell_spells, actor.dispell_spells)
for spellid, habilidade in pairs(actor.dispell_spells._ActorTable) do
local habilidade_shadow = shadow.dispell_spells:PegaHabilidade(spellid, true, nil, true)
habilidade_shadow.dispell_oque = habilidade_shadow.dispell_oque or {}
end
end
--cc break
if (actor.cc_break) then
refresh_alvos(shadow.cc_break_targets, actor.cc_break_targets)
refresh_habilidades(shadow.cc_break_spells, actor.cc_break_spells)
for spellid, habilidade in pairs(actor.cc_break_spells._ActorTable) do
local habilidade_shadow = shadow.cc_break_spells:PegaHabilidade(spellid, true, nil, true)
habilidade_shadow.cc_break_oque = habilidade_shadow.cc_break_oque or {}
end
end
return shadow
end
local sumKeyValues = function(habilidade, habilidade_tabela1)
for key, value in pairs(habilidade) do
if (type(value) == "number") then
if (key ~= "id" and key ~= "spellschool") then
habilidade_tabela1[key] = (habilidade_tabela1[key] or 0) + value
end
end
end
end
local sumTargetValues = function(container1, container2)
for targetName, amount in pairs(container2) do
container1[targetName] = (container1[targetName] or 0) + amount
end
end
local sumSpellTableKeyValues = function(container1, container2)
for spellId, spellTable in pairs(container2._ActorTable) do
local spellTable1 = container1:PegaHabilidade(spellId, true, nil, false)
sumTargetValues(spellTable1.targets, spellTable.targets)
sumKeyValues(spellTable, spellTable1)
end
end
function atributo_misc:r_connect_shadow(actor, no_refresh, combat_object)
local host_combat = combat_object or Details.tabela_overall
--criar uma shadow desse ator se ainda n�o tiver uma
local overall_misc = host_combat[4]
local shadow = overall_misc._ActorTable[overall_misc._NameIndexTable[actor.nome]]
if (not actor.nome) then
actor.nome = "unknown"
end
if (not shadow) then
shadow = overall_misc:PegarCombatente(actor.serial, actor.nome, actor.flag_original, true)
shadow.classe = actor.classe
shadow:SetSpecId(actor.spec)
shadow.grupo = actor.grupo
shadow.pvp = actor.pvp
shadow.isTank = actor.isTank
shadow.boss = actor.boss
shadow.boss_fight_component = actor.boss_fight_component
shadow.fight_component = actor.fight_component
end
--aplica a meta e indexes
if (not no_refresh) then
Details.refresh:r_atributo_misc(actor, shadow)
end
--pets(add unique pet names)
for _, petName in ipairs(actor.pets) do
DetailsFramework.table.addunique(shadow.pets, petName)
end
if (actor.cleu_prescience_time) then
local shadowPrescienceStackData = shadow.cleu_prescience_time
if (not shadowPrescienceStackData) then
shadow.cleu_prescience_time = detailsFramework.table.copy({}, actor.cleu_prescience_time)
else
for amountOfPrescienceApplied, time in pairs(actor.cleu_prescience_time.stackTime) do
shadow.cleu_prescience_time.stackTime[amountOfPrescienceApplied] = shadow.cleu_prescience_time.stackTime[amountOfPrescienceApplied] + time
end
end
end
if (actor.cc_done) then
if (not shadow.cc_done_targets) then
shadow.cc_done = Details:GetOrderNumber()
shadow.cc_done_targets = {}
shadow.cc_done_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
shadow.cc_done = shadow.cc_done + actor.cc_done
sumTargetValues(shadow.cc_done_targets, actor.cc_done_targets)
sumSpellTableKeyValues(shadow.cc_done_spells, actor.cc_done_spells)
end
if (actor.cooldowns_defensive) then
if (not shadow.cooldowns_defensive_targets) then
shadow.cooldowns_defensive = Details:GetOrderNumber(actor.nome)
shadow.cooldowns_defensive_targets = {}
shadow.cooldowns_defensive_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
shadow.cooldowns_defensive = shadow.cooldowns_defensive + actor.cooldowns_defensive
host_combat.totals[4].cooldowns_defensive = host_combat.totals[4].cooldowns_defensive + actor.cooldowns_defensive
if (actor.grupo) then
host_combat.totals_grupo[4].cooldowns_defensive = host_combat.totals_grupo[4].cooldowns_defensive + actor.cooldowns_defensive
end
sumTargetValues(shadow.cooldowns_defensive_targets, actor.cooldowns_defensive_targets)
sumSpellTableKeyValues(shadow.cooldowns_defensive_spells, actor.cooldowns_defensive_spells)
end
if (actor.buff_uptime) then
if (not shadow.buff_uptime_targets) then
shadow.buff_uptime = 0
shadow.buff_uptime_targets = {}
shadow.buff_uptime_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
if (actor.received_buffs_spells) then
if (not shadow.received_buffs_spells) then
shadow.received_buffs_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
sumSpellTableKeyValues(shadow.received_buffs_spells, actor.received_buffs_spells)
end
shadow.buff_uptime = shadow.buff_uptime + actor.buff_uptime
sumTargetValues(shadow.buff_uptime_targets, actor.buff_uptime_targets)
sumSpellTableKeyValues(shadow.buff_uptime_spells, actor.buff_uptime_spells)
end
if (actor.debuff_uptime) then
if (not shadow.debuff_uptime_targets) then
shadow.debuff_uptime = 0
if (actor.boss_debuff) then
shadow.debuff_uptime_targets = {}
shadow.boss_debuff = true
shadow.damage_twin = actor.damage_twin
shadow.spellschool = actor.spellschool
shadow.damage_spellid = actor.damage_spellid
shadow.debuff_uptime = 0
else
shadow.debuff_uptime_targets = {}
end
shadow.debuff_uptime_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
shadow.debuff_uptime = shadow.debuff_uptime + actor.debuff_uptime
for target_name, amount in pairs(actor.debuff_uptime_targets) do
if (type(amount) == "table") then --boss debuff
local t = shadow.debuff_uptime_targets [target_name]
if (not t) then
shadow.debuff_uptime_targets [target_name] = atributo_misc:CreateBuffTargetObject()
t = shadow.debuff_uptime_targets [target_name]
end
t.uptime = t.uptime + amount.uptime
t.activedamt = t.activedamt + amount.activedamt
t.refreshamt = t.refreshamt + amount.refreshamt
t.appliedamt = t.appliedamt + amount.appliedamt
else
shadow.debuff_uptime_targets [target_name] = (shadow.debuff_uptime_targets [target_name] or 0) + amount
end
end
sumSpellTableKeyValues(shadow.debuff_uptime_spells, actor.debuff_uptime_spells)
end
--interrupt
if (actor.interrupt) then
if (not shadow.interrupt_targets) then
shadow.interrupt = 0
shadow.interrupt_targets = {}
shadow.interrupt_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS) --cria o container das habilidades usadas para interromper
shadow.interrompeu_oque = {}
end
shadow.interrupt = shadow.interrupt + actor.interrupt
host_combat.totals[4].interrupt = host_combat.totals[4].interrupt + actor.interrupt
if (actor.grupo) then
host_combat.totals_grupo[4].interrupt = host_combat.totals_grupo[4].interrupt + actor.interrupt
end
sumTargetValues(shadow.interrupt_targets, actor.interrupt_targets)
sumSpellTableKeyValues(shadow.interrupt_spells, actor.interrupt_spells)
for spellid, habilidade in pairs(actor.interrupt_spells._ActorTable) do
local habilidade_shadow = shadow.interrupt_spells:PegaHabilidade(spellid, true, nil, true)
habilidade_shadow.interrompeu_oque = habilidade_shadow.interrompeu_oque or {}
for _spellid, amount in pairs(habilidade.interrompeu_oque) do
habilidade_shadow.interrompeu_oque [_spellid] = (habilidade_shadow.interrompeu_oque [_spellid] or 0) + amount
end
end
for spellid, amount in pairs(actor.interrompeu_oque) do
shadow.interrompeu_oque [spellid] = (shadow.interrompeu_oque [spellid] or 0) + amount
end
end
--ress
if (actor.ress) then
if (not shadow.ress_targets) then
shadow.ress = 0
shadow.ress_targets = {}
shadow.ress_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
shadow.ress = shadow.ress + actor.ress
host_combat.totals[4].ress = host_combat.totals[4].ress + actor.ress
if (actor.grupo) then
host_combat.totals_grupo[4].ress = host_combat.totals_grupo[4].ress + actor.ress
end
sumTargetValues(shadow.ress_targets, actor.ress_targets)
sumSpellTableKeyValues(shadow.ress_spells, actor.ress_spells)
end
--dispell
if (actor.dispell) then
if (not shadow.dispell_targets) then
shadow.dispell = 0
shadow.dispell_targets = {}
shadow.dispell_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
shadow.dispell_oque = {}
end
shadow.dispell = shadow.dispell + actor.dispell
host_combat.totals[4].dispell = host_combat.totals[4].dispell + actor.dispell
if (actor.grupo) then
host_combat.totals_grupo[4].dispell = host_combat.totals_grupo[4].dispell + actor.dispell
end
sumTargetValues(shadow.dispell_targets, actor.dispell_targets)
sumSpellTableKeyValues(shadow.dispell_spells, actor.dispell_spells)
for spellid, habilidade in pairs(actor.dispell_spells._ActorTable) do
local habilidade_shadow = shadow.dispell_spells:PegaHabilidade(spellid, true, nil, true)
habilidade_shadow.dispell_oque = habilidade_shadow.dispell_oque or {}
for _spellid, amount in pairs(habilidade.dispell_oque) do
habilidade_shadow.dispell_oque [_spellid] = (habilidade_shadow.dispell_oque [_spellid] or 0) + amount
end
end
for spellid, amount in pairs(actor.dispell_oque) do
shadow.dispell_oque [spellid] = (shadow.dispell_oque [spellid] or 0) + amount
end
end
if (actor.cc_break) then
if (not shadow.cc_break) then
shadow.cc_break = 0
shadow.cc_break_targets = {}
shadow.cc_break_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS) --cria o container das habilidades usadas para interromper
shadow.cc_break_oque = {}
end
shadow.cc_break = shadow.cc_break + actor.cc_break
host_combat.totals[4].cc_break = host_combat.totals[4].cc_break + actor.cc_break
if (actor.grupo) then
host_combat.totals_grupo[4].cc_break = host_combat.totals_grupo[4].cc_break + actor.cc_break
end
sumTargetValues(shadow.cc_break_targets, actor.cc_break_targets)
sumSpellTableKeyValues(shadow.cc_break_spells, actor.cc_break_spells)
for spellid, habilidade in pairs(actor.cc_break_spells._ActorTable) do
local habilidade_shadow = shadow.cc_break_spells:PegaHabilidade(spellid, true, nil, true)
habilidade_shadow.cc_break_oque = habilidade_shadow.cc_break_oque or {}
for _spellid, amount in pairs(habilidade.cc_break_oque) do
habilidade_shadow.cc_break_oque [_spellid] = (habilidade_shadow.cc_break_oque [_spellid] or 0) + amount
end
end
for spellid, amount in pairs(actor.cc_break_oque) do
shadow.cc_break_oque [spellid] = (shadow.cc_break_oque [spellid] or 0) + amount
end
end
return shadow
end
function Details.refresh:r_atributo_misc(thisActor, shadow)
setmetatable(thisActor, Details.atributo_misc)
detailsFramework:Mixin(thisActor, Details222.Mixins.ActorMixin)
thisActor.__index = Details.atributo_misc
--refresh cc done
if (thisActor.cc_done) then
if (shadow and not shadow.cc_done_targets) then
shadow.cc_done = 0
shadow.cc_done_targets = {}
shadow.cc_done_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
Details.refresh:r_container_habilidades(thisActor.cc_done_spells, shadow and shadow.cc_done_spells)
end
--refresh interrupts
if (thisActor.interrupt_targets) then
if (shadow and not shadow.interrupt_targets) then
shadow.interrupt = 0
shadow.interrupt_targets = {}
shadow.interrupt_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
shadow.interrompeu_oque = {}
end
Details.refresh:r_container_habilidades(thisActor.interrupt_spells, shadow and shadow.interrupt_spells)
end
--refresh buff uptime
if (thisActor.buff_uptime_targets) then
if (shadow and not shadow.buff_uptime_targets) then
shadow.buff_uptime = 0
shadow.buff_uptime_targets = {}
shadow.buff_uptime_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
if (thisActor.received_buffs_spells) then
shadow.received_buffs_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
end
Details.refresh:r_container_habilidades(thisActor.buff_uptime_spells, shadow and shadow.buff_uptime_spells)
if (thisActor.received_buffs_spells) then
Details.refresh:r_container_habilidades(thisActor.received_buffs_spells, shadow and shadow.received_buffs_spells)
end
end
--refresh buff uptime
if (thisActor.debuff_uptime_targets) then
if (shadow and not shadow.debuff_uptime_targets) then
shadow.debuff_uptime = 0
if (thisActor.boss_debuff) then
shadow.debuff_uptime_targets = {}
shadow.boss_debuff = true
shadow.damage_twin = thisActor.damage_twin
shadow.spellschool = thisActor.spellschool
shadow.damage_spellid = thisActor.damage_spellid
shadow.debuff_uptime = 0
else
shadow.debuff_uptime_targets = {}
end
shadow.debuff_uptime_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
Details.refresh:r_container_habilidades(thisActor.debuff_uptime_spells, shadow and shadow.debuff_uptime_spells)
end
--refresh cooldowns defensive
if (thisActor.cooldowns_defensive_targets) then
if (shadow and not shadow.cooldowns_defensive_targets) then
shadow.cooldowns_defensive = 0
shadow.cooldowns_defensive_targets = {}
shadow.cooldowns_defensive_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
Details.refresh:r_container_habilidades(thisActor.cooldowns_defensive_spells, shadow and shadow.cooldowns_defensive_spells)
end
--refresh ressers
if (thisActor.ress_targets) then
if (shadow and not shadow.ress_targets) then
shadow.ress = 0
shadow.ress_targets = {}
shadow.ress_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
end
Details.refresh:r_container_habilidades(thisActor.ress_spells, shadow and shadow.ress_spells)
end
--refresh dispells
if (thisActor.dispell_targets) then
if (shadow and not shadow.dispell_targets) then
shadow.dispell = 0
shadow.dispell_targets = {}
shadow.dispell_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS) --cria o container das habilidades usadas para interromper
shadow.dispell_oque = {}
end
Details.refresh:r_container_habilidades(thisActor.dispell_spells, shadow and shadow.dispell_spells)
end
--refresh cc_breaks
if (thisActor.cc_break_targets) then
if (shadow and not shadow.cc_break) then
shadow.cc_break = 0
shadow.cc_break_targets = {}
shadow.cc_break_spells = container_habilidades:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS)
shadow.cc_break_oque = {}
end
Details.refresh:r_container_habilidades(thisActor.cc_break_spells, shadow and shadow.cc_break_spells)
end
end
function Details.clear:c_atributo_misc(este_jogador)
este_jogador.__index = nil
este_jogador.links = nil
este_jogador.minha_barra = nil
if (este_jogador.cc_done_targets) then
Details.clear:c_container_habilidades(este_jogador.cc_done_spells)
end
if (este_jogador.interrupt_targets) then
Details.clear:c_container_habilidades(este_jogador.interrupt_spells)
end
if (este_jogador.cooldowns_defensive_targets) then
Details.clear:c_container_habilidades(este_jogador.cooldowns_defensive_spells)
end
if (este_jogador.buff_uptime_targets) then
Details.clear:c_container_habilidades(este_jogador.buff_uptime_spells)
if (este_jogador.received_buffs_spells) then
Details.clear:c_container_habilidades(este_jogador.received_buffs_spells)
end
end
if (este_jogador.debuff_uptime_targets) then
Details.clear:c_container_habilidades(este_jogador.debuff_uptime_spells)
end
if (este_jogador.ress_targets) then
Details.clear:c_container_habilidades(este_jogador.ress_spells)
end
if (este_jogador.cc_break_targets) then
Details.clear:c_container_habilidades(este_jogador.cc_break_spells)
end
if (este_jogador.dispell_targets) then
Details.clear:c_container_habilidades(este_jogador.dispell_spells)
end
end
atributo_misc.__add = function(tabela1, tabela2)
if (tabela2.cleu_prescience_time) then --timeline
local shadowPrescienceStackData = tabela1.cleu_prescience_time
if (not shadowPrescienceStackData) then
tabela1.cleu_prescience_time = detailsFramework.table.copy({}, tabela2.cleu_prescience_time)
else
for amountOfPrescienceApplied, time in pairs(tabela2.cleu_prescience_time.stackTime) do
tabela1.cleu_prescience_time.stackTime[amountOfPrescienceApplied] = tabela1.cleu_prescience_time.stackTime[amountOfPrescienceApplied] + time
end
end
end
if (tabela2.cc_done) then
tabela1.cc_done = tabela1.cc_done + tabela2.cc_done
for targetName, amount in pairs(tabela2.cc_done_targets) do
tabela1.cc_done_targets[targetName] = (tabela1.cc_done_targets[targetName] or 0) + amount
end
for spellId, spellTable in pairs(tabela2.cc_done_spells._ActorTable) do
local spellTable1 = tabela1.cc_done_spells:PegaHabilidade(spellId, true, nil, false)
for target_name, amount in pairs(spellTable.targets) do
spellTable1.targets[target_name] = (spellTable1.targets[target_name] or 0) + amount
end
sumKeyValues(spellTable, spellTable1)
end
end
if (tabela2.interrupt) then
if (not tabela1.interrupt) then
tabela1.interrupt = 0
tabela1.interrupt_targets = {}
tabela1.interrupt_spells = container_habilidades:NovoContainer(container_misc)
tabela1.interrompeu_oque = {}
end
--total de interrupts
tabela1.interrupt = tabela1.interrupt + tabela2.interrupt
--soma o interrompeu o que
for spellid, amount in pairs(tabela2.interrompeu_oque) do
tabela1.interrompeu_oque[spellid] = (tabela1.interrompeu_oque [spellid] or 0) + amount
end
--soma os containers de alvos
for target_name, amount in pairs(tabela2.interrupt_targets) do
tabela1.interrupt_targets[target_name] = (tabela1.interrupt_targets[target_name] or 0) + amount
end
--soma o container de habilidades
for spellid, habilidade in pairs(tabela2.interrupt_spells._ActorTable) do
local habilidade_tabela1 = tabela1.interrupt_spells:PegaHabilidade(spellid, true, nil, false)
habilidade_tabela1.interrompeu_oque = habilidade_tabela1.interrompeu_oque or {}
for _spellid, amount in pairs(habilidade.interrompeu_oque) do
habilidade_tabela1.interrompeu_oque[_spellid] = (habilidade_tabela1.interrompeu_oque[_spellid] or 0) + amount
end
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) + amount
end
sumKeyValues(habilidade, habilidade_tabela1)
end
end
if (tabela2.buff_uptime) then
if (not tabela1.buff_uptime) then
tabela1.buff_uptime = 0
tabela1.buff_uptime_targets = {}
tabela1.buff_uptime_spells = container_habilidades:NovoContainer(container_misc)
end
if (tabela2.received_buffs_spells) then
if (not tabela1.received_buffs_spells) then
tabela1.received_buffs_spells = container_habilidades:NovoContainer(container_misc)
end
for spellId, spellTable in pairs(tabela2.received_buffs_spells._ActorTable) do
local habilidade_tabela1 = tabela1.received_buffs_spells:PegaHabilidade(spellId, true, nil, false)
for target_name, amount in pairs(spellTable.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) + amount
end
sumKeyValues(spellTable, habilidade_tabela1)
end
end
tabela1.buff_uptime = tabela1.buff_uptime + tabela2.buff_uptime
for target_name, amount in pairs(tabela2.buff_uptime_targets) do
tabela1.buff_uptime_targets[target_name] = (tabela1.buff_uptime_targets[target_name] or 0) + amount
end
for spellId, spellTable in pairs(tabela2.buff_uptime_spells._ActorTable) do
local habilidade_tabela1 = tabela1.buff_uptime_spells:PegaHabilidade(spellId, true, nil, false)
for target_name, amount in pairs(spellTable.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) + amount
end
sumKeyValues(spellTable, habilidade_tabela1)
end
end
if (tabela2.debuff_uptime) then
if (not tabela1.debuff_uptime) then
if (tabela2.boss_debuff) then
tabela1.debuff_uptime_targets = {}
tabela1.boss_debuff = true
tabela1.damage_twin = tabela2.damage_twin
tabela1.spellschool = tabela2.spellschool
tabela1.damage_spellid = tabela2.damage_spellid
else
tabela1.debuff_uptime_targets = {}
end
tabela1.debuff_uptime = 0
tabela1.debuff_uptime_spells = container_habilidades:NovoContainer(container_misc)
end
tabela1.debuff_uptime = tabela1.debuff_uptime + tabela2.debuff_uptime
for target_name, amount in pairs(tabela2.debuff_uptime_targets) do
if (type(amount) == "table") then --boss debuff
local t = tabela1.debuff_uptime_targets[target_name]
if (not t) then
tabela1.debuff_uptime_targets[target_name] = atributo_misc:CreateBuffTargetObject()
t = tabela1.debuff_uptime_targets[target_name]
end
t.uptime = t.uptime + amount.uptime
t.activedamt = t.activedamt + amount.activedamt
t.refreshamt = t.refreshamt + amount.refreshamt
t.appliedamt = t.appliedamt + amount.appliedamt
else
tabela1.debuff_uptime_targets[target_name] = (tabela1.debuff_uptime_targets[target_name] or 0) + amount
end
end
for spellid, habilidade in pairs(tabela2.debuff_uptime_spells._ActorTable) do
local habilidade_tabela1 = tabela1.debuff_uptime_spells:PegaHabilidade(spellid, true, nil, false)
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) + amount
end
sumKeyValues(habilidade, habilidade_tabela1)
end
end
if (tabela2.cooldowns_defensive) then
if (not tabela1.cooldowns_defensive) then
tabela1.cooldowns_defensive = 0
tabela1.cooldowns_defensive_targets = {}
tabela1.cooldowns_defensive_spells = container_habilidades:NovoContainer(container_misc)
end
tabela1.cooldowns_defensive = tabela1.cooldowns_defensive + tabela2.cooldowns_defensive
for target_name, amount in pairs(tabela2.cooldowns_defensive_targets) do
tabela1.cooldowns_defensive_targets[target_name] = (tabela1.cooldowns_defensive_targets[target_name] or 0) + amount
end
for spellid, habilidade in pairs(tabela2.cooldowns_defensive_spells._ActorTable) do
local habilidade_tabela1 = tabela1.cooldowns_defensive_spells:PegaHabilidade(spellid, true, nil, false)
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) + amount
end
sumKeyValues(habilidade, habilidade_tabela1)
end
end
if (tabela2.ress) then
if (not tabela1.ress) then
tabela1.ress = 0
tabela1.ress_targets = {}
tabela1.ress_spells = container_habilidades:NovoContainer(container_misc)
end
tabela1.ress = tabela1.ress + tabela2.ress
for target_name, amount in pairs(tabela2.ress_targets) do
tabela1.ress_targets[target_name] = (tabela1.ress_targets[target_name] or 0) + amount
end
for spellid, habilidade in pairs(tabela2.ress_spells._ActorTable) do
local habilidade_tabela1 = tabela1.ress_spells:PegaHabilidade(spellid, true, nil, false)
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) + amount
end
sumKeyValues(habilidade, habilidade_tabela1)
end
end
if (tabela2.dispell) then
if (not tabela1.dispell) then
tabela1.dispell = 0
tabela1.dispell_targets = {}
tabela1.dispell_spells = container_habilidades:NovoContainer(container_misc)
tabela1.dispell_oque = {}
end
tabela1.dispell = tabela1.dispell + tabela2.dispell
for target_name, amount in pairs(tabela2.dispell_targets) do
tabela1.dispell_targets[target_name] = (tabela1.dispell_targets[target_name] or 0) + amount
end
for spellid, habilidade in pairs(tabela2.dispell_spells._ActorTable) do
local habilidade_tabela1 = tabela1.dispell_spells:PegaHabilidade(spellid, true, nil, false)
habilidade_tabela1.dispell_oque = habilidade_tabela1.dispell_oque or {}
for _spellid, amount in pairs(habilidade.dispell_oque) do
habilidade_tabela1.dispell_oque[_spellid] = (habilidade_tabela1.dispell_oque[_spellid] or 0) + amount
end
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) + amount
end
sumKeyValues(habilidade, habilidade_tabela1)
end
for spellid, amount in pairs(tabela2.dispell_oque) do
tabela1.dispell_oque[spellid] = (tabela1.dispell_oque[spellid] or 0) + amount
end
end
if (tabela2.cc_break) then
if (not tabela1.cc_break) then
tabela1.cc_break = 0
tabela1.cc_break_targets = {}
tabela1.cc_break_spells = container_habilidades:NovoContainer(container_misc)
tabela1.cc_break_oque = {}
end
tabela1.cc_break = tabela1.cc_break + tabela2.cc_break
for target_name, amount in pairs(tabela2.cc_break_targets) do
tabela1.cc_break_targets[target_name] = (tabela1.cc_break_targets[target_name] or 0) + amount
end
for spellid, habilidade in pairs(tabela2.cc_break_spells._ActorTable) do
local habilidade_tabela1 = tabela1.cc_break_spells:PegaHabilidade(spellid, true, nil, false)
habilidade_tabela1.cc_break_oque = habilidade_tabela1.cc_break_oque or {}
for _spellid, amount in pairs(habilidade.cc_break_oque) do
habilidade_tabela1.cc_break_oque[_spellid] = (habilidade_tabela1.cc_break_oque[_spellid] or 0) + amount
end
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) + amount
end
sumKeyValues(habilidade, habilidade_tabela1)
end
for spellid, amount in pairs(tabela2.cc_break_oque) do
tabela1.cc_break_oque[spellid] = (tabela1.cc_break_oque[spellid] or 0) + amount
end
end
return tabela1
end
local subtractKeyValues = function(habilidade, habilidade_tabela1)
for key, value in pairs(habilidade) do
if (type(value) == "number") then
if (key ~= "id" and key ~= "spellschool") then
habilidade_tabela1[key] = (habilidade_tabela1[key] or 0) - value
end
end
end
end
atributo_misc.__sub = function(tabela1, tabela2)
if (tabela2.cleu_prescience_time) then --timeline
local shadowPrescienceStackData = tabela1.cleu_prescience_time
if (shadowPrescienceStackData) then
for amountOfPrescienceApplied, time in pairs(tabela2.cleu_prescience_time.stackTime) do
tabela1.cleu_prescience_time.stackTime[amountOfPrescienceApplied] = tabela1.cleu_prescience_time.stackTime[amountOfPrescienceApplied] - time
end
end
end
if (tabela2.cc_done) then
tabela1.cc_done = tabela1.cc_done - tabela2.cc_done
for target_name, amount in pairs(tabela2.cc_done_targets) do
tabela1.cc_done_targets[target_name] = (tabela1.cc_done_targets[target_name] or 0) - amount
end
for spellid, habilidade in pairs(tabela2.cc_done_spells._ActorTable) do
local habilidade_tabela1 = tabela1.cc_done_spells:PegaHabilidade(spellid, true, nil, false)
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) - amount
end
subtractKeyValues(habilidade, habilidade_tabela1)
end
end
if (tabela2.interrupt) then
--total de interrupts
tabela1.interrupt = tabela1.interrupt - tabela2.interrupt
--soma o interrompeu o que
for spellid, amount in pairs(tabela2.interrompeu_oque) do
tabela1.interrompeu_oque[spellid] = (tabela1.interrompeu_oque[spellid] or 0) - amount
end
--soma os containers de alvos
for target_name, amount in pairs(tabela2.interrupt_targets) do
tabela1.interrupt_targets[target_name] = (tabela1.interrupt_targets[target_name] or 0) - amount
end
--soma o container de habilidades
for spellid, habilidade in pairs(tabela2.interrupt_spells._ActorTable) do
local habilidade_tabela1 = tabela1.interrupt_spells:PegaHabilidade(spellid, true, nil, false)
habilidade_tabela1.interrompeu_oque = habilidade_tabela1.interrompeu_oque or {}
for _spellid, amount in pairs(habilidade.interrompeu_oque) do
habilidade_tabela1.interrompeu_oque[_spellid] = (habilidade_tabela1.interrompeu_oque[_spellid] or 0) - amount
end
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) - amount
end
subtractKeyValues(habilidade, habilidade_tabela1)
end
end
if (tabela2.buff_uptime) then
tabela1.buff_uptime = tabela1.buff_uptime - tabela2.buff_uptime
for target_name, amount in pairs(tabela2.buff_uptime_targets) do
tabela1.buff_uptime_targets[target_name] = (tabela1.buff_uptime_targets[target_name] or 0) - amount
end
for spellid, habilidade in pairs(tabela2.buff_uptime_spells._ActorTable) do
local habilidade_tabela1 = tabela1.buff_uptime_spells:PegaHabilidade(spellid, true, nil, false)
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) - amount
end
subtractKeyValues(habilidade, habilidade_tabela1)
end
if (tabela2.received_buffs_spells) then
for spellId, spellTable in pairs(tabela2.received_buffs_spells._ActorTable) do
local habilidade_tabela1 = tabela1.received_buffs_spells:PegaHabilidade(spellId, true, nil, false)
subtractKeyValues(spellTable, habilidade_tabela1)
end
end
end
if (tabela2.debuff_uptime) then
tabela1.debuff_uptime = tabela1.debuff_uptime - tabela2.debuff_uptime
for target_name, amount in pairs(tabela2.debuff_uptime_targets) do
if (type(amount) == "table") then --boss debuff
local t = tabela1.debuff_uptime_targets[target_name]
if (not t) then
tabela1.debuff_uptime_targets[target_name] = atributo_misc:CreateBuffTargetObject()
t = tabela1.debuff_uptime_targets[target_name]
end
t.uptime = t.uptime - amount.uptime
t.activedamt = t.activedamt - amount.activedamt
t.refreshamt = t.refreshamt - amount.refreshamt
t.appliedamt = t.appliedamt - amount.appliedamt
else
tabela2.debuff_uptime_targets[target_name] = (tabela2.debuff_uptime_targets[target_name] or 0) - amount
end
end
for spellid, habilidade in pairs(tabela2.debuff_uptime_spells._ActorTable) do
local habilidade_tabela1 = tabela1.debuff_uptime_spells:PegaHabilidade(spellid, true, nil, false)
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) - amount
end
subtractKeyValues(habilidade, habilidade_tabela1)
end
end
if (tabela2.cooldowns_defensive) then
tabela1.cooldowns_defensive = tabela1.cooldowns_defensive - tabela2.cooldowns_defensive
for target_name, amount in pairs(tabela2.cooldowns_defensive_targets) do
tabela1.cooldowns_defensive_targets[target_name] = (tabela1.cooldowns_defensive_targets[target_name] or 0) - amount
end
for spellid, habilidade in pairs(tabela2.cooldowns_defensive_spells._ActorTable) do
local habilidade_tabela1 = tabela1.cooldowns_defensive_spells:PegaHabilidade(spellid, true, nil, false)
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) - amount
end
subtractKeyValues(habilidade, habilidade_tabela1)
end
end
if (tabela2.ress) then
tabela1.ress = tabela1.ress - tabela2.ress
for target_name, amount in pairs(tabela2.ress_targets) do
tabela1.ress_targets[target_name] = (tabela1.ress_targets[target_name] or 0) - amount
end
for spellid, habilidade in pairs(tabela2.ress_spells._ActorTable) do
local habilidade_tabela1 = tabela1.ress_spells:PegaHabilidade(spellid, true, nil, false)
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) - amount
end
subtractKeyValues(habilidade, habilidade_tabela1)
end
end
if (tabela2.dispell) then
tabela1.dispell = tabela1.dispell - tabela2.dispell
for target_name, amount in pairs(tabela2.dispell_targets) do
tabela1.dispell_targets[target_name] = (tabela1.dispell_targets[target_name] or 0) - amount
end
for spellid, habilidade in pairs(tabela2.dispell_spells._ActorTable) do
local habilidade_tabela1 = tabela1.dispell_spells:PegaHabilidade(spellid, true, nil, false)
habilidade_tabela1.dispell_oque = habilidade_tabela1.dispell_oque or {}
for _spellid, amount in pairs(habilidade.dispell_oque) do
habilidade_tabela1.dispell_oque[_spellid] = (habilidade_tabela1.dispell_oque[_spellid] or 0) - amount
end
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) - amount
end
subtractKeyValues(habilidade, habilidade_tabela1)
end
for spellid, amount in pairs(tabela2.dispell_oque) do
tabela1.dispell_oque[spellid] = (tabela1.dispell_oque[spellid] or 0) - amount
end
end
if (tabela2.cc_break) then
tabela1.cc_break = tabela1.cc_break - tabela2.cc_break
for target_name, amount in pairs(tabela2.cc_break_targets) do
tabela1.cc_break_targets[target_name] = (tabela1.cc_break_targets[target_name] or 0) - amount
end
for spellid, habilidade in pairs(tabela2.cc_break_spells._ActorTable) do
local habilidade_tabela1 = tabela1.cc_break_spells:PegaHabilidade(spellid, true, nil, false)
habilidade_tabela1.cc_break_oque = habilidade_tabela1.cc_break_oque or {}
for _spellid, amount in pairs(habilidade.cc_break_oque) do
habilidade_tabela1.cc_break_oque[_spellid] = (habilidade_tabela1.cc_break_oque[_spellid] or 0) - amount
end
for target_name, amount in pairs(habilidade.targets) do
habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets[target_name] or 0) - amount
end
subtractKeyValues(habilidade, habilidade_tabela1)
end
for spellid, amount in pairs(tabela2.cc_break_oque) do
tabela1.cc_break_oque[spellid] = (tabela1.cc_break_oque[spellid] or 0) - amount
end
end
return tabela1
end