diff --git a/Details.toc b/Details.toc index 93f53886..7195559f 100644 --- a/Details.toc +++ b/Details.toc @@ -60,6 +60,7 @@ functions\deathmenu.lua functions\macros.lua functions\testbars.lua functions\editmode.lua +functions\warcraftlogs.lua core\timemachine.lua diff --git a/Libs/LibOpenRaid/GetPlayerInformation.lua b/Libs/LibOpenRaid/GetPlayerInformation.lua index cd792206..98d60846 100644 --- a/Libs/LibOpenRaid/GetPlayerInformation.lua +++ b/Libs/LibOpenRaid/GetPlayerInformation.lua @@ -662,6 +662,67 @@ function openRaidLib.CooldownManager.GetPlayerCooldownStatus(spellId) end end +do + --make new namespace + openRaidLib.AuraTracker = {} + + function openRaidLib.AuraTracker.ScanCallback(aura) + local unitId = openRaidLib.AuraTracker.CurrentUnitId + local thisUnitAuras = openRaidLib.AuraTracker.CurrentAuras[unitId] + + local auraInfo = C_UnitAuras.GetAuraDataByAuraInstanceID(unitId, aura.auraInstanceID) + if (auraInfo) then + local spellId = auraInfo.spellId + if (spellId) then + thisUnitAuras[spellId] = true + openRaidLib.AuraTracker.AurasFoundOnScan[spellId] = true + end + end + end + + function openRaidLib.AuraTracker.ScanPlayerAuras(unitId) + local batchCount = nil + local usePackedAura = true + openRaidLib.AuraTracker.CurrentUnitId = unitId + + openRaidLib.AuraTracker.AurasFoundOnScan = {} + AuraUtil.ForEachAura(unitId, "HELPFUL", batchCount, openRaidLib.AuraTracker.ScanCallback, usePackedAura) + + local thisUnitAuras = openRaidLib.AuraTracker.CurrentAuras[unitId] + for spellId in pairs(thisUnitAuras) do + if (not openRaidLib.AuraTracker.AurasFoundOnScan[spellId]) then + --aura removed + openRaidLib.internalCallback.TriggerEvent("unitAuraRemoved", unitId, spellId) + end + end + end + + --run when the open raid lib loads + function openRaidLib.AuraTracker.StartScanUnitAuras(unitId) + openRaidLib.AuraTracker.CurrentAuras = { + [unitId] = {} + } + + local auraFrameEvent = CreateFrame("frame") + auraFrameEvent:RegisterUnitEvent("UNIT_AURA", unitId) + + auraFrameEvent:SetScript("OnEvent", function() + openRaidLib.AuraTracker.ScanPlayerAuras(unitId) + end) + end + + --test case: + local debugModule = {} + function debugModule.AuraRemoved(event, unitId, spellId) + local spellName = GetSpellInfo(spellId) + --print("aura removed:", unitId, spellId, spellName) + end + openRaidLib.internalCallback.RegisterCallback("unitAuraRemoved", debugModule.AuraRemoved) + +end + + + --which is the main attribute of each spec --1 Intellect --2 Agility diff --git a/Libs/LibOpenRaid/LibOpenRaid.lua b/Libs/LibOpenRaid/LibOpenRaid.lua index 9b5cb8f0..fbbcc163 100644 --- a/Libs/LibOpenRaid/LibOpenRaid.lua +++ b/Libs/LibOpenRaid/LibOpenRaid.lua @@ -64,7 +64,7 @@ if (WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE and not isExpansion_Dragonflight()) t end local major = "LibOpenRaid-1.0" -local CONST_LIB_VERSION = 81 +local CONST_LIB_VERSION = 82 if (not LIB_OPEN_RAID_MAX_VERSION) then LIB_OPEN_RAID_MAX_VERSION = CONST_LIB_VERSION @@ -726,6 +726,7 @@ end ["mythicDungeonStart"] = {}, ["playerPetChange"] = {}, ["mythicDungeonEnd"] = {}, + ["unitAuraRemoved"] = {}, } openRaidLib.internalCallback.RegisterCallback = function(event, func) @@ -804,10 +805,12 @@ end ["PLAYER_ENTERING_WORLD"] = function(...) --has the selected character just loaded? - if (not openRaidLib.isFirstEnteringWorld) then + if (not openRaidLib.bHasEnteredWorld) then --register events openRaidLib.OnEnterWorldRegisterEvents() + --openRaidLib.AuraTracker.StartScanUnitAuras("player") + if (IsInGroup()) then openRaidLib.RequestAllData() openRaidLib.UpdateUnitIDCache() @@ -845,7 +848,7 @@ end detailsEventListener:RegisterEvent("UNIT_TALENTS", "UnitTalentsFound") end - openRaidLib.isFirstEnteringWorld = true + openRaidLib.bHasEnteredWorld = true end openRaidLib.internalCallback.TriggerEvent("onEnterWorld") @@ -1984,6 +1987,35 @@ end openRaidLib.CooldownManager.CheckCooldownChanges() end + function openRaidLib.CooldownManager.OnAuraRemoved(event, unitId, spellId) + --under development ~aura + local timeLeft, charges, startTimeOffset, duration, auraDuration = openRaidLib.CooldownManager.GetPlayerCooldownStatus(spellId) + + --do need to update? + if (not timeLeft or timeLeft < 1 or not auraDuration or auraDuration < 1) then + return + end + + local latencyCompensation = 1 + + if (spellId) then + if (auraDuration > latencyCompensation) then + --cooldown aura got removed before expiration + local newAuraDuration = 0 + local unitName = GetUnitName(unitId, true) or unitId + openRaidLib.CooldownManager.CooldownSpellUpdate(unitName, spellId, timeLeft, charges, startTimeOffset, duration, newAuraDuration) + + --trigger a public callback + local playerCooldownTable = openRaidLib.GetUnitCooldowns(unitName) + local cooldownInfo = cooldownGetSpellInfo(unitName, spellId) + openRaidLib.publicCallback.TriggerCallback("CooldownUpdate", "player", spellId, cooldownInfo, playerCooldownTable, openRaidLib.CooldownManager.UnitData) + + --send to comm + openRaidLib.CooldownManager.SendPlayerCooldownUpdate(spellId, timeLeft, charges, startTimeOffset, duration, newAuraDuration) + end + end + end + openRaidLib.internalCallback.RegisterCallback("onLeaveGroup", openRaidLib.CooldownManager.OnPlayerLeaveGroup) openRaidLib.internalCallback.RegisterCallback("playerCast", openRaidLib.CooldownManager.OnPlayerCast) openRaidLib.internalCallback.RegisterCallback("onPlayerRess", openRaidLib.CooldownManager.OnPlayerRess) @@ -1992,6 +2024,7 @@ end openRaidLib.internalCallback.RegisterCallback("onLeaveCombat", openRaidLib.CooldownManager.OnEncounterEnd) openRaidLib.internalCallback.RegisterCallback("mythicDungeonStart", openRaidLib.CooldownManager.OnMythicPlusStart) openRaidLib.internalCallback.RegisterCallback("playerPetChange", openRaidLib.CooldownManager.OnPlayerPetChanged) + openRaidLib.internalCallback.RegisterCallback("unitAuraRemoved", openRaidLib.CooldownManager.OnAuraRemoved) --send a list through comm with cooldowns added or removed function openRaidLib.CooldownManager.CheckCooldownChanges() diff --git a/Libs/LibOpenRaid/ThingsToMantain_Dragonflight.lua b/Libs/LibOpenRaid/ThingsToMantain_Dragonflight.lua index dae616fc..6bd89e41 100644 --- a/Libs/LibOpenRaid/ThingsToMantain_Dragonflight.lua +++ b/Libs/LibOpenRaid/ThingsToMantain_Dragonflight.lua @@ -804,6 +804,59 @@ do --191427 havoc } + LIB_OPEN_RAID_SPECID_TO_CLASSID = { + [577] = 12, + [581] = 12, + + [250] = 6, + [251] = 6, + [252] = 6, + + [71] = 1, + [72] = 1, + [73] = 1, + + [62] = 8, + [63] = 8, + [64] = 8, + + [259] = 4, + [260] = 4, + [261] = 4, + + [102] = 11, + [103] = 11, + [104] = 11, + [105] = 11, + + [253] = 3, + [254] = 3, + [255] = 3, + + [262] = 7, + [263] = 7, + [264] = 7, + + [256] = 5, + [257] = 5, + [258] = 5, + + [265] = 9, + [266] = 9, + [267] = 9, + + [65] = 2, + [66] = 2, + [70] = 2, + + [268] = 10, + [269] = 10, + [270] = 10, + + [1467] = 13, + [1468] = 13, + } + LIB_OPEN_RAID_DATABASE_LOADED = true end diff --git a/boot.lua b/boot.lua index 203d2741..30e807b2 100644 --- a/boot.lua +++ b/boot.lua @@ -6,8 +6,8 @@ local addonName, Details222 = ... local version, build, date, tocversion = GetBuildInfo() - _detalhes.build_counter = 10289 - _detalhes.alpha_build_counter = 10289 --if this is higher than the regular counter, use it instead + _detalhes.build_counter = 10290 + _detalhes.alpha_build_counter = 10290 --if this is higher than the regular counter, use it instead _detalhes.dont_open_news = true _detalhes.game_version = version _detalhes.userversion = version .. " " .. _detalhes.build_counter diff --git a/classes/class_combat.lua b/classes/class_combat.lua index 058c5e3d..5723a20b 100644 --- a/classes/class_combat.lua +++ b/classes/class_combat.lua @@ -86,6 +86,10 @@ return self.is_boss and self.is_boss.diff end + function combate:GetEncounterCleuID() + return self.is_boss and self.is_boss.id + end + function combate:GetBossInfo() return self.is_boss end diff --git a/core/parser.lua b/core/parser.lua index ef0b4c4a..7f0a5942 100755 --- a/core/parser.lua +++ b/core/parser.lua @@ -5326,6 +5326,24 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 end end + --tag item level of all players + local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0") + local allUnitsInfo = openRaidLib.GetAllUnitsInfo() + local allPlayersGear = openRaidLib.GetAllUnitsGear() + + local status = xpcall(function() + for actorIndex, actorObject in Details:GetCurrentCombat():GetContainer(DETAILS_ATTRIBUTE_DAMAGE):ListActors() do + local gearInfo = allPlayersGear[actorObject:Name()] + if (gearInfo) then + actorObject.ilvl = gearInfo.ilevel + end + end + end, geterrorhandler()) + + if (not status) then + Details:Msg("ilvl error:", status) + end + _detalhes:SendEvent("COMBAT_ENCOUNTER_END", nil, ...) wipe(_detalhes.encounter_table) diff --git a/frames/window_playerbreakdown_list.lua b/frames/window_playerbreakdown_list.lua index dffef26f..602a785e 100644 --- a/frames/window_playerbreakdown_list.lua +++ b/frames/window_playerbreakdown_list.lua @@ -1,6 +1,8 @@ local Details = _G.Details local detailsFramework = _G.DetailsFramework + local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0") + local addonName, Details222 = ... local breakdownWindowPlayerList = {} @@ -8,13 +10,24 @@ local C_Timer = _G.C_Timer local tinsert = _G.tinsert - local scrollbox_size = {200, 405} - local scrollbox_lines = 25 + local scrollbox_size = {215, 405} + local scrollbox_lines = 23 local player_line_height = 21.7 local scrollbox_line_backdrop_color = {0.2, 0.2, 0.2, 0.5} local scrollbox_line_backdrop_color_selected = {.6, .6, .1, 0.7} local scrollbox_line_backdrop_color_highlight = {.9, .9, .9, 0.5} - local player_scroll_size = {180, 288} + local player_scroll_size = {195, 288} + + --header setup + local headerTable = { + {text = "", width = 20}, + {text = "Player Name", width = 100}, + {text = "iLvL", width = 30}, + {text = "WCL Parse", width = 60}, + } + local headerOptions = { + padding = 2, + } function breakdownWindowPlayerList.CreatePlayerListFrame() local f = _G.DetailsPlayerDetailsWindow @@ -26,14 +39,18 @@ topResult = topResult.total end - for i = 1, totalLines do + local combatObject = Details:GetCombatFromBreakdownWindow() + local encounterId = combatObject:GetEncounterCleuID() + local difficultyId = combatObject:GetDifficulty() + + for i = 1, totalLines do --~refresh local index = i + offset local playerObject = data[index] if (playerObject) then local line = self:GetLine(i) line.playerObject = playerObject line.index = index - line:UpdateLine(topResult) + line:UpdateLine(topResult, encounterId, difficultyId) end end end @@ -61,7 +78,7 @@ self.roleIcon:SetBlendMode("BLEND") end - local updatePlayerLine = function(self, topResult) + local updatePlayerLine = function(self, topResult, encounterId, difficultyId) --~update local playerSelected = Details:GetPlayerObjectFromBreakdownWindow() if (playerSelected and playerSelected == self.playerObject) then self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected)) @@ -107,21 +124,50 @@ self.roleIcon:SetTexture("") end + local playerGear = openRaidLib.GetUnitGear(self.playerObject.nome) + --do not show the role icon - self.roleIcon:SetTexture("") + self.roleIcon:SetTexture("") --not in use --set the player name self.playerName:SetText(Details:GetOnlyName(self.playerObject.nome)) - self.rankText:SetText(self.index) + self.rankText:SetText(self.index) --not in use --set the player class name - self.className:SetText(string.lower(_G.UnitClass(self.playerObject.nome) or self.playerObject:Class())) + --self.className:SetText(string.lower(_G.UnitClass(self.playerObject.nome) or self.playerObject:Class())) --not in use + + --item level + self.itemLevelText:SetText(self.playerObject.ilvl or (playerGear and playerGear.ilevel) or "0") + + local actorSpecId = self.playerObject.spec + local actorTotal = self.playerObject.total + + --warcraftlogs percentile + if (self.playerObject.tipo == DETAILS_ATTRIBUTE_DAMAGE) then + local parcePercent = Details222.WarcraftLogs.GetDamageParsePercent(encounterId, difficultyId, actorSpecId, actorTotal) + if (parcePercent) then + self.percentileText:SetText(math.floor(parcePercent)) + self.percentileText.alpha = 1 + else + parcePercent = Details222.ParsePercent.GetPercent(DETAILS_ATTRIBUTE_DAMAGE, difficultyId, encounterId, actorSpecId, actorTotal) + if (parcePercent) then + self.percentileText:SetText(math.floor(parcePercent)) + self.percentileText.alpha = 1 + else + self.percentileText:SetText("#.def") + self.percentileText:SetAlpha(0.25) + end + end + else + self.percentileText:SetText("#.def") + self.percentileText:SetAlpha(0.25) + end --set the statusbar local r, g, b = self.playerObject:GetClassColor() self.totalStatusBar:SetStatusBarColor(r, g, b, 1) self.totalStatusBar:SetMinMaxValues(0, topResult) - self.totalStatusBar:SetValue(self.playerObject.total) + self.totalStatusBar:SetValue(actorTotal) end --get a Details! window @@ -142,29 +188,33 @@ local createPlayerLine = function(self, index) --create a new line local line = _G.CreateFrame("button", "$parentLine" .. index, self, "BackdropTemplate") + detailsFramework:Mixin(line, detailsFramework.HeaderFunctions) + + local upFrame = CreateFrame("frame", nil, line) + upFrame:SetFrameLevel(line:GetFrameLevel()+2) + upFrame:SetAllPoints() --set its parameters - line:SetPoint("topleft", self, "topleft", 1, -((index-1) * (player_line_height+1)) - 1) - line:SetSize(scrollbox_size[1]-19, player_line_height) + line:SetPoint("topleft", self, "topleft", 1, -((index) * (player_line_height+1)) - 1) + line:SetSize(scrollbox_size[1], player_line_height) + --line:SetSize(scrollbox_size[1]-19, player_line_height) line:RegisterForClicks("LeftButtonDown", "RightButtonDown") line:SetScript("OnEnter", lineOnEnter) line:SetScript("OnLeave", lineOnLeave) line:SetScript("OnClick", lineOnClick) - line:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true, edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1}) - line:SetBackdropColor(unpack(scrollbox_line_backdrop_color)) - line:SetBackdropBorderColor(0, 0, 0, 1) + detailsFramework:ApplyStandardBackdrop(line) - local specIcon = line:CreateTexture("$parentSpecIcon", "artwork") - specIcon:SetSize(player_line_height, player_line_height) + local specIcon = upFrame:CreateTexture("$parentSpecIcon", "artwork") + specIcon:SetSize(headerTable[1].width - 1, headerTable[1].width - 1) specIcon:SetAlpha(0.71) - local roleIcon = line:CreateTexture("$parentRoleIcon", "overlay") + local roleIcon = upFrame:CreateTexture("$parentRoleIcon", "overlay") roleIcon:SetSize((player_line_height-2) / 2, (player_line_height-2) / 2) roleIcon:SetAlpha(0.71) - local playerName = detailsFramework:CreateLabel(line, "", 11, "white", "GameFontNormal") + local playerName = detailsFramework:CreateLabel(upFrame, "", 11, "white", "GameFontNormal") if (fontFile) then playerName.fontface = fontFile end @@ -177,26 +227,35 @@ playerName.textcolor = {1, 1, 1, .9} - local className = detailsFramework:CreateLabel(line, "", "GameFontNormal") + local className = detailsFramework:CreateLabel(upFrame, "", "GameFontNormal") className.textcolor = {.95, .8, .2, 0} className.textsize = 9 - local rankText = detailsFramework:CreateLabel(line, "", "GameFontNormal") + local itemLevelText = detailsFramework:CreateLabel(upFrame, "", "GameFontNormal") + itemLevelText.textcolor = {1, 1, 1, .7} + itemLevelText.textsize = 11 + + local percentileText = detailsFramework:CreateLabel(upFrame, "", "GameFontNormal") + percentileText.textcolor = {1, 1, 1, .7} + percentileText.textsize = 11 + + local rankText = detailsFramework:CreateLabel(upFrame, "", "GameFontNormal") rankText.textcolor = {.3, .3, .3, .7} - rankText.textsize = 13 + rankText.textsize = fontSize local totalStatusBar = CreateFrame("statusbar", nil, line) totalStatusBar:SetSize(scrollbox_size[1]-19-player_line_height, 4) totalStatusBar:SetMinMaxValues(0, 100) totalStatusBar:SetStatusBarTexture([[Interface\AddOns\Details\images\bar_skyline]]) - totalStatusBar:SetFrameLevel(line:GetFrameLevel()-1) + totalStatusBar:SetFrameLevel(line:GetFrameLevel()+1) + totalStatusBar:SetAlpha(0.5) --setup anchors - specIcon:SetPoint("topleft", line, "topleft", 0, 0) - roleIcon:SetPoint("topleft", specIcon, "topright", 2, 0) - playerName:SetPoint("topleft", specIcon, "topright", 2, -3) - className:SetPoint("topleft", roleIcon, "bottomleft", 0, -2) - rankText:SetPoint("right", line, "right", -2, 0) + --specIcon:SetPoint("topleft", line, "topleft", 0, 0) + --roleIcon:SetPoint("topleft", specIcon, "topright", 2, 0) + --playerName:SetPoint("topleft", specIcon, "topright", 2, -3) + --className:SetPoint("topleft", roleIcon, "bottomleft", 0, -2) + --rankText:SetPoint("right", line, "right", -2, 0) totalStatusBar:SetPoint("bottomleft", specIcon, "bottomright", 0, 0) line.specIcon = specIcon @@ -205,6 +264,15 @@ line.className = className line.rankText = rankText line.totalStatusBar = totalStatusBar + line.itemLevelText = itemLevelText + line.percentileText = percentileText + + line:AddFrameToHeaderAlignment(specIcon) + line:AddFrameToHeaderAlignment(playerName) + line:AddFrameToHeaderAlignment(itemLevelText) + line:AddFrameToHeaderAlignment(percentileText) + + line:AlignWithHeader(f.Header, "left") line.UpdateLine = updatePlayerLine @@ -214,8 +282,9 @@ local playerScroll = detailsFramework:CreateScrollBox(f, "$parentPlayerScrollBox", refreshPlayerList, {}, player_scroll_size[1] + 22, player_scroll_size[2], scrollbox_lines, player_line_height) detailsFramework:ReskinSlider(playerScroll) playerScroll.ScrollBar:ClearAllPoints() - playerScroll.ScrollBar:SetPoint("topright", playerScroll, "topright", -2, -17) + playerScroll.ScrollBar:SetPoint("topright", playerScroll, "topright", -2, -37) playerScroll.ScrollBar:SetPoint("bottomright", playerScroll, "bottomright", -2, 17) + playerScroll.ScrollBar:Hide() playerScroll:SetPoint("topright", f, "topleft", -1, 0) playerScroll:SetPoint("bottomright", f, "bottomleft", -1, 0) playerScroll:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true}) @@ -223,6 +292,14 @@ playerScroll:SetBackdropBorderColor(0, 0, 0, 1) f.playerScrollBox = playerScroll + --need to be created before + f.Header = DetailsFramework:CreateHeader(f, headerTable, headerOptions) + f.Header:SetPoint("topleft", playerScroll, "topleft", 0, -1) + f.Header:SetPoint("topright", playerScroll, "topright", 0, -1) + + local playerSelectionLabel = detailsFramework:CreateLabel(playerScroll, "click to select a player", 14) + playerSelectionLabel:SetPoint("bottom", playerScroll, "bottom", 0, 7) + --create the scrollbox lines for i = 1, scrollbox_lines do playerScroll:CreateLine(createPlayerLine) @@ -241,6 +318,7 @@ MONK = 10, DRUID = 11, DEMONHUNTER = 12, + EVOKER = 13, } --get the player list from the segment and build a table compatible with the scroll box @@ -275,7 +353,7 @@ local updatePlayerList = function() local playerList = breakdownWindowPlayerList.BuildPlayerList() - playerScroll:SetData (playerList) + playerScroll:SetData(playerList) playerScroll:Refresh() playerScroll:Show() end diff --git a/functions/warcraftlogs.lua b/functions/warcraftlogs.lua new file mode 100644 index 00000000..86a1fc23 --- /dev/null +++ b/functions/warcraftlogs.lua @@ -0,0 +1,319 @@ + + local Details = _G.Details + local detailsFramework = _G.DetailsFramework + local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0") + local addonName, Details222 = ... + + local specIdToClassId = {} + + --wrap warcraftlogs addon api + Details222.WarcraftLogs = {} --namespace + + function Details222.WarcraftLogs.GetAddon() + local WCLAddonName = "WarcraftLogs" + local WarcraftLogs = _G[WCLAddonName] + return WarcraftLogs + end + + function Details222.WarcraftLogs.GetPlayerProfile(actorObject) + local playerName, playerRealm = actorObject:Name():match("(%w+)%-(%w+)") + + local WarcraftLogs = Details222.WarcraftLogs.GetAddon() + if (WarcraftLogs) then + playerName = playerName or actorObject:Name() + playerRealm = playerRealm or GetRealmName() + + local factionName = actorObject.enemy and Details.faction_against or UnitFactionGroup("player") + local factionId = factionName == "Horde" and 2 or 1 + + local playerProfile + + --~rename or change function call + if (WarcraftLogs.GetProfile) then + playerProfile = WarcraftLogs.GetProfile(playerName, playerRealm, factionId) + end + + return playerProfile or {} + else + return {} + end + end + + --details wrap + function Details222.WarcraftLogs.GetClassPercentileFromBossProfile(bossProfile) + --pipeline to return a table with information about the damage percentiles of all classes of an encounter + --~rename or change function call + return bossProfile.ClassPercentile or {} --wrapped + end + + --details wrap + function Details222.WarcraftLogs.GetEncounterProfile(cleuBossId, difficultyId) + --pipeline to return a table with an encounter data + local WarcraftLogs = Details222.WarcraftLogs.GetAddon() + if (WarcraftLogs) then + --~rename or change function call + if (WarcraftLogs.GetEncounterProfile) then + return WarcraftLogs.GetEncounterProfile(cleuBossId, difficultyId) or {} --wrapped + else + return {} + end + else + return {} + end + end + + --details wrap + function Details222.WarcraftLogs.GetClassPercentileForEncounterID(cleuBossId, difficultyId, classId) + --pipeline: return a table with class damage percentile, this table need to have sub tables with specs + local bossProfile = Details222.WarcraftLogs.GetEncounterProfile(cleuBossId, difficultyId) --wrapped + if (bossProfile) then + local classesPercentile = Details222.WarcraftLogs.GetClassPercentileFromBossProfile(bossProfile) --wrapped + if (classesPercentile) then + return classesPercentile or {} + else + return {} + end + end + + return {} + end + + --detais wrap + function Details222.WarcraftLogs.GetSpecPercentileFromClassPercentile(classPercentile, specId) + --pipeline: get a table with percentile damage information of a SPEC, this table should have {min = minDamage, max = maxDamage} + local percentileTable = classPercentile[specId] + local resultTable = {} + if (percentileTable) then + --~rename or change function call + local minDamage = percentileTable["MinDamage"] + local maxDamage = percentileTable["MaxDamage"] + resultTable = {min = minDamage, max = maxDamage} + end + return resultTable or {min = 0, max = 1} + end + + --details wrap + function Details222.WarcraftLogs.GetDamageParsePercent(encounterId, difficultyId, specId, damageDone) + local classId = LIB_OPEN_RAID_SPECID_TO_CLASSID[specId] + local classPercentileTable = Details222.WarcraftLogs.GetClassPercentileForEncounterID(encounterId, difficultyId, classId) --wrapped + + local specPercentile = classPercentileTable[specId] + if (specPercentile) then + local minDamage = specPercentile.min + local maxDamage = specPercentile.max + + local percentScalar = detailsFramework:MapRangeClamped(minDamage, maxDamage, 0, 100, damageDone) + return percentScalar + else + return nil + end + end + + --namespace + Details222.ParsePercent = {} + + function Details222.ParsePercent.GetPercent(attribute, difficultyId, encounterId, specId, amount) + --query warcraftlogs addon + if (attribute == DETAILS_ATTRIBUTE_DAMAGE) then + local percent = Details222.WarcraftLogs.GetDamageParsePercent(encounterId, difficultyId, specId, amount) + if (not percent) then + local data = Details222.ParsePercent.Data.Damage + local difficultyData = data[difficultyId] + if (difficultyData) then + local encounterData = difficultyData[encounterId] + if (encounterData) then + local parsePercentForSpec = encounterData[specId] + if (parsePercentForSpec) then + local minDamage = parsePercentForSpec.min + local maxDamage = parsePercentForSpec.max + local percentScalar = detailsFramework:MapRangeClamped(minDamage, maxDamage, 0, 100, amount) + return percentScalar + end + end + end + end + end + end + + --all data below are from warcraftlogs.com + Details222.ParsePercent.Data = {} + Details222.ParsePercent.Data.Damage = { + [16] = { --mythic + [2549] = { + encounterName = "Rygelon", + difficultyId = 16, + encounterId = 2549, + [256] = {min = 1626, max = 7425}, [65] = {min = 306, max = 12589}, [66] = {min = 1422, max = 24248}, [259] = {min = 16245, max = 33852}, [260] = {min = 63, max = 46266}, [581] = {min = 4083, max = 25071}, [262] = {min = 7184, max = 38595}, [263] = {min = 5742, max = 41418}, [72] = {min = 237, max = 46719}, [265] = {min = 3895, max = 80390}, [266] = {min = 5298, max = 42644}, [267] = {min = 75, max = 60883}, [268] = {min = 4776, max = 26091}, [269] = {min = 5532, max = 44171}, [270] = {min = 1029, max = 10306}, [102] = {min = 48, max = 69128}, [103] = {min = 12, max = 34808}, [104] = {min = 8649, max = 57866}, [105] = {min = 111, max = 5676}, [1468] = {min = 0, max = 9055}, [257] = {min = 0, max = 13921}, [264] = {min = 0, max = 13998}, [258] = {min = 0, max = 37454}, [577] = {min = 4, max = 50291}, [70] = {min = 9, max = 39581}, [255] = {min = 19545, max = 35969}, [62] = {min = 9015, max = 58220}, [64] = {min = 238, max = 39381}, [73] = {min = 5606, max = 21926}, [251] = {min = 5159, max = 45765}, [71] = {min = 3177, max = 42030}, [261] = {min = 17589, max = 35743}, [250] = {min = 5052, max = 29744}, [1467] = {min = 21, max = 53874}, [252] = {min = 42, max = 55027}, [253] = {min = 131, max = 56301}, [254] = {min = 7216, max = 25786}, [63] = {min = 3080, max = 44934}, + }, + + [2542] = { + encounterName = "Skolex, the Insatiable Ravener", + difficultyId = 16, + encounterId = 2542, + [256] = {min = 1660, max = 8282}, [577] = {min = 949, max = 66929}, [258] = {min = 6726, max = 58808}, [259] = {min = 11187, max = 43587}, [260] = {min = 0, max = 64508}, [581] = {min = 3985, max = 32690}, [262] = {min = 7548, max = 70129}, [263] = {min = 2443, max = 56677}, [264] = {min = 0, max = 29608}, [265] = {min = 5349, max = 119245}, [266] = {min = 8728, max = 81211}, [267] = {min = 0, max = 60711}, [268] = {min = 4051, max = 38896}, [269] = {min = 374, max = 72983}, [270] = {min = 144, max = 17106}, [102] = {min = 40, max = 108134}, [103] = {min = 0, max = 43682}, [104] = {min = 3119, max = 74814}, [105] = {min = 6, max = 12923}, [65] = {min = 0, max = 21372}, [1468] = {min = 0, max = 9218}, [71] = {min = 0, max = 61207}, [257] = {min = 0, max = 11007}, [255] = {min = 10013, max = 48432}, [254] = {min = 8829, max = 36167}, [72] = {min = 132, max = 77011}, [70] = {min = 324, max = 72764}, [1467] = {min = 476, max = 66210}, [73] = {min = 4923, max = 28826}, [66] = {min = 59, max = 32459}, [64] = {min = 9, max = 65568}, [261] = {min = 13385, max = 42379}, [250] = {min = 581, max = 41322}, [251] = {min = 237, max = 62833}, [252] = {min = 336, max = 84710}, [253] = {min = 3080, max = 96027}, [62] = {min = 1572, max = 56735}, [63] = {min = 5530, max = 58773}, + }, + + [2539] = { + encounterName = "Lihuvim, Principal Architect", + difficultyId = 16, + encounterId = 2539, + [256] = {min = 3011, max = 7868}, [577] = {min = 1132, max = 72054}, [66] = {min = 5123, max = 26117}, [259] = {min = 14790, max = 51766}, [260] = {min = 1190, max = 59834}, [581] = {min = 6246, max = 29596}, [262] = {min = 12650, max = 75350}, [263] = {min = 11347, max = 50277}, [72] = {min = 4641, max = 65615}, [265] = {min = 8015, max = 169882}, [266] = {min = 11103, max = 79833}, [267] = {min = 0, max = 52499}, [268] = {min = 6084, max = 40329}, [269] = {min = 13185, max = 69375}, [270] = {min = 618, max = 19657}, [102] = {min = 54, max = 109717}, [103] = {min = 12387, max = 48102}, [104] = {min = 8444, max = 71747}, [105] = {min = 0, max = 11354}, [70] = {min = 0, max = 67326}, [257] = {min = 80, max = 8273}, [1468] = {min = 0, max = 9596}, [264] = {min = 0, max = 25636}, [63] = {min = 6489, max = 63280}, [62] = {min = 10213, max = 62808}, [261] = {min = 8793, max = 35809}, [71] = {min = 257, max = 51415}, [251] = {min = 5799, max = 55044}, [258] = {min = 3482, max = 55788}, [64] = {min = 24, max = 61930}, [73] = {min = 5770, max = 33081}, [65] = {min = 31, max = 12068}, [250] = {min = 3839, max = 41956}, [1467] = {min = 1258, max = 98542}, [252] = {min = 24, max = 80672}, [253] = {min = 0, max = 111086}, [254] = {min = 12780, max = 34447}, [255] = {min = 25418, max = 38668}, + }, + + [2529] = { + encounterName = "Halondrus the Reclaimer", + difficultyId = 16, + encounterId = 2529, + [64] = {min = 5056, max = 28896}, [577] = {min = 7093, max = 45045}, [258] = {min = 9106, max = 30073}, [259] = {min = 16679, max = 36056}, [260] = {min = 407, max = 45629}, [261] = {min = 17450, max = 29193}, [262] = {min = 11546, max = 31585}, [71] = {min = 2645, max = 37612}, [72] = {min = 3784, max = 41779}, [265] = {min = 7701, max = 41880}, [266] = {min = 6232, max = 38614}, [267] = {min = 9089, max = 33653}, [268] = {min = 4061, max = 20363}, [269] = {min = 7826, max = 36996}, [270] = {min = 429, max = 12408}, [102] = {min = 68, max = 68528}, [103] = {min = 14432, max = 34306}, [104] = {min = 6736, max = 52497}, [105] = {min = 0, max = 10141}, [1468] = {min = 0, max = 4893}, [257] = {min = 0, max = 9311}, [70] = {min = 19, max = 40946}, [264] = {min = 65, max = 13698}, [255] = {min = 28135, max = 30662}, [254] = {min = 15813, max = 19925}, [65] = {min = 1405, max = 14512}, [256] = {min = 2245, max = 5362}, [251] = {min = 7892, max = 41885}, [73] = {min = 730, max = 20118}, [263] = {min = 11272, max = 35673}, [66] = {min = 5231, max = 13732}, [581] = {min = 4605, max = 22964}, [250] = {min = 5940, max = 24676}, [1467] = {min = 3570, max = 32861}, [252] = {min = 6175, max = 59998}, [253] = {min = 5431, max = 51637}, [62] = {min = 860, max = 31660}, [63] = {min = 2585, max = 32445}, + }, + + [2537] = { + encounterName = "The Jailer", + difficultyId = 16, + encounterId = 2537, + [64] = {min = 163, max = 66605}, [65] = {min = 23, max = 16095}, [258] = {min = 33, max = 65322}, [259] = {min = 0, max = 61954}, [260] = {min = 4, max = 68358}, [261] = {min = 10, max = 63011}, [262] = {min = 24, max = 71824}, [71] = {min = 23, max = 68116}, [72] = {min = 0, max = 81676}, [73] = {min = 36, max = 34610}, [266] = {min = 10, max = 73962}, [267] = {min = 5, max = 70493}, [268] = {min = 578, max = 42536}, [269] = {min = 0, max = 86592}, [270] = {min = 6, max = 17608}, [102] = {min = 0, max = 120056}, [103] = {min = 2, max = 52493}, [104] = {min = 63, max = 90099}, [105] = {min = 0, max = 8947}, [70] = {min = 0, max = 81460}, [577] = {min = 4, max = 85436}, [1468] = {min = 0, max = 12279}, [255] = {min = 2933, max = 47242}, [254] = {min = 54, max = 58569}, [265] = {min = 121, max = 154457}, [66] = {min = 5, max = 32383}, [251] = {min = 23, max = 80501}, [581] = {min = 9, max = 39238}, [264] = {min = 0, max = 18841}, [257] = {min = 0, max = 19892}, [263] = {min = 56, max = 65007}, [256] = {min = 55, max = 10584}, [250] = {min = 54, max = 58082}, [1467] = {min = 7, max = 72426}, [252] = {min = 17, max = 92259}, [253] = {min = 0, max = 130009}, [62] = {min = 317, max = 77104}, [63] = {min = 140, max = 82191}, + }, + + [2540] = { + encounterName = "Dausegne, the Fallen Oracle", + difficultyId = 16, + encounterId = 2540, + [256] = {min = 2261, max = 8920}, [577] = {min = 229, max = 84685}, [258] = {min = 8129, max = 62342}, [259] = {min = 1836, max = 53743}, [260] = {min = 15, max = 67308}, [581] = {min = 4489, max = 41766}, [262] = {min = 2376, max = 70828}, [263] = {min = 3814, max = 57779}, [264] = {min = 0, max = 31010}, [265] = {min = 6330, max = 205013}, [266] = {min = 9207, max = 120339}, [267] = {min = 0, max = 60703}, [268] = {min = 4450, max = 46429}, [269] = {min = 0, max = 83255}, [270] = {min = 131, max = 21087}, [102] = {min = 107, max = 136214}, [103] = {min = 1950, max = 52186}, [104] = {min = 5489, max = 100541}, [105] = {min = 118, max = 12519}, [64] = {min = 0, max = 79918}, [254] = {min = 0, max = 37574}, [1468] = {min = 0, max = 12974}, [257] = {min = 0, max = 10371}, [255] = {min = 18456, max = 42526}, [65] = {min = 104, max = 22834}, [66] = {min = 5604, max = 32507}, [72] = {min = 642, max = 66439}, [251] = {min = 2733, max = 74272}, [73] = {min = 974, max = 34317}, [261] = {min = 16576, max = 49824}, [70] = {min = 1560, max = 71870}, [71] = {min = 1291, max = 61619}, [250] = {min = 4413, max = 46804}, [1467] = {min = 88, max = 90726}, [252] = {min = 921, max = 86261}, [253] = {min = 152, max = 122104}, [62] = {min = 7768, max = 67170}, [63] = {min = 128, max = 81629}, + }, + + [2544] = { + encounterName = "Prototype Pantheon", + difficultyId = 16, + encounterId = 2544, + [256] = {min = 1467, max = 8575}, [577] = {min = 11087, max = 74432}, [258] = {min = 9355, max = 70028}, [259] = {min = 16258, max = 51420}, [260] = {min = 3085, max = 67981}, [581] = {min = 9326, max = 46505}, [70] = {min = 7208, max = 85924}, [263] = {min = 13278, max = 68027}, [72] = {min = 4743, max = 79646}, [73] = {min = 8697, max = 37977}, [266] = {min = 20877, max = 124897}, [267] = {min = 0, max = 63397}, [268] = {min = 10094, max = 57005}, [269] = {min = 120, max = 96070}, [270] = {min = 470, max = 23504}, [102] = {min = 104, max = 111666}, [103] = {min = 663, max = 64002}, [104] = {min = 9424, max = 100330}, [105] = {min = 0, max = 14378}, [1468] = {min = 0, max = 12555}, [1467] = {min = 0, max = 99448}, [257] = {min = 0, max = 13864}, [264] = {min = 0, max = 29500}, [255] = {min = 22870, max = 47224}, [254] = {min = 10349, max = 52557}, [64] = {min = 7, max = 105331}, [65] = {min = 494, max = 18457}, [262] = {min = 36, max = 79752}, [265] = {min = 15967, max = 193747}, [66] = {min = 6774, max = 31577}, [261] = {min = 23728, max = 45070}, [71] = {min = 2872, max = 59317}, [250] = {min = 9976, max = 53933}, [251] = {min = 14052, max = 75024}, [252] = {min = 5681, max = 103977}, [253] = {min = 2542, max = 112982}, [62] = {min = 1469, max = 66056}, [63] = {min = 254, max = 75081}, + }, + + [2543] = { + encounterName = "Lords of Dread", + difficultyId = 16, + encounterId = 2543, + [64] = {min = 2502, max = 114225}, [65] = {min = 253, max = 22346}, [258] = {min = 294, max = 96439}, [259] = {min = 17327, max = 59147}, [260] = {min = 0, max = 84630}, [581] = {min = 14713, max = 54438}, [262] = {min = 6559, max = 81248}, [263] = {min = 11038, max = 114766}, [72] = {min = 31, max = 96836}, [265] = {min = 3005, max = 215712}, [266] = {min = 1860, max = 110359}, [267] = {min = 5794, max = 121131}, [268] = {min = 49, max = 67378}, [269] = {min = 1552, max = 113755}, [270] = {min = 29, max = 22652}, [102] = {min = 0, max = 236482}, [103] = {min = 10628, max = 92694}, [104] = {min = 18723, max = 123898}, [105] = {min = 0, max = 14228}, [1468] = {min = 0, max = 11523}, [1467] = {min = 0, max = 116256}, [257] = {min = 0, max = 26046}, [264] = {min = 0, max = 30717}, [255] = {min = 3833, max = 58314}, [62] = {min = 2927, max = 118934}, [66] = {min = 46, max = 68190}, [577] = {min = 61, max = 96590}, [73] = {min = 7063, max = 42825}, [256] = {min = 1860, max = 16383}, [70] = {min = 28, max = 119230}, [261] = {min = 9, max = 63535}, [71] = {min = 2156, max = 123888}, [250] = {min = 4323, max = 87139}, [251] = {min = 3137, max = 98430}, [252] = {min = 47, max = 130374}, [253] = {min = 208, max = 129046}, [254] = {min = 10531, max = 62653}, [63] = {min = 5331, max = 112939}, + }, + + [2512] = { + encounterName = "Vigilant Guardian", + difficultyId = 16, + encounterId = 2512, + [256] = {min = 1627, max = 15396}, [65] = {min = 0, max = 22817}, [66] = {min = 5194, max = 43170}, [259] = {min = 16363, max = 51786}, [260] = {min = 8973, max = 81427}, [581] = {min = 7366, max = 42701}, [262] = {min = 2758, max = 76725}, [263] = {min = 10530, max = 70638}, [72] = {min = 0, max = 94150}, [73] = {min = 4713, max = 44133}, [266] = {min = 12508, max = 92878}, [267] = {min = 0, max = 73103}, [268] = {min = 6520, max = 48122}, [269] = {min = 0, max = 96037}, [270] = {min = 95, max = 15823}, [102] = {min = 0, max = 128755}, [103] = {min = 6927, max = 59516}, [104] = {min = 85, max = 79825}, [105] = {min = 115, max = 11237}, [70] = {min = 0, max = 82011}, [64] = {min = 0, max = 76943}, [63] = {min = 0, max = 86800}, [577] = {min = 0, max = 80000}, [258] = {min = 3042, max = 78984}, [254] = {min = 1293, max = 57475}, [261] = {min = 11056, max = 51154}, [1468] = {min = 0, max = 16683}, [1467] = {min = 304, max = 102275}, [71] = {min = 0, max = 83289}, [265] = {min = 1240, max = 135593}, [264] = {min = 0, max = 25232}, [257] = {min = 0, max = 25197}, [250] = {min = 4421, max = 59154}, [251] = {min = 0, max = 82985}, [252] = {min = 0, max = 95127}, [253] = {min = 0, max = 118264}, [62] = {min = 0, max = 91924}, [255] = {min = 14206, max = 47431}, + }, + + [2553] = { + encounterName = "Artificer Xy'mox", + difficultyId = 16, + encounterId = 2553, + [256] = {min = 797, max = 7404}, [577] = {min = 4, max = 51659}, [66] = {min = 3005, max = 23645}, [259] = {min = 18438, max = 37961}, [260] = {min = 3475, max = 52019}, [581] = {min = 6136, max = 25313}, [262] = {min = 22, max = 62229}, [263] = {min = 5129, max = 42172}, [72] = {min = 2096, max = 48641}, [73] = {min = 3076, max = 22067}, [266] = {min = 7938, max = 70181}, [267] = {min = 61, max = 45052}, [268] = {min = 5924, max = 34167}, [269] = {min = 13, max = 57008}, [270] = {min = 498, max = 14915}, [102] = {min = 55, max = 82505}, [103] = {min = 5437, max = 38185}, [104] = {min = 6453, max = 51754}, [105] = {min = 107, max = 10952}, [1468] = {min = 0, max = 8374}, [257] = {min = 0, max = 9080}, [264] = {min = 0, max = 21505}, [65] = {min = 3, max = 13631}, [64] = {min = 5, max = 63392}, [255] = {min = 6707, max = 33658}, [254] = {min = 3043, max = 40855}, [70] = {min = 24, max = 47404}, [265] = {min = 3685, max = 111394}, [251] = {min = 1774, max = 50182}, [71] = {min = 635, max = 40356}, [258] = {min = 7282, max = 41833}, [261] = {min = 17678, max = 37062}, [250] = {min = 154, max = 36124}, [1467] = {min = 488, max = 52310}, [252] = {min = 44, max = 61758}, [253] = {min = 108, max = 58369}, [62] = {min = 9490, max = 48616}, [63] = {min = 124, max = 53016}, + }, + + [2546] = { + encounterName = "Anduin Wrynn", + difficultyId = 16, + encounterId = 2546, + [64] = {min = 13310, max = 100905}, [65] = {min = 866, max = 19784}, [66] = {min = 16093, max = 67052}, [259] = {min = 33340, max = 76875}, [260] = {min = 40, max = 99983}, [261] = {min = 35761, max = 80096}, [262] = {min = 26788, max = 102392}, [71] = {min = 6257, max = 109950}, [264] = {min = 0, max = 42249}, [73] = {min = 11010, max = 60141}, [266] = {min = 11305, max = 89744}, [267] = {min = 15, max = 87282}, [268] = {min = 8572, max = 62243}, [269] = {min = 12256, max = 115165}, [270] = {min = 557, max = 30189}, [102] = {min = 47, max = 149146}, [103] = {min = 14220, max = 100089}, [104] = {min = 21840, max = 101125}, [105] = {min = 41, max = 23435}, [1468] = {min = 0, max = 20941}, [72] = {min = 0, max = 111321}, [257] = {min = 0, max = 31938}, [581] = {min = 14889, max = 54920}, [255] = {min = 36161, max = 73728}, [254] = {min = 34837, max = 98306}, [577] = {min = 366, max = 167035}, [258] = {min = 41, max = 82571}, [251] = {min = 17323, max = 103732}, [256] = {min = 1417, max = 14445}, [263] = {min = 6894, max = 104238}, [265] = {min = 26994, max = 177927}, [70] = {min = 18, max = 118124}, [250] = {min = 4747, max = 83442}, [1467] = {min = 129, max = 120937}, [252] = {min = 16, max = 120978}, [253] = {min = 996, max = 163203}, [62] = {min = 21848, max = 122162}, [63] = {min = 3081, max = 132784}, + }, + }, + + [15] = { --17 to test on raid finder + [2537] = { + encounterName = "The Jailer", + difficultyId = 15, + encounterId = 2537, + [256] = {min = 15, max = 8959}, [257] = {min = 0, max = 13934}, [258] = {min = 0, max = 65252}, [259] = {min = 0, max = 58866}, [260] = {min = 0, max = 63798}, [261] = {min = 0, max = 44350}, [262] = {min = 0, max = 64091}, [71] = {min = 0, max = 62485}, [264] = {min = 0, max = 14565}, [265] = {min = 0, max = 139087}, [266] = {min = 0, max = 76676}, [267] = {min = 0, max = 54435}, [268] = {min = 0, max = 37138}, [269] = {min = 0, max = 69644}, [270] = {min = 0, max = 14470}, [102] = {min = 0, max = 99872}, [103] = {min = 3, max = 47215}, [104] = {min = 0, max = 69376}, [105] = {min = 0, max = 8394}, [70] = {min = 0, max = 83930}, [65] = {min = 0, max = 15871}, [64] = {min = 0, max = 65529}, [63] = {min = 0, max + = 82999}, [577] = {min = 0, max = 67002}, [62] = {min = 0, max = 68100}, [66] = {min = 0, max = 33886}, [1468] = {min = 0, max = 11867}, [1467] = {min = 0, max = 57933}, [263] = {min = 0, max = 61092}, [581] = {min = 0, max = 42647}, [73] = {min = 0, max = 23625}, [72] = {min = 0, max = 64040}, [250] = {min = 0, max = 35509}, [251] = {min = 0, max = 67179}, [252] = {min = 0, max = 88558}, [253] = {min = 0, max = 111049}, [254] = {min = 0, max = 36079}, [255] = {min = 0, max = 36569}, + }, + + [2549] = { + encounterName = "Rygelon", + difficultyId = 15, + encounterId = 2549, + [256] = {min = 30, max = 9670}, [257] = {min = 0, max = 15147}, [258] = {min = 9, max = 47884}, [259] = {min = 8, max = 38848}, [260] = {min = 0, max = 53192}, [261] = {min = 9, max = 35739}, [262] = {min = 0, max = 47231}, [263] = {min = 0, max = 47665}, [264] = {min = 0, max = 13195}, [265] = {min = 54, max = 98712}, [266] = {min = 0, max = 43400}, [267] = {min = 0, max = 44086}, [268] = {min = 47, max = 31473}, [269] = {min = 0, max = 44870}, [270] = {min = 0, max = 12388}, [102] = {min = 0, max = 65153}, [103] = {min = 7, max = 37474}, [104] = {min = 0, max = 63012}, [105] = {min = 0, max = 10755}, [70] = {min = 0, max = 49585}, [66] = {min = 0, max = 24391}, [65] = {min = 0, max = 15135}, [64] = {min = 0, max = 36869}, [255] = {min = 103, max = 26606}, [62] = {min = 43, max = 58110}, [71] = {min = 0, max = 46517}, [252] = {min = 5, max = 60052}, [1467] = {min = 0, max = 37942}, [581] = {min = 0, max = 35291}, [72] = {min = 0, max = 49275}, [73] = {min = 0, max = 19236}, [577] = {min = 0, max = 45108}, [250] = {min = 3, max = 28547}, [251] = {min = 0, max = 51155}, [1468] = {min = 0, max = 9578}, [253] = {min = 0, max = 60657}, [254] = {min = 0, max = 27647}, [63] = {min = 0, max = 52600}, + }, + + [2512] = { + encounterName = "Vigilant Guardian", + difficultyId = 15, + encounterId = 2512, + [64] = {min = 0, max = 47744}, [257] = {min = 0, max = 9018}, [258] = {min = 0, max = 41701}, [259] = {min = 0, max = 38397}, [260] = {min = 0, max = 47671}, [261] = {min = 4, max = 24293}, [262] = {min = 18, max = 43486}, [71] = {min = 17, max = 44877}, [264] = {min = 0, max = 12857}, [73] = {min = 0, max = 18670}, [266] = {min = 0, max = 44779}, [267] = {min = 0, max = 38536}, [268] = {min = 2008, max = 32757}, [269] = {min = 0, max = 67971}, [270] = {min = 0, max = 11710}, [102] = {min = 0, max = 66199}, [103] = {min = 0, max = 32670}, [104] = {min = 0, max = 49388}, [105] = {min = 0, max = 5641}, [256] = {min = 0, max = 9040}, [70] = {min = 0, max = 66502}, [65] = {min = 0, max = 8745}, [255] = {min + = 0, max = 26681}, [62] = {min = 0, max = 48329}, [265] = {min = 0, max = 83160}, [1468] = {min = 0, max = 7341}, [1467] = {min = 0, max = 47176}, [581] = {min = 0, max = 36612}, [577] = {min = 0, max = 48211}, [66] = {min = 6, max = 26990}, [72] = {min = 0, max = 47381}, [263] = {min = 0, max = 46259}, [250] = {min = 0, max = 29562}, [251] = {min = 0, max = 41950}, [252] = {min = 0, max = 61884}, [253] = {min = 0, max = 79911}, [254] = {min = 0, max = 25300}, [63] = {min = 0, max = 64871}, + }, + + [2543] = { + encounterName = "Lords of Dread", + difficultyId = 15, + encounterId = 2543, + [64] = {min = 0, max = 143327}, [257] = {min = 0, max = 15949}, [258] = {min = 0, max = 116028}, [259] = {min = 0, max = 87466}, [260] = {min = 0, max = 102099}, [261] = {min = 0, max = 53316}, [262] = {min = 0, max = 81944}, [263] = {min = 2, max = 109760}, [264] = {min = 0, max = 26180}, [73] = {min = 0, max = 38867}, [266] = {min = 0, max = 106380}, [267] = {min = 0, max = 95200}, [268] = {min = 32, max = 80110}, [269] = {min = 0, max = 117413}, [270] = {min = 0, max = 21669}, [102] = {min = 0, max = 293153}, [103] = {min = 0, max = 103736}, [104] = {min = 0, max = 135974}, [105] = {min = 0, max = 10655}, [256] = {min = 0, max = 13368}, [70] = {min = 0, max = 122920}, [65] + = {min = 0, max = 30901}, [255] = {min = 86, max = 86188}, [62] = {min = 23, max = 151537}, [66] = {min = 2, max = 91605}, [252] = {min = 13, max = 123127}, [1467] = {min = 0, max = 103169}, [581] = {min = 0, max = 64520}, [265] = {min = 0, max = 176578}, [71] = {min = 0, max = 132533}, [72] = {min = 0, max = 103813}, [577] = {min = 0, max = 101076}, [250] = {min = 1, max = 59608}, [251] = {min = 0, max = 128489}, [1468] = {min = 0, max = 19807}, [253] = {min = 0, max = 125235}, [254] = {min = 11, max = 91006}, [63] = {min = 0, max = 114060}, + }, + + [2540] = { + encounterName = "Dausegne, the Fallen Oracle", + difficultyId = 15, + encounterId = 2540, + [256] = {min = 27, max = 15423}, [257] = {min = 0, max = 15987}, [66] = {min = 6, max = 51881}, [259] = {min = 0, max = 59925}, [260] = {min = 0, max = 75489}, [261] = {min + = 0, max = 26192}, [262] = {min = 0, max = 94827}, [263] = {min = 0, max = 72319}, [264] = {min = 0, max = 24611}, [265] = {min = 0, max = 242780}, [266] = {min = 0, max = 97498}, [267] = {min = 299, max = 69105}, [268] = {min = 0, max = 66270}, [269] = {min = 0, max = 90107}, [270] = {min = 0, max = 15806}, [102] = {min = 0, max = 183109}, [103] = {min = 49, max = 60617}, [104] = {min = 0, max = 128962}, [105] = {min = 0, max = 12744}, [70] = {min = 0, max = 101326}, [65] = {min = 0, max = 23287}, [63] = {min = 0, max + = 126577}, [258] = {min = 0, max = 82241}, [62] = {min = 648, max = 135298}, [64] = {min = 4, max = 99064}, [1468] = {min = 0, max = 16105}, [1467] = {min = 0, max = 76872}, [71] = {min = 0, max = 69054}, [72] = {min = 0, max = 74877}, [73] = {min = 0, max = 26494}, [577] = {min = 0, max = 87321}, [581] = {min = 0, max = 48213}, [250] = {min = 6, max = 59945}, [251] = {min = 0, max = 81458}, [252] = {min = 0, max = 144306}, [253] = {min = 0, max = 152407}, [254] = {min = 0, max = 40232}, [255] = {min = 0, max = 47516}, + }, + + [2546] = { + encounterName = "Anduin Wrynn", + difficultyId = 15, + encounterId = 2546, + [64] = {min = 0, max = 100040}, [257] = {min = 0, max = 19732}, [258] = {min = 2, max = 81782}, [259] = {min = 0, max = 93638}, [260] = {min = 0, max = 96245}, [261] = {min = 0, max = 50610}, [262] = {min = 0, max = 97561}, [263] = {min = 0, max = 108748}, [264] = {min = 0, max = 29753}, [265] = {min = 0, max = 135030}, [266] = {min = 0, max = 80540}, [267] = {min = 0, max = 81394}, [268] = {min = 11, max = 74655}, [269] = {min = 0, max = 90405}, [270] = {min = 0, max = 18010}, [102] = {min = 0, max = 185767}, [103] = {min = 0, max = 80344}, [104] = {min = 0, max = 99768}, [105] = {min = 0, max = 17810}, [256] = {min = 0, max = 18632}, [70] = {min = 0, max = 150788}, [65] = {min = 0, max = 23109}, [255] = {min = 18, max = 52548}, [62] = {min = 7, max = 107795}, [66] = {min = 1, max = 60289}, [1468] = {min = 0, max = 20589}, [251] = {min = 3, max = 107230}, [71] = {min = 0, max = 120222}, [72] = {min = 0, max = 118753}, [73] = {min = 0, max = 36569}, [577] = {min = 0, max = 96636}, [581] = {min = 0, max = 74331}, [250] = {min = 1, max = 61297}, [1467] = {min = 0, max = 79615}, [252] = {min = 0, max = 140278}, [253] = {min = 0, max = 131235}, [254] = {min = 0, max = 65598}, [63] = {min = 0, max = 132792}, + }, + + [2539] = { + encounterName = "Lihuvim, Principal Architect", + difficultyId = 15, + encounterId = 2539, + [64] = {min = 0, max = 95745}, [257] = {min = 0, max = 14538}, [258] = {min = 8, max = 60754}, [259] = {min = 0, max = 62899}, [260] = {min = 0, max = 78032}, [261] = {min = 0, max = 37570}, [262] = {min = 0, max = 86220}, [71] = {min = 8, max = 82121}, [264] = {min = 0, max = 19346}, [265] = {min = 0, max = 191718}, [266] = {min = 0, max = 118577}, [267] = {min = 0, max = 68510}, [268] = {min = 0, max = 65256}, [269] = {min = 0, max = 93815}, [270] = {min = 0, max = 17737}, [102] = {min = 0, max = 226280}, [103] = {min = 47, max = 61461}, [104] = {min = 50, max = 88592}, [105] = {min = 0, max = 10698}, [256] = {min = 0, max = 13562}, [70] = {min = 0, max = 90840}, [65] = {min = 0, max = 20993}, [255] = {min = 0, max = 40955}, [62] = {min = 110, max = 96212}, [72] = {min = 0, max = 80140}, [1468] = {min = 0, max = 17450}, [1467] = {min = 0, max = 70482}, [263] = {min = 0, max = 73164}, [73] = {min = 0, max = 34590}, [577] = {min = 0, max = 91632}, [581] = {min = 0, max = 48545}, [66] = {min = 3, max = 48774}, [250] = {min = 0, max = 74413}, [251] = {min = 0, max = 66403}, [252] = {min = 0, max = 108284}, [253] = {min = 0, max = 163139}, [254] = {min = 0, max = 39281}, [63] = {min = 0, max = 95348}, + }, + + [2529] = { + encounterName = "Halondrus the Reclaimer", + difficultyId = 15, + encounterId = 2529, + [64] = {min = 28, max = 44154}, [257] = {min = 0, max = 10446}, [258] = {min = 0, max = 47129}, [259] = {min = 0, max = 44919}, [260] = {min = 4, max = 50932}, [261] = {min = 0, max = 21011}, [262] = {min = 0, max = 40749}, [71] = {min = 17, max = 47420}, [72] = {min = 0, max = 51611}, [265] = {min = 0, max = 66416}, [266] = {min = 0, max = 48778}, [267] = {min + = 0, max = 40900}, [268] = {min = 1119, max = 28039}, [269] = {min = 0, max = 51753}, [270] = {min = 0, max = 11042}, [102] = {min = 0, max = 79687}, [103] = {min = 0, max = 40354}, [104] = {min = 17, max = 75226}, [105] = {min = 0, max = 10229}, [256] = {min = 0, max = 8034}, [70] = {min = 0, max = 55712}, [66] = {min = 0, max = 22331}, [65] = {min = 0, max = 12609}, [255] = {min = 879, max = 26729}, [254] = {min = 46, max = 32832}, [581] = {min = 4, max = 27475}, [1468] = {min = 0, max = 8495}, [251] = {min = 16, max = 48231}, [577] = {min = 0, max = 51834}, [263] = {min = 0, max = 44925}, [264] = {min = 0, max = 12054}, [73] = {min = 0, max = 17782}, [250] = {min = 16, max = 24068}, [1467] = {min = 0, max = 41245}, [252] = {min = 0, max = 69430}, [253] = {min = 0, max = 69978}, [62] = {min = 215, max = 38895}, [63] = {min = 0, max = 60766}, + }, + + [2542] = { + encounterName = "Skolex, the Insatiable Ravener", + difficultyId = 15, + encounterId = 2542, + [256] = {min = 271, max = 10094}, [257] = {min = 0, max = 14406}, [66] = {min = 16, max = 51537}, [259] = {min = 0, max = 64691}, [260] = {min = 0, max = 71433}, [261] = {min + = 0, max = 29475}, [262] = {min = 0, max = 83649}, [263] = {min = 0, max = 69501}, [264] = {min = 0, max = 17591}, [265] = {min = 0, max = 152230}, [266] = {min = 0, max = 94325}, [267] = {min = 0, max = 70824}, [268] = {min = 0, max = 42793}, [269] = {min = 0, max = 93975}, [270] = {min = 0, max = 24151}, [102] = {min = 0, max = 199522}, [103] = {min + = 0, max = 57741}, [104] = {min = 0, max = 72943}, [105] = {min = 0, max = 13211}, [70] = {min = 0, max = 100549}, [65] = {min = 0, max = 20763}, [64] = {min = 0, max = 88475}, [255] = {min = 112, max = 42084}, [62] = {min = 0, max = 96368}, [73] = {min = 0, max = 28507}, [1468] = {min = 0, max = 11553}, [1467] = {min = 0, max = 76901}, [258] = {min + = 0, max = 65188}, [577] = {min = 0, max = 78885}, [581] = {min = 0, max = 46778}, [72] = {min = 0, max = 79490}, [71] = {min = 0, max = 72782}, [250] = {min = 0, max = 55900}, [251] = {min = 0, max = 75438}, [252] = {min = 0, max = 125691}, [253] = {min = 0, max = 112643}, [254] = {min = 0, max = 39698}, [63] = {min = 0, max = 115827}, + }, + + [2544] = { + encounterName = "Prototype Pantheon", + difficultyId = 15, + encounterId = 2544, + [64] = {min = 0, max = 108283}, [257] = {min = 0, max = 15220}, [258] = {min = 0, max = 72731}, [259] = {min = 0, max = 57688}, [260] = {min = 0, max = 68463}, [261] = {min = 0, max = 29653}, [262] = {min = 0, max = 82429}, [263] = {min = 0, max = 75930}, [264] = {min = 0, max = 22283}, [265] = {min = 0, max = 275775}, [266] = {min = 0, max = 131667}, [267] = {min = 0, max = 66544}, [268] = {min = 2263, max = 57813}, [269] = {min = 0, max = 99127}, [270] = {min = 0, max = 22205}, [102] = {min = 0, max = 134851}, [103] = {min + = 0, max = 52823}, [104] = {min = 112, max = 92505}, [105] = {min = 0, max = 14270}, [256] = {min = 0, max = 16529}, [70] = {min = 0, max = 95961}, [65] = {min = 0, max = 19297}, [63] = {min = 73, max = 107171}, [62] = {min = 126, max = 91554}, [66] = {min = 3, max = 35003}, [1468] = {min = 0, max = 16638}, [1467] = {min = 0, max = 78207}, [71] = {min = 0, max = 61526}, [72] = {min = 0, max = 86095}, [73] = {min = 0, max = 25579}, [577] = {min = 0, max = 75173}, [581] = {min = 0, max = 49011}, [250] = {min = 13, max = 45176}, [251] = {min = 0, max = 79676}, [252] = {min = 0, max = 118116}, [253] = {min = 0, max = 114283}, [254] = {min = 0, max = 50788}, [255] = {min = 0, max = 38675}, + }, + + [2553] = { + encounterName = "Artificer Xy'mox", + difficultyId = 15, + encounterId = 2553, + [64] = {min = 0, max = 75227}, [257] = {min = 0, max = 16946}, [258] = {min = 0, max = 58744}, [259] = {min = 0, max = 58446}, [260] = {min = 0, max = 59794}, [261] = {min = 0, max = 26010}, [262] = {min = 17, max = 70740}, [263] = {min = 4, max = 57720}, [264] = {min = 0, max = 19465}, [265] = {min = 0, max = 162348}, [266] = {min = 0, max = 84628}, [267] = {min = 0, max = 52454}, [268] = {min = 81, max = 39433}, [269] = {min = 0, max = 93118}, [270] = {min = 0, max = 20319}, [102] = {min = 0, max = 90077}, [103] = {min + = 13, max = 43399}, [104] = {min = 0, max = 64418}, [105] = {min = 0, max = 11345}, [256] = {min = 0, max = 15449}, [70] = {min = 0, max = 86984}, [66] = {min = 0, max = 32851}, [65] + = {min = 0, max = 16511}, [255] = {min = 0, max = 40009}, [254] = {min = 42, max = 51248}, [71] = {min = 49, max = 57600}, [252] = {min = 13, max = 98953}, [1467] = {min = 0, max = 59878}, [72] = {min = 0, max = 68892}, [73] = {min = 0, max = 24387}, [577] = {min = 0, max = 67419}, [581] = {min = 0, max = 50139}, [250] = {min = 6, max = 37574}, [251] = {min = 0, max = 67577}, [1468] = {min = 0, max = 18160}, [253] = {min = 0, max = 104953}, [62] = {min = 0, max = 74689}, [63] = {min = 0, max = 96869}, + }, + + }, + + --[14] = {} --normal + + --[17] = {} --raid finder + --}, + } + + + diff --git a/plugins/Details_Compare2/Details_Compare2.lua b/plugins/Details_Compare2/Details_Compare2.lua new file mode 100644 index 00000000..3e11b752 --- /dev/null +++ b/plugins/Details_Compare2/Details_Compare2.lua @@ -0,0 +1,1595 @@ + +do + local Details = Details + if (not Details) then + print ("Details! Not Found.") + return + end + + local _ + local DF = _G.DetailsFramework + local _ipairs = ipairs + local unpack = _G.unpack + local gameCooltip = GameCooltip2 + + --> minimal details version required to run this plugin + local MINIMAL_DETAILS_VERSION_REQUIRED = 136 + local COMPARETWO_VERSION = "v1.0.0" + + --> create a plugin object + local compareTwo = Details:NewPluginObject ("Details_Compare2", _G.DETAILSPLUGIN_ALWAYSENABLED) + --> just localizing here the plugin's main frame + local frame = compareTwo.Frame + --> set the description + compareTwo:SetPluginDescription("Replaces the default comparison window on the player breakdown.") + + --> when receiving an event from details, handle it here + local handle_details_event = function (event, ...) + + if (event == "COMBAT_PLAYER_ENTER") then + + elseif (event == "COMBAT_PLAYER_LEAVE") then + + elseif (event == "PLUGIN_DISABLED") then + --> plugin has been disabled at the details options panel + + elseif (event == "PLUGIN_ENABLED") then + --> plugin has been enabled at the details options panel + + elseif (event == "DETAILS_DATA_SEGMENTREMOVED") then + --> old segment got deleted by the segment limit + + elseif (event == "DETAILS_DATA_RESET") then + --> combat data got wiped + + end + end + + function compareTwo.InstallAdvancedCompareWindow() + + --colors to use on percent number + local red = "FFFFAAAA" + local green = "FFAAFFAA" + local plus = red .. "-" + local minor = green .. "+" + + local comparisonFrameSettings = { + --main player scroll frame + mainScrollWidth = 250, + petColor = "|cFFCCBBBB", + + --spell scroll + spellScrollHeight = 300, + spellLineAmount = 14, + spellLineHeight = 20, + + --target scroll + targetScrollHeight = 130, + targetScrollLineAmount = 6, + targetScrollLineHeight = 20, + + --comparison scrolls + comparisonScrollWidth = 140, + targetMaxLines = 16, + targetTooltipLineHeight = 16, + + --font settings + fontSize = 10, + playerNameSize = 12, + playerNameYOffset = 12, + + --line colors + lineOnEnterColor = {.85, .85, .85, .5}, + + --tooltips + tooltipBorderColor = {.2, .2, .2, .9}, + } + + local comparisonLineContrast = {{1, 1, 1, .1}, {1, 1, 1, 0}} + local latestLinesHighlighted = {} + local comparisonTooltips = {nextTooltip = 0} + local comparisonTargetTooltips = {nextTooltip = 0} + + local resetTargetComparisonTooltip = function() + comparisonTargetTooltips.nextTooltip = 0 + for _, tooltip in ipairs (comparisonTargetTooltips) do + for i = 1, #tooltip.lines do + local line = tooltip.lines [i] + line.spellIcon:SetTexture ("") + line.spellName:SetText ("") + line.spellAmount:SetText ("") + line.spellPercent:SetText ("") + line:Hide() + end + + tooltip:Hide() + tooltip:ClearAllPoints() + end + end + + local resetComparisonTooltip = function() + comparisonTooltips.nextTooltip = 0 + for _, tooltip in ipairs (comparisonTooltips) do + tooltip:Hide() + tooltip:ClearAllPoints() + end + end + + local getTargetComparisonTooltip = function() + comparisonTargetTooltips.nextTooltip = comparisonTargetTooltips.nextTooltip + 1 + local tooltip = comparisonTargetTooltips [comparisonTargetTooltips.nextTooltip] + + if (tooltip) then + return tooltip + end + + tooltip = CreateFrame ("frame", nil, UIParent, "BackdropTemplate") + tooltip:SetFrameStrata ("tooltip") + tooltip:SetSize (1, 1) + _detalhes.gump:CreateBorder (tooltip) + tooltip:SetBackdrop ({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\AddOns\Details\images\background]], tileSize = 64, tile = true}) + tooltip:SetBackdropColor (.2, .2, .2, .99) + tooltip:SetBackdropBorderColor (unpack (comparisonFrameSettings.tooltipBorderColor)) + tooltip:SetHeight (77) + + local bg_color = {0.5, 0.5, 0.5} + local bg_texture = [[Interface\AddOns\Details\images\bar_background]] + local bg_alpha = 1 + local bg_height = 12 + local colors = {{26/255, 26/255, 26/255}, {19/255, 19/255, 19/255}, {26/255, 26/255, 26/255}, {34/255, 39/255, 42/255}, {42/255, 51/255, 60/255}} + + --player name label + tooltip.player_name_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.player_name_label:SetPoint ("bottomleft", tooltip, "topleft", 1, 2) + tooltip.player_name_label:SetTextColor (1, .7, .1, .834) + DetailsFramework:SetFontSize (tooltip.player_name_label, 11) + + local name_bg = tooltip:CreateTexture (nil, "artwork") + name_bg:SetTexture (bg_texture) + name_bg:SetPoint ("bottomleft", tooltip, "topleft", 0, 1) + name_bg:SetPoint ("bottomright", tooltip, "topright", 0, 1) + name_bg:SetHeight (bg_height + 2) + name_bg:SetAlpha (bg_alpha) + name_bg:SetVertexColor (unpack (colors[2])) + + comparisonTargetTooltips [comparisonTargetTooltips.nextTooltip] = tooltip + + tooltip.lines = {} + + local lineHeight = comparisonFrameSettings.targetTooltipLineHeight + local fontSize = 10 + + for i = 1, comparisonFrameSettings.targetMaxLines do + local line = CreateFrame ("frame", nil, tooltip, "BackdropTemplate") + line:SetPoint ("topleft", tooltip, "topleft", 0, -(i-1) * (lineHeight + 1)) + line:SetPoint ("topright", tooltip, "topright", 0, -(i-1) * (lineHeight + 1)) + line:SetHeight (lineHeight) + + line:SetBackdrop ({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true}) + line:SetBackdropColor (0, 0, 0, 0.2) + + local spellIcon = line:CreateTexture ("$parentIcon", "overlay") + spellIcon:SetSize (lineHeight -2 , lineHeight - 2) + + local spellName = line:CreateFontString ("$parentName", "overlay", "GameFontNormal") + local spellAmount = line:CreateFontString ("$parentAmount", "overlay", "GameFontNormal") + local spellPercent = line:CreateFontString ("$parentPercent", "overlay", "GameFontNormal") + DetailsFramework:SetFontSize (spellName, fontSize) + DetailsFramework:SetFontSize (spellAmount, fontSize) + DetailsFramework:SetFontSize (spellPercent, fontSize) + + spellIcon:SetPoint ("left", line, "left", 2, 0) + spellName:SetPoint ("left", spellIcon, "right", 2, 0) + spellAmount:SetPoint ("right", line, "right", -2, 0) + spellPercent:SetPoint ("right", line, "right", -40, 0) + + spellName:SetJustifyH ("left") + spellAmount:SetJustifyH ("right") + spellPercent:SetJustifyH ("right") + + line.spellIcon = spellIcon + line.spellName = spellName + line.spellAmount = spellAmount + line.spellPercent = spellPercent + + tooltip.lines [#tooltip.lines+1] = line + + if (i % 2 == 0) then + line:SetBackdropColor (unpack (comparisonLineContrast [1])) + line.BackgroundColor = comparisonLineContrast [1] + else + line:SetBackdropColor (unpack (comparisonLineContrast [2])) + line.BackgroundColor = comparisonLineContrast [2] + end + end + + return tooltip + end + + local getComparisonTooltip = function() + comparisonTooltips.nextTooltip = comparisonTooltips.nextTooltip + 1 + local tooltip = comparisonTooltips [comparisonTooltips.nextTooltip] + + if (tooltip) then + return tooltip + end + + tooltip = CreateFrame ("frame", nil, UIParent, "BackdropTemplate") + tooltip:SetFrameStrata ("tooltip") + tooltip:SetSize (1, 1) + _detalhes.gump:CreateBorder (tooltip) + tooltip:SetBackdrop ({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\AddOns\Details\images\background]], tileSize = 64, tile = true}) + tooltip:SetBackdropColor (0, 0, 0, 1) + tooltip:SetBackdropBorderColor (unpack (comparisonFrameSettings.tooltipBorderColor)) + tooltip:SetHeight (77) + + comparisonTooltips [comparisonTooltips.nextTooltip] = tooltip + + --prototype + local y = -3 + local x_start = 2 + + local bg_color = {0.5, 0.5, 0.5} + local bg_texture = [[Interface\AddOns\Details\images\bar_background]] + local bg_alpha = 1 + local bg_height = 12 + local colors = {{26/255, 26/255, 26/255}, {19/255, 19/255, 19/255}, {26/255, 26/255, 26/255}, {34/255, 39/255, 42/255}, {42/255, 51/255, 60/255}} + + local background = tooltip:CreateTexture (nil, "border") + background:SetTexture ([[Interface\SPELLBOOK\Spellbook-Page-1]]) + background:SetTexCoord (.6, 0.1, 0, 0.64453125) + background:SetVertexColor (0, 0, 0, 0.2) + background:SetPoint ("topleft", tooltip, "topleft", 0, 0) + background:SetPoint ("bottomright", tooltip, "bottomright", 0, 0) + + --player name label + tooltip.player_name_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.player_name_label:SetPoint ("bottomleft", tooltip, "topleft", 1, 2) + tooltip.player_name_label:SetTextColor (1, .7, .1, .834) + DetailsFramework:SetFontSize (tooltip.player_name_label, 11) + + local name_bg = tooltip:CreateTexture (nil, "artwork") + name_bg:SetTexture (bg_texture) + name_bg:SetPoint ("bottomleft", tooltip, "topleft", 0, 1) + name_bg:SetPoint ("bottomright", tooltip, "topright", 0, 1) + name_bg:SetHeight (bg_height + 2) + name_bg:SetAlpha (bg_alpha) + name_bg:SetVertexColor (unpack (colors[2])) + + --cast line + tooltip.casts_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.casts_label:SetPoint ("topleft", tooltip, "topleft", x_start, -2 + (y*0)) + tooltip.casts_label:SetText ("Casts:") + tooltip.casts_label:SetJustifyH ("left") + tooltip.casts_label2 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.casts_label2:SetPoint ("topright", tooltip, "topright", -x_start, -2 + (y*0)) + tooltip.casts_label2:SetText ("0") + tooltip.casts_label2:SetJustifyH ("right") + tooltip.casts_label3 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.casts_label3:SetPoint ("topright", tooltip, "topright", -x_start - 46, -2 + (y*0)) + tooltip.casts_label3:SetText ("0") + tooltip.casts_label3:SetJustifyH ("right") + + --hits + tooltip.hits_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.hits_label:SetPoint ("topleft", tooltip, "topleft", x_start, -14 + (y*1)) + tooltip.hits_label:SetText ("Hits:") + tooltip.hits_label:SetJustifyH ("left") + tooltip.hits_label2 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.hits_label2:SetPoint ("topright", tooltip, "topright", -x_start, -14 + (y*1)) + tooltip.hits_label2:SetText ("0") + tooltip.hits_label2:SetJustifyH ("right") + tooltip.hits_label3 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.hits_label3:SetPoint ("topright", tooltip, "topright", -x_start - 46, -14 + (y*1)) + tooltip.hits_label3:SetText ("0") + tooltip.hits_label3:SetJustifyH ("right") + + --average + tooltip.average_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.average_label:SetPoint ("topleft", tooltip, "topleft", x_start, -26 + (y*2)) + tooltip.average_label:SetText ("Average:") + tooltip.average_label:SetJustifyH ("left") + tooltip.average_label2 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.average_label2:SetPoint ("topright", tooltip, "topright", -x_start, -26 + (y*2)) + tooltip.average_label2:SetText ("0") + tooltip.average_label2:SetJustifyH ("right") + tooltip.average_label3 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.average_label3:SetPoint ("topright", tooltip, "topright", -x_start - 46, -26 + (y*2)) + tooltip.average_label3:SetText ("0") + tooltip.average_label3:SetJustifyH ("right") + + --critical + tooltip.crit_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.crit_label:SetPoint ("topleft", tooltip, "topleft", x_start, -38 + (y*3)) + tooltip.crit_label:SetText ("Critical:") + tooltip.crit_label:SetJustifyH ("left") + tooltip.crit_label2 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.crit_label2:SetPoint ("topright", tooltip, "topright", -x_start, -38 + (y*3)) + tooltip.crit_label2:SetText ("0") + tooltip.crit_label2:SetJustifyH ("right") + tooltip.crit_label3 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.crit_label3:SetPoint ("topright", tooltip, "topright", -x_start - 46, -38 + (y*3)) + tooltip.crit_label3:SetText ("0") + tooltip.crit_label3:SetJustifyH ("right") + + --uptime + tooltip.uptime_label = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.uptime_label:SetPoint ("topleft", tooltip, "topleft", x_start, -50 + (y*4)) + tooltip.uptime_label:SetText ("Uptime:") + tooltip.uptime_label:SetJustifyH ("left") + tooltip.uptime_label2 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.uptime_label2:SetPoint ("topright", tooltip, "topright", -x_start, -50 + (y*4)) + tooltip.uptime_label2:SetText ("0") + tooltip.uptime_label2:SetJustifyH ("right") + tooltip.uptime_label3 = tooltip:CreateFontString (nil, "overlay", "GameFontHighlightSmall") + tooltip.uptime_label3:SetPoint ("topright", tooltip, "topright", -x_start - 46, -50 + (y*4)) + tooltip.uptime_label3:SetText ("0") + tooltip.uptime_label3:SetJustifyH ("right") + + for i = 1, 5 do + local bg_line1 = tooltip:CreateTexture (nil, "artwork") + bg_line1:SetTexture (bg_texture) + bg_line1:SetPoint ("topleft", tooltip, "topleft", 0, -2 + (((i-1) * 12) * -1) + (y * (i-1)) + 2) + bg_line1:SetPoint ("topright", tooltip, "topright", -0, -2 + (((i-1) * 12) * -1) + (y * (i-1)) + 2) + bg_line1:SetHeight (bg_height + 4) + bg_line1:SetAlpha (bg_alpha) + bg_line1:SetVertexColor (unpack (colors[i])) + end + + return tooltip + end + + --fill the tooltip for the main player being compared + --actualPlayerName is the name of the player being compared, playerName can be the name of a pet + local fillMainSpellTooltip = function (line, rawSpellTable, actualPlayerName, playerName) + local tooltip = getComparisonTooltip() + local formatFunc = Details:GetCurrentToKFunction() + local spellId = rawSpellTable.id + + tooltip.player_name_label:SetText (Details:GetOnlyName (actualPlayerName)) + + local fullPercent = "100%" + local noData = "-" + + --amount of casts + local castAmount = 0 + local combatObject = Details:GetCombatFromBreakdownWindow() + local playerMiscObject = combatObject:GetActor (DETAILS_ATTRIBUTE_MISC, playerName) + + if (playerMiscObject) then + castAmount = playerMiscObject.spell_cast and playerMiscObject.spell_cast [spellId] or 0 + tooltip.casts_label2:SetText (fullPercent) + tooltip.casts_label3:SetText (castAmount) + DetailsFramework:SetFontColor (tooltip.casts_label2, "gray") + DetailsFramework:SetFontColor (tooltip.casts_label3, "white") + else + tooltip.casts_label2:SetText (noData) + tooltip.casts_label3:SetText (noData) + DetailsFramework:SetFontColor (tooltip.casts_label2, "silver") + DetailsFramework:SetFontColor (tooltip.casts_label3, "silver") + end + + --hit amount + tooltip.hits_label2:SetText (fullPercent) + DetailsFramework:SetFontColor (tooltip.hits_label2, "gray") + tooltip.hits_label3:SetText (rawSpellTable.counter) + DetailsFramework:SetFontColor (tooltip.hits_label3, "white") + + --average + tooltip.average_label2:SetText (fullPercent) + DetailsFramework:SetFontColor (tooltip.average_label2, "gray") + local average = rawSpellTable.total / rawSpellTable.counter + tooltip.average_label3:SetText (formatFunc (_, average)) + + --critical strikes + tooltip.crit_label2:SetText (fullPercent) + DetailsFramework:SetFontColor (tooltip.crit_label2, "gray") + tooltip.crit_label3:SetText (rawSpellTable.c_amt) + + --uptime + local uptime = 0 + if (playerMiscObject) then + local spell = playerMiscObject.debuff_uptime_spells and playerMiscObject.debuff_uptime_spells._ActorTable and playerMiscObject.debuff_uptime_spells._ActorTable [spellId] + if (spell) then + local minutos, segundos = floor (spell.uptime / 60), floor (spell.uptime % 60) + uptime = spell.uptime + tooltip.uptime_label2:SetText (fullPercent) + tooltip.uptime_label3:SetText (minutos .. "m " .. segundos .. "s") + + DetailsFramework:SetFontColor (tooltip.uptime_label2, "gray") + DetailsFramework:SetFontColor (tooltip.uptime_label3, "white") + else + tooltip.uptime_label2:SetText (noData) + tooltip.uptime_label3:SetText (noData) + DetailsFramework:SetFontColor (tooltip.uptime_label2, "gray") + DetailsFramework:SetFontColor (tooltip.uptime_label3, "gray") + end + else + tooltip.uptime_label2:SetText (noData) + tooltip.uptime_label3:SetText (noData) + DetailsFramework:SetFontColor (tooltip.uptime_label2, "gray") + DetailsFramework:SetFontColor (tooltip.uptime_label3, "gray") + end + + --show tooltip + tooltip:SetPoint ("bottom", line, "top", 0, 2) + tooltip:SetWidth (line:GetWidth()) + tooltip:Show() + + --highlight line + line:SetBackdropColor (unpack (comparisonFrameSettings.lineOnEnterColor)) + latestLinesHighlighted [#latestLinesHighlighted + 1] = line + + return true, castAmount, rawSpellTable.counter, average, rawSpellTable.c_amt, uptime + end + + local getPercentComparison = function (value1, value2) + if (value1 == 0 and value2 == 0) then + return "|c" .. minor .. "0%|r" + + elseif (value1 >= value2) then + local diff = value1 - value2 + local up + + if (diff == 0 or value2 == 0) then --stop div by zero ptr + up = "0" + else + up = diff / value2 * 100 + up = floor (up) + + if (up > 999) then + up = "" .. 999 + end + end + + return "|c" .. minor .. up .. "%|r" + else + local diff = value2 - value1 + local down + + if (diff == 0 or value1 == 0) then --stop div by zero ptr + down = "0" + else + down = diff / value1 * 100 + down = floor (down) + if (down > 999) then + down = "" .. 999 + end + end + + return "|c" .. plus .. down .. "%|r" + end + end + + --fill the tooltip for comparison lines + --actualPlayerName is the name of the player being compared, playerName can be the name of a pet + local fillComparisonSpellTooltip = function (line, rawSpellTable, actualPlayerName, playerName, mainCastAmount, mainHitCounter, mainAverageDamage, mainCritAmount, mainAuraUptime) + local tooltip = getComparisonTooltip() + local formatFunc = Details:GetCurrentToKFunction() + local spellId = rawSpellTable.id + local noData = "-" + + tooltip.player_name_label:SetText (Details:GetOnlyName (actualPlayerName)) + + --amount of casts + local castAmount = 0 + local combatObject = Details:GetCombatFromBreakdownWindow() + local playerMiscObject = combatObject:GetActor (DETAILS_ATTRIBUTE_MISC, playerName) + + if (playerMiscObject) then + castAmount = playerMiscObject.spell_cast and playerMiscObject.spell_cast [spellId] or 0 + tooltip.casts_label2:SetText (getPercentComparison (mainCastAmount, castAmount)) + tooltip.casts_label3:SetText (castAmount) + DetailsFramework:SetFontColor (tooltip.casts_label2, "white") + DetailsFramework:SetFontColor (tooltip.casts_label3, "white") + else + tooltip.casts_label2:SetText (noData) + tooltip.casts_label3:SetText (noData) + DetailsFramework:SetFontColor (tooltip.casts_label2, "silver") + DetailsFramework:SetFontColor (tooltip.casts_label3, "silver") + end + + --hits + tooltip.hits_label2:SetText (getPercentComparison (mainHitCounter, rawSpellTable.counter)) + tooltip.hits_label3:SetText (rawSpellTable.counter) + DetailsFramework:SetFontColor (tooltip.hits_label2, "white") + DetailsFramework:SetFontColor (tooltip.hits_label3, "white") + + --average + local average = rawSpellTable.total / rawSpellTable.counter + tooltip.average_label2:SetText (getPercentComparison (mainAverageDamage, average)) + tooltip.average_label3:SetText (formatFunc (_, average)) + DetailsFramework:SetFontColor (tooltip.average_label3, "white") + DetailsFramework:SetFontColor (tooltip.average_label2, "white") + + --critical strikes + tooltip.crit_label2:SetText (getPercentComparison (mainCritAmount, rawSpellTable.c_amt)) + tooltip.crit_label3:SetText (rawSpellTable.c_amt) + DetailsFramework:SetFontColor (tooltip.crit_label2, "white") + DetailsFramework:SetFontColor (tooltip.crit_label2, "white") + + --uptime + local uptime = 0 + if (playerMiscObject) then + local spell = playerMiscObject.debuff_uptime_spells and playerMiscObject.debuff_uptime_spells._ActorTable and playerMiscObject.debuff_uptime_spells._ActorTable [spellId] + if (spell) then + local minutos, segundos = floor (spell.uptime / 60), floor (spell.uptime % 60) + uptime = spell.uptime + tooltip.uptime_label2:SetText (getPercentComparison (mainAuraUptime, uptime)) + tooltip.uptime_label3:SetText (minutos .. "m " .. segundos .. "s") + + DetailsFramework:SetFontColor (tooltip.uptime_label2, "white") + DetailsFramework:SetFontColor (tooltip.uptime_label3, "white") + else + tooltip.uptime_label2:SetText (noData) + tooltip.uptime_label3:SetText (noData) + DetailsFramework:SetFontColor (tooltip.uptime_label2, "gray") + DetailsFramework:SetFontColor (tooltip.uptime_label3, "gray") + end + else + tooltip.uptime_label2:SetText (noData) + tooltip.uptime_label3:SetText (noData) + DetailsFramework:SetFontColor (tooltip.uptime_label2, "gray") + DetailsFramework:SetFontColor (tooltip.uptime_label3, "gray") + end + + --show tooltip + tooltip:SetPoint ("bottom", line, "top", 0, 2) + tooltip:SetWidth (line:GetWidth()) + tooltip:Show() + + --highlight line + line:SetBackdropColor (unpack (comparisonFrameSettings.lineOnEnterColor)) + latestLinesHighlighted [#latestLinesHighlighted + 1] = line + end + + local comparisonLineOnEnter = function (self) + local scrollFrame = self:GetParent() + local frame = scrollFrame:GetParent() + + if (not frame.GetPlayerInfo) then + frame = frame:GetParent() + end + + --check if this is a spell or a target line + if (self.lineType == "mainPlayerSpell" or self.lineType == "comparisonPlayerSpell") then + + --get data + local spellTable = self.spellTable + local isPet = spellTable.npcId + local npcId = spellTable.npcId + local spellId = spellTable.spellId + + local mainPlayerObject = frame.GetMainPlayerObject() + local mainSpellTable = frame.GetMainSpellTable() + local allComparisonFrames = frame.GetAllComparisonFrames() + + local mainFrameScroll = frame.mainFrameScroll + local playerObject, playerName = frame.GetPlayerInfo (scrollFrame) + + --store the spell information from the main tooltip + local mainHasTooltip, castAmount, hitCounter, averageDamage, critAmount, auraUptime + + --iterate on the main player scroll and find the line + local mainFrameLines = mainFrameScroll:GetFrames() + for i = 1, #mainFrameLines do + local line = mainFrameLines [i] + if (line.spellTable and line:IsShown()) then + if (isPet) then + if (line.spellTable.spellId == spellId and line.spellTable.npcId == npcId) then + --main line for the hover over spell + local rawSpellTable = line.spellTable.rawSpellTable + mainHasTooltip, castAmount, hitCounter, averageDamage, critAmount, auraUptime = fillMainSpellTooltip (line, rawSpellTable, mainPlayerObject:Name(), line.spellTable.originalName) + break + end + else + if (line.spellTable.spellId == spellId and not line.spellTable.npcId) then + --main line for the hover over spell + local rawSpellTable = line.spellTable.rawSpellTable + mainHasTooltip, castAmount, hitCounter, averageDamage, critAmount, auraUptime = fillMainSpellTooltip (line, rawSpellTable, mainPlayerObject:Name(), mainPlayerObject:Name()) + break + end + end + end + end + + if (mainHasTooltip) then + --iterate among all other comparison scrolls + for i = 1, #allComparisonFrames do + local comparisonFrame = allComparisonFrames [i] + if (comparisonFrame:IsShown()) then + local scrollFrame = comparisonFrame.spellsScroll + local playerObject, playerName = frame.GetPlayerInfo (comparisonFrame) + + local frameLines = scrollFrame:GetFrames() + for i = 1, #frameLines do + local line = frameLines [i] + if (line.spellTable and line:IsShown() and line.spellTable.rawSpellTable) then + if (isPet) then + if (line.spellTable.spellId == spellId and line.spellTable.npcId == npcId) then + --line for the hover over spell in a comparison scroll frame + local rawSpellTable = line.spellTable.rawSpellTable + fillComparisonSpellTooltip (line, rawSpellTable, playerName, line.spellTable.originalName, castAmount, hitCounter, averageDamage, critAmount, auraUptime) + end + else + if (line.spellTable.spellId == spellId and not line.spellTable.npcId) then + --line for the hover over spell in a comparison scroll frame + local rawSpellTable = line.spellTable.rawSpellTable + fillComparisonSpellTooltip (line, rawSpellTable, playerName, playerName, castAmount, hitCounter, averageDamage, critAmount, auraUptime) + end + end + end + end + end + end + end + + + + + elseif (self.lineType == "mainPlayerTarget" or self.lineType == "comparisonPlayerTarget") then + + local targetName = self.targetTable.originalName + local attribute = Details:GetDisplayTypeFromBreakdownWindow() + + --build a list of spells used by the main actor + local mainPlayerObject = frame.GetMainPlayerObject() + local damageDoneBySpell = {} + + --find the main line + --iterate on the main player scroll and find the line + local mainLine + local mainFrameScroll = frame.targetFrameScroll + local mainFrameLines = mainFrameScroll:GetFrames() + + for i = 1, #mainFrameLines do + local line = mainFrameLines [i] + if (line.targetTable and line:IsShown()) then + if (line.targetTable.originalName == targetName) then + mainLine = line + break + end + end + end + + if (not mainLine) then + return + end + + --spells + for spellId, spellTable in pairs (mainPlayerObject:GetActorSpells()) do + local damageOnTarget = spellTable.targets [targetName] + if (damageOnTarget and damageOnTarget > 0) then + damageDoneBySpell [#damageDoneBySpell + 1] = {spellTable, damageOnTarget, mainPlayerObject:Name(), mainPlayerObject, false} + end + end + + --pets + for _, petName in ipairs (mainPlayerObject:Pets()) do + local petObject = Details:GetCombatFromBreakdownWindow():GetActor (attribute, petName) + if (petObject) then + for spellId, spellTable in pairs (petObject:GetActorSpells()) do + local damageOnTarget = spellTable.targets [targetName] + if (damageOnTarget and damageOnTarget > 0) then + damageDoneBySpell [#damageDoneBySpell + 1] = {spellTable, damageOnTarget, petName, petObject, DetailsFramework:GetNpcIdFromGuid (petObject.serial)} + end + end + end + end + + table.sort (damageDoneBySpell, DetailsFramework.SortOrder2) + + local tooltip = getTargetComparisonTooltip() + local formatFunc = Details:GetCurrentToKFunction() + local mainHasTooltip = false + tooltip.player_name_label:SetText (mainPlayerObject:GetDisplayName()) + + for i = 1, #damageDoneBySpell do + local damageTable = damageDoneBySpell [i] + local spellTable = damageTable [1] + local damageDone = damageTable [2] + local actorName = damageTable [3] + local actorObject = damageTable [4] + local npcId = damageTable [5] + + local spellName, _, spellIcon = Details.GetSpellInfo (spellTable.id) + + local line = tooltip.lines [i] + if (not line) then + break + end + + if (npcId) then + spellName = spellName .. " (" .. comparisonFrameSettings.petColor .. actorName:gsub (" <.*", "") .. "|r)" + end + + line.spellName:SetText (spellName) + DetailsFramework:TruncateText (line.spellName, mainFrameScroll:GetWidth() - 110) + + line.spellIcon:SetTexture (spellIcon) + line.spellIcon:SetTexCoord (.1, .9, .1, .9) + line.spellAmount:SetText ("100%") + DetailsFramework:SetFontColor (line.spellAmount, "gray") + line.spellPercent:SetText (formatFunc (_, damageDone)) + + line:Show() + mainHasTooltip = true + end + + --comparison + if (mainHasTooltip) then + local allComparisonFrames = frame.GetAllComparisonFrames() + local combatObject = Details:GetCombatFromBreakdownWindow() + + --iterate among all other comparison scrolls + for i = 1, #allComparisonFrames do + local comparisonFrame = allComparisonFrames [i] + if (comparisonFrame:IsShown()) then + local scrollFrame = comparisonFrame.targetsScroll + local playerObject, playerName = frame.GetPlayerInfo (comparisonFrame) + + local targetLines = scrollFrame:GetFrames() + for o = 1, #targetLines do + local line = targetLines [o] + if (line and line.targetTable and line:IsShown()) then + if (line.targetTable.originalName == targetName) then + + --get a tooltip for this actor + local actorTooltip = getTargetComparisonTooltip() + + actorTooltip:SetPoint ("bottom", line, "top", 0, 2) + actorTooltip:SetWidth (line:GetWidth()) + actorTooltip:SetHeight (min (comparisonFrameSettings.targetMaxLines, #damageDoneBySpell) * comparisonFrameSettings.targetTooltipLineHeight + comparisonFrameSettings.targetMaxLines) + actorTooltip:Show() + + actorTooltip.player_name_label:SetText (playerObject:GetDisplayName()) + + --highlight line + line:SetBackdropColor (unpack (comparisonFrameSettings.lineOnEnterColor)) + latestLinesHighlighted [#latestLinesHighlighted + 1] = line + + --iterate among all spells in the first tooltip and fill here + --if is a pet line, need to get the data from the player pet instead + + + for a = 1, #damageDoneBySpell do + local damageTable = damageDoneBySpell [a] + local spellTable = damageTable [1] + local damageDone = damageTable [2] + local actorName = damageTable [3] + local actorObject = damageTable [4] + local npcId = damageTable [5] + + local foundSpell + + -- i is also the tooltip line index + + if (not npcId) then + local spellObject = playerObject:GetSpell (spellTable.id) + if (spellObject) then + local damageOnTarget = spellObject.targets [targetName] or 0 + if (damageOnTarget > 0) then + --this actor did damage on this target, add into the tooltip + local tooltipLine = actorTooltip.lines [a] + if (not tooltipLine) then + break + end + + local spellName, _, spellIcon = Details.GetSpellInfo (spellTable.id) + + tooltipLine.spellName:SetText ("") + tooltipLine.spellIcon:SetTexture (spellIcon) + tooltipLine.spellIcon:SetTexCoord (.1, .9, .1, .9) + + -- calculate percent + local mainSpellDamageOnTarget = 0 + -- find this spell in the main actor table + for u = 1, #damageDoneBySpell do + local mainSpell = damageDoneBySpell [u] + + local spellTableMain = damageTable [1] + local damageDoneMain = damageTable [2] + local actorNameMain = damageTable [3] + local actorObjectMain = damageTable [4] + local npcIdMain = damageTable [5] + + if (not npcIdMain and spellTableMain.id == spellObject.id) then + --found the spell in the main table + mainSpellDamageOnTarget = damageDoneMain + break + end + end + + tooltipLine.spellAmount:SetText (getPercentComparison (mainSpellDamageOnTarget, damageOnTarget)) + tooltipLine.spellPercent:SetText (formatFunc (_, damageOnTarget)) + + tooltipLine:Show() + foundSpell = true + end + end + else + --iterate among all pets the player has and find one with the same npcId + for _, petName in ipairs (playerObject:Pets()) do + local petObject = combatObject:GetActor (attribute, petName) + if (petObject) then + local petNpcId = DetailsFramework:GetNpcIdFromGuid (petObject.serial) + if (petNpcId and petNpcId == npcId) then + --found the correct pet + local spellObject = petObject:GetSpell (spellTable.id) + if (spellObject) then + local damageOnTarget = spellObject.targets [targetName] or 0 + if (damageOnTarget > 0) then + --this pet did damage on this target, add into the tooltip + + local tooltipLine = actorTooltip.lines [a] + if (not tooltipLine) then + break + end + + -- calculate percent + local mainSpellDamageOnTarget = 0 + -- find this spell in the main actor table + for u = 1, #damageDoneBySpell do + local mainSpell = damageDoneBySpell [u] + + local spellTableMain = damageTable [1] + local damageDoneMain = damageTable [2] + local actorNameMain = damageTable [3] + local actorObjectMain = damageTable [4] + local npcIdMain = damageTable [5] + + if (npcIdMain and npcIdMain == petNpcId and spellTableMain.id == spellObject.id) then + --found the spell in the main table + mainSpellDamageOnTarget = damageDoneMain + break + end + end + + local spellName, _, spellIcon = Details.GetSpellInfo (spellTable.id) + + tooltipLine.spellName:SetText ("") + tooltipLine.spellIcon:SetTexture (spellIcon) + tooltipLine.spellIcon:SetTexCoord (.1, .9, .1, .9) + tooltipLine.spellAmount:SetText (getPercentComparison (mainSpellDamageOnTarget, damageOnTarget)) + tooltipLine.spellPercent:SetText (formatFunc (_, damageOnTarget)) + + tooltipLine:Show() + foundSpell = true + end + end + end + end + end + + end + + if (not foundSpell) then + --add an empty line in the tooltip + local tooltipLine = actorTooltip.lines [a] + if (tooltipLine) then + tooltipLine:Show() + end + end + end + + --break the loop to find the correct line + break + end + end + end + end + end + end + + --highlight line + mainLine:SetBackdropColor (unpack (comparisonFrameSettings.lineOnEnterColor)) + latestLinesHighlighted [#latestLinesHighlighted + 1] = mainLine + + tooltip:SetPoint ("bottom", mainLine, "top", 0, 2) + tooltip:SetWidth (mainLine:GetWidth()) + tooltip:SetHeight (min (comparisonFrameSettings.targetMaxLines, #damageDoneBySpell) * comparisonFrameSettings.targetTooltipLineHeight + comparisonFrameSettings.targetMaxLines) + tooltip:Show() + end + end + + local comparisonLineOnLeave = function (self) + for i = #latestLinesHighlighted, 1, -1 do + local line = latestLinesHighlighted [i] + line:SetBackdropColor (unpack (line.BackgroundColor)) + tremove (latestLinesHighlighted, i) + end + + resetComparisonTooltip() + resetTargetComparisonTooltip() + end + + local playerComparisonCreate = function (tab, frame) + + frame.isComparisonTab = true + + --regular functions for comparison API + function frame.GetMainPlayerName() + return frame.mainPlayerObject:Name() + end + function frame.GetMainPlayerObject() + return frame.mainPlayerObject + end + + function frame.GetMainSpellTable() + return frame.mainSpellTable + end + function frame.GetMainTargetTable() + return frame.mainTargetTable + end + + function frame.GetAllComparisonFrames() + return frame.comparisonFrames + end + + function frame.GetPlayerInfo (f) + if (f.mainPlayerObject) then + return f.mainPlayerObject, f.mainPlayerObject:Name() + else + return f.playerObject, f.playerObject:Name() + end + end + + --main player spells (scroll box with the spells the player used) + local mainPlayerCreateline = function (self, index) + local lineHeight = self.lineHeight + local lineWidth = self.scrollWidth + local fontSize = self.fontSize + + local line = CreateFrame ("button", "$parentLine" .. index, self, "BackdropTemplate") + line:SetPoint ("topleft", self, "topleft", 1, -((index-1) * (lineHeight+1))) + line:SetSize (lineWidth -2, lineHeight) + + line:SetScript ("OnEnter", comparisonLineOnEnter) + line:SetScript ("OnLeave", comparisonLineOnLeave) + + line:SetBackdrop ({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true}) + line:SetBackdropColor (0, 0, 0, 0.2) + + local spellIcon = line:CreateTexture ("$parentIcon", "overlay") + spellIcon:SetSize (lineHeight -2 , lineHeight - 2) + + local spellName = line:CreateFontString ("$parentName", "overlay", "GameFontNormal") + local spellAmount = line:CreateFontString ("$parentAmount", "overlay", "GameFontNormal") + local spellPercent = line:CreateFontString ("$parentPercent", "overlay", "GameFontNormal") + DetailsFramework:SetFontSize (spellName, fontSize) + DetailsFramework:SetFontSize (spellAmount, fontSize) + DetailsFramework:SetFontSize (spellPercent, fontSize) + + spellIcon:SetPoint ("left", line, "left", 2, 0) + spellName:SetPoint ("left", spellIcon, "right", 2, 0) + spellAmount:SetPoint ("right", line, "right", -2, 0) + spellPercent:SetPoint ("right", line, "right", -40, 0) + + spellName:SetJustifyH ("left") + spellAmount:SetJustifyH ("right") + spellPercent:SetJustifyH ("right") + + line.spellIcon = spellIcon + line.spellName = spellName + line.spellAmount = spellAmount + line.spellPercent = spellPercent + + return line + end + + --the refresh function receives an already prepared table and just update the lines + local mainPlayerRefreshSpellScroll = function (self, data, offset, totalLines) + for i = 1, totalLines do + local index = i + offset + local spellTable = data [index] + + if (spellTable) then + local line = self:GetLine (i) + + --store the line into the spell table + spellTable.line = line + line.spellTable = spellTable + + local spellId = spellTable.spellId + local spellName = spellTable.spellName + local spellIcon = spellTable.spellIcon + local amountDone = spellTable.amount + + line.spellId = spellId + + line.spellIcon:SetTexture (spellIcon) + line.spellIcon:SetTexCoord (.1, .9, .1, .9) + + line.spellName:SetText (spellName) + DetailsFramework:TruncateText (line.spellName, line:GetWidth() - 70) + + local formatFunc = Details:GetCurrentToKFunction() + line.spellAmount:SetText (formatFunc (_, amountDone)) + + if (i % 2 == 0) then + line:SetBackdropColor (unpack (comparisonLineContrast [1])) + line.BackgroundColor = comparisonLineContrast [1] + else + line:SetBackdropColor (unpack (comparisonLineContrast [2])) + line.BackgroundColor = comparisonLineContrast [2] + end + end + end + end + + local mainPlayerRefreshTargetScroll = function (self, data, offset, totalLines) + for i = 1, totalLines do + local index = i + offset + local targetTable = data [index] + + if (targetTable) then + local line = self:GetLine (i) + + --store the line into the target table + targetTable.line = line + line.targetTable = targetTable + + local targetName = targetTable.targetName + local amountDone = targetTable.amount + + line.targetName = targetName + + line.spellIcon:SetTexture ("") --todo - fill this texture + line.spellIcon:SetTexCoord (.1, .9, .1, .9) + + line.spellName:SetText (targetName) + DetailsFramework:TruncateText (line.spellName, line:GetWidth() - 50) + + local formatFunc = Details:GetCurrentToKFunction() + line.spellAmount:SetText (formatFunc (_, amountDone)) + + if (i % 2 == 0) then + line:SetBackdropColor (unpack (comparisonLineContrast [1])) + line.BackgroundColor = comparisonLineContrast [1] + else + line:SetBackdropColor (unpack (comparisonLineContrast [2])) + line.BackgroundColor = comparisonLineContrast [2] + end + end + end + end + + --main player spells scroll + local mainPlayerFrameScroll = DetailsFramework:CreateScrollBox (frame, "$parentComparisonMainPlayerSpellsScroll", mainPlayerRefreshSpellScroll, {}, comparisonFrameSettings.mainScrollWidth, comparisonFrameSettings.spellScrollHeight, comparisonFrameSettings.spellLineAmount, comparisonFrameSettings.spellLineHeight) + mainPlayerFrameScroll:SetPoint ("topleft", frame, "topleft", 5, -30) + mainPlayerFrameScroll.lineHeight = comparisonFrameSettings.spellLineHeight + mainPlayerFrameScroll.scrollWidth = comparisonFrameSettings.mainScrollWidth + mainPlayerFrameScroll.fontSize = comparisonFrameSettings.fontSize + + mainPlayerFrameScroll:HookScript ("OnVerticalScroll", function (self, offset) + frame.RefreshAllComparisonScrollFrames() + end) + + --create lines + for i = 1, comparisonFrameSettings.spellLineAmount do + local line = mainPlayerFrameScroll:CreateLine (mainPlayerCreateline) + line.lineType = "mainPlayerSpell" + end + DetailsFramework:ReskinSlider (mainPlayerFrameScroll) + + frame.mainFrameScroll = mainPlayerFrameScroll + + --main player targets (scroll box with enemies the player applied damage) + local mainTargetFrameScroll = DetailsFramework:CreateScrollBox (frame, "$parentComparisonMainPlayerTargetsScroll", mainPlayerRefreshTargetScroll, {}, comparisonFrameSettings.mainScrollWidth, comparisonFrameSettings.targetScrollHeight, comparisonFrameSettings.targetScrollLineAmount, comparisonFrameSettings.targetScrollLineHeight) + mainTargetFrameScroll:SetPoint ("topleft", mainPlayerFrameScroll, "bottomleft", 0, -20) + mainTargetFrameScroll.lineHeight = comparisonFrameSettings.targetScrollLineHeight + mainTargetFrameScroll.scrollWidth = comparisonFrameSettings.mainScrollWidth + mainTargetFrameScroll.fontSize = comparisonFrameSettings.fontSize + + --create lines + for i = 1, comparisonFrameSettings.targetScrollLineAmount do + local line = mainTargetFrameScroll:CreateLine (mainPlayerCreateline) + line.lineType = "mainPlayerTarget" + end + DetailsFramework:ReskinSlider (mainTargetFrameScroll) + + frame.targetFrameScroll = mainTargetFrameScroll + + --main player name + frame.mainPlayerName = DetailsFramework:CreateLabel (mainPlayerFrameScroll) + frame.mainPlayerName:SetPoint ("topleft", mainPlayerFrameScroll, "topleft", 2, comparisonFrameSettings.playerNameYOffset) + frame.mainPlayerName.fontsize = comparisonFrameSettings.playerNameSize + + --create the framework for the comparing players + local settings = { + --comparison frame + height = 600, + } + + frame.comparisonFrames = {} + frame.comparisonScrollFrameIndex = 0 + + function frame.ResetComparisonFrames() + frame.comparisonScrollFrameIndex = 0 + for _, comparisonFrame in ipairs (frame.comparisonFrames) do + comparisonFrame:Hide() + comparisonFrame.playerObject = nil + comparisonFrame.spellsScroll.playerObject = nil + end + end + + local comparisonPlayerRefreshTargetScroll = function (self, data, offset, totalLines) + offset = FauxScrollFrame_GetOffset (mainPlayerFrameScroll) + + for i = 1, totalLines do + local index = i + offset + local targetTable = data [index] + + if (targetTable) then + local line = self:GetLine (i) + line:SetWidth (comparisonFrameSettings.comparisonScrollWidth - 2) + + --store the line into the target table + targetTable.line = line + line.targetTable = targetTable + + line.spellIcon:SetTexture ("") + + local mainPlayerAmount = targetTable.mainTargetAmount + local amountDone = targetTable.amount + + if (mainPlayerAmount) then + local formatFunc = Details:GetCurrentToKFunction() + + if (mainPlayerAmount > amountDone) then + local diff = mainPlayerAmount - amountDone + local up = diff / amountDone * 100 + up = floor (up) + if (up > 999) then + up = "" .. 999 + end + + line.spellPercent:SetText ("|c" .. minor .. up .. "%|r") + else + local diff = amountDone - mainPlayerAmount + local down = diff / mainPlayerAmount * 100 + down = floor (down) + if (down > 999) then + down = "" .. 999 + end + + line.spellPercent:SetText ("|c" .. plus .. down .. "%|r") + end + + line.spellAmount:SetText (formatFunc (_, amountDone)) + else + line.spellPercent:SetText ("") + line.spellAmount:SetText ("") + end + + if (i % 2 == 0) then + line:SetBackdropColor (unpack (comparisonLineContrast [1])) + line.BackgroundColor = comparisonLineContrast [1] + else + line:SetBackdropColor (unpack (comparisonLineContrast [2])) + line.BackgroundColor = comparisonLineContrast [2] + end + end + end + end + + --refresh a spell scroll on a comparison frame + local comparisonPlayerRefreshSpellScroll = function (self, data, offset, totalLines) + + offset = FauxScrollFrame_GetOffset (mainPlayerFrameScroll) + + for i = 1, totalLines do + local index = i + offset + local spellTable = data[index] + + if (spellTable) then + local line = self:GetLine(i) + line:SetWidth(comparisonFrameSettings.comparisonScrollWidth - 2) + + --store the line into the spell table + spellTable.line = line + line.spellTable = spellTable + + local spellId = spellTable.spellId + local spellName = spellTable.spellName + local spellIcon = spellTable.spellIcon + local amountDone = spellTable.amount + + line.spellId = spellId + + line.spellIcon:SetTexture(spellIcon) + line.spellIcon:SetTexCoord(.1, .9, .1, .9) + + line.spellName:SetText("") --won't show the spell name, only the icon + + local percent = 1 + + local mainFrame = self:GetParent().mainPlayer + local mainSpellTable = self:GetParent().mainSpellTable + local mainPlayerAmount = spellTable.mainSpellAmount + + if (mainPlayerAmount) then + local formatFunc = Details:GetCurrentToKFunction() + + if (mainPlayerAmount > amountDone) then + local diff = mainPlayerAmount - amountDone + local up + + if (diff == 0 or mainPlayerAmount == 0) then --stop div by zero ptr + up = "0" + else + up = diff / amountDone * 100 + up = floor (up) + if (up > 999) then + up = "" .. 999 + end + end + + line.spellPercent:SetText ("|c" .. minor .. up .. "%|r") + else + local down + local diff = amountDone - mainPlayerAmount + if (diff == 0 or mainPlayerAmount == 0) then --stop div by zero ptr + down = "0" + else + down = diff / mainPlayerAmount * 100 + down = floor(down) + if (down > 999) then + down = "" .. 999 + end + end + + line.spellPercent:SetText("|c" .. plus .. down .. "%|r") + end + + line.spellAmount:SetText(formatFunc(_, amountDone)) + else + line.spellPercent:SetText("") + line.spellAmount:SetText("") + end + + if (i % 2 == 0) then + line:SetBackdropColor (unpack (comparisonLineContrast [1])) + line.BackgroundColor = comparisonLineContrast [1] + else + line:SetBackdropColor (unpack (comparisonLineContrast [2])) + line.BackgroundColor = comparisonLineContrast [2] + end + end + end + end + + function frame.RefreshAllComparisonScrollFrames() + for _, comparisonFrame in ipairs (frame.comparisonFrames) do + comparisonFrame.spellsScroll:Refresh() + end + end + + --get a frame which has two scrolls, one for spells and another for targets + function frame.GetComparisonScrollFrame() + frame.comparisonScrollFrameIndex = frame.comparisonScrollFrameIndex + 1 + + local comparisonFrame = frame.comparisonFrames [frame.comparisonScrollFrameIndex] + if (comparisonFrame) then + comparisonFrame:Show() + return comparisonFrame + end + + local newComparisonFrame = CreateFrame ("frame", "DetailsComparisonFrame" .. frame.comparisonScrollFrameIndex, frame, "BackdropTemplate") + frame.comparisonFrames [frame.comparisonScrollFrameIndex] = newComparisonFrame + newComparisonFrame:SetSize (comparisonFrameSettings.comparisonScrollWidth, settings.height) + + if (frame.comparisonScrollFrameIndex == 1) then + newComparisonFrame:SetPoint ("topleft", mainPlayerFrameScroll, "topright", 30, 0) + else + newComparisonFrame:SetPoint ("topleft", frame.comparisonFrames [frame.comparisonScrollFrameIndex - 1], "topright", 10, 0) + end + + --create the spell comparison scroll + --player name + newComparisonFrame.playerName = DetailsFramework:CreateLabel (newComparisonFrame) + newComparisonFrame.playerName:SetPoint ("topleft", newComparisonFrame, "topleft", 2, comparisonFrameSettings.playerNameYOffset) + newComparisonFrame.playerName.fontsize = comparisonFrameSettings.playerNameSize + + --spells scroll + local spellsScroll = DetailsFramework:CreateScrollBox (newComparisonFrame, "$parentComparisonPlayerSpellsScroll", comparisonPlayerRefreshSpellScroll, {}, comparisonFrameSettings.comparisonScrollWidth, comparisonFrameSettings.spellScrollHeight, comparisonFrameSettings.spellLineAmount, comparisonFrameSettings.spellLineHeight) + spellsScroll:SetPoint ("topleft", newComparisonFrame, "topleft", 0, 0) + spellsScroll.lineHeight = comparisonFrameSettings.spellLineHeight + spellsScroll.scrollWidth = comparisonFrameSettings.mainScrollWidth + spellsScroll.fontSize = comparisonFrameSettings.fontSize + _G [spellsScroll:GetName() .. "ScrollBar"]:Hide() + + --create lines + for i = 1, comparisonFrameSettings.spellLineAmount do + local line = spellsScroll:CreateLine (mainPlayerCreateline) + line.lineType = "comparisonPlayerSpell" + end + DetailsFramework:ReskinSlider (spellsScroll) + + newComparisonFrame.spellsScroll = spellsScroll + + --targets scroll + local targetsScroll = DetailsFramework:CreateScrollBox (newComparisonFrame, "$parentComparisonPlayerTargetsScroll", comparisonPlayerRefreshTargetScroll, {}, comparisonFrameSettings.comparisonScrollWidth, comparisonFrameSettings.targetScrollHeight, comparisonFrameSettings.targetScrollLineAmount, comparisonFrameSettings.targetScrollLineHeight) + targetsScroll:SetPoint ("topleft", newComparisonFrame, "topleft", 0, -comparisonFrameSettings.spellScrollHeight - 20) + targetsScroll.lineHeight = comparisonFrameSettings.spellLineHeight + targetsScroll.scrollWidth = comparisonFrameSettings.mainScrollWidth + targetsScroll.fontSize = comparisonFrameSettings.fontSize + _G [targetsScroll:GetName() .. "ScrollBar"]:Hide() + + --create lines + for i = 1, comparisonFrameSettings.targetScrollLineAmount do + local line = targetsScroll:CreateLine (mainPlayerCreateline) + line.lineType = "comparisonPlayerTarget" + end + DetailsFramework:ReskinSlider (targetsScroll) + + newComparisonFrame.targetsScroll = targetsScroll + + return newComparisonFrame + end + + end + + local buildSpellAndTargetTables = function (player, combat, attribute) + --build the spell list for the main player including pets + local allPlayerSpells = player:GetActorSpells() + local resultSpellTable = {} + + for spellId, spellTable in pairs(allPlayerSpells) do + local spellName, _, spellIcon = Details.GetSpellInfo (spellId) + resultSpellTable [#resultSpellTable + 1] = {spellId, spellTable.total, spellName = spellName, spellIcon = spellIcon, spellId = spellId, amount = spellTable.total, rawSpellTable = spellTable} + end + + --pets + local petAbilities = {} + for _, petName in ipairs(player:Pets()) do + local petObject = combat:GetActor(attribute, petName) + if (petObject) then + local allPetSpells = petObject:GetActorSpells() + local petNpcId = DetailsFramework:GetNpcIdFromGuid(petObject.serial) + for spellId, spellTable in pairs(allPetSpells) do + petAbilities[spellId] = petAbilities[spellId] or {total = 0, rawSpellTable = spellTable} + petAbilities[spellId].total = petAbilities[spellId].total + spellTable.total + end + end + end + + for spellId, petSpellTable in pairs(petAbilities) do + local spellName, _, spellIcon = Details.GetSpellInfo(spellId) + resultSpellTable [#resultSpellTable + 1] = {spellId, petSpellTable.total, spellName = spellName, spellIcon = spellIcon, spellId = spellId, amount = petSpellTable.total, rawSpellTable = petSpellTable.rawSpellTable} + end + + table.sort (resultSpellTable, DetailsFramework.SortOrder2) + + --build the target list for the main player + local resultTargetTable = {} + for targetName, amountDone in pairs (player.targets) do + resultTargetTable [#resultTargetTable + 1] = {targetName, amountDone, targetName = Details:RemoveOwnerName (targetName), amount = amountDone, originalName = targetName, rawPlayerObject = player} + end + + table.sort (resultTargetTable, DetailsFramework.SortOrder2) + + return resultSpellTable, resultTargetTable + end + + --main tab function to be executed when the tab is shown + local playerComparisonFill = function (tab, player, combat) + local frame = tab.frame + + --update player name + frame.mainPlayerName.text = player:GetDisplayName() + + frame.mainPlayerObject = player + frame.mainFrameScroll.mainPlayerObject = player + + --reset the comparison scroll frame + frame.ResetComparisonFrames() + resetComparisonTooltip() + resetTargetComparisonTooltip() + + local attribute = Details:GetDisplayTypeFromBreakdownWindow() + local resultSpellTable, resultTargetTable = buildSpellAndTargetTables (player, combat, attribute) + + --update the two main scroll frames + frame.mainFrameScroll:SetData (resultSpellTable) + frame.mainFrameScroll:Refresh() + + frame.targetFrameScroll:SetData (resultTargetTable) + frame.targetFrameScroll:Refresh() + + frame.mainSpellTable = resultSpellTable + frame.mainTargetTable = resultTargetTable + + --search the combat for players with the same spec and build a scroll frame for them + --to keep consistency, sort these players with the max amount of damage or healing they have done + local actorContainer = combat:GetContainer (attribute) + local playersWithSameSpec = {} + + for _, playerObject in actorContainer:ListActors() do + if (playerObject:IsPlayer() and playerObject.spec == player.spec and playerObject.serial ~= player.serial) then + playersWithSameSpec [#playersWithSameSpec + 1] = {playerObject, playerObject.total} + end + end + + table.sort (playersWithSameSpec, DetailsFramework.SortOrder2) + + frame.comparisonSpellTable = {} + frame.comparisonTargetTable = {} + + for i = 1, #playersWithSameSpec do + --other player with the same spec + local playerObject = playersWithSameSpec[i][1] + local otherPlayerSpellTable, otherPlayerTargetTable = buildSpellAndTargetTables (playerObject, combat, attribute) + + frame.comparisonSpellTable [#frame.comparisonSpellTable + 1] = otherPlayerSpellTable + frame.comparisonTargetTable [#frame.comparisonTargetTable + 1] = otherPlayerTargetTable + + local comparisonFrame = frame.GetComparisonScrollFrame() + comparisonFrame.mainPlayer = player + comparisonFrame.mainSpellTable = resultSpellTable + comparisonFrame.mainTargetTable = resultTargetTable + + comparisonFrame.playerObject = playerObject + comparisonFrame.playerName.text = playerObject:GetDisplayName() + + --iterate among spells of the main player and check if the spell exists on this player + local otherPlayerResultSpellTable = {} + + for i = 1, #resultSpellTable do + local spellTable = resultSpellTable [i] + + local found = false + + --iterate amont spell of the other player which the main player is being compared + for o = 1, #otherPlayerSpellTable do + local otherSpellTable = otherPlayerSpellTable[o] + + --check if this is a pet + if (spellTable.npcId) then + --match the npcId before match the spellId + if (otherSpellTable.npcId == spellTable.npcId) then + if (otherSpellTable.spellId == spellTable.spellId) then + found = true + --insert the amount of the main spell in the table + otherSpellTable.mainSpellAmount = spellTable.amount + otherPlayerResultSpellTable [#otherPlayerResultSpellTable+1] = otherSpellTable + break + end + end + else + if (otherSpellTable.spellId == spellTable.spellId) then + found = true + --insert the amount of the main spell in the table + otherSpellTable.mainSpellAmount = spellTable.amount + otherPlayerResultSpellTable [#otherPlayerResultSpellTable+1] = otherSpellTable + break + end + end + end + + if (not found) then + otherPlayerResultSpellTable [#otherPlayerResultSpellTable+1] = {0, 0, spellName = "", spellIcon = "", spellId = 0, amount = 0} + end + end + + --call the update function + comparisonFrame.spellsScroll.playerObject = playerObject + comparisonFrame.spellsScroll:SetData (otherPlayerResultSpellTable) + comparisonFrame.spellsScroll:Refresh() + + --iterate among targets of the main player and check if the target exists on this player + local otherPlayerResultTargetsTable = {} + + for i = 1, #resultTargetTable do + local targetTable = resultTargetTable [i] + + local found = false + + --iterate amont targets of the other player which the main player is being compared + for o = 1, #otherPlayerTargetTable do + local otherTargetTable = otherPlayerTargetTable[o] + + if (otherTargetTable.originalName == targetTable.originalName) then + found = true + --insert the amount of the main spell in the table + otherTargetTable.mainTargetAmount = targetTable.amount + otherPlayerResultTargetsTable [#otherPlayerResultTargetsTable+1] = otherTargetTable + break + end + end + + if (not found) then + otherPlayerResultTargetsTable [#otherPlayerResultTargetsTable+1] = {"", 0, targetName = "", amount = 0, originalName = ""} + end + end + + --call the update function + comparisonFrame.targetsScroll:SetData (otherPlayerResultTargetsTable) + comparisonFrame.targetsScroll:Refresh() + end + end + + local iconTableCompare = { + texture = [[Interface\AddOns\Details\images\icons]], + --coords = {363/512, 381/512, 0/512, 17/512}, + coords = {383/512, 403/512, 0/512, 15/512}, + width = 16, + height = 14, + } + + Details:CreatePlayerDetailsTab ("New Compare", "Compare", --[1] tab name [2] localized name + function (tabOBject, playerObject) --[2] condition + + local attribute = Details:GetDisplayTypeFromBreakdownWindow() + local combat = Details:GetCombatFromBreakdownWindow() + + if (attribute > 2) then + return false + end + + local playerSpec = playerObject.spec or "no-spec" + local playerSerial = playerObject.serial + local showTab = false + + for index, actor in _ipairs (combat [attribute]._ActorTable) do + if (actor.spec == playerSpec and actor.serial ~= playerSerial) then + showTab = true + break + end + end + + if (showTab) then + return true + end + + --return false + return true --debug? + end, + + playerComparisonFill, --[3] fill function + + nil, --[4] onclick + + playerComparisonCreate, --[5] oncreate + iconTableCompare, --[6] icon table + + { + attributes = { + [1] = {1, 2, 3, 4, 5, 6, 7, 8}, + [2] = {1, 2, 3, 4, 5, 6, 7, 8}, + }, + tabNameToReplace = "Compare", + } --replace tab [attribute] = [sub attributes] + ) + end + +--------------------------------------------------------------------------------------------------------------------------------------- + + function compareTwo:OnEvent(_, event, ...) + if (event == "ADDON_LOADED") then + local AddonName = select(1, ...) + if (AddonName == "Details_Compare2") then + --> every plugin must have a OnDetailsEvent function + function compareTwo:OnDetailsEvent(event, ...) + return handle_details_event(event, ...) + end + + --> Install: install -> if successful installed; saveddata -> a table saved inside details db, used to save small amount of data like configs + local install, saveddata = Details:InstallPlugin("RAID", "Compare 2.0", "Interface\\Icons\\Ability_Warrior_BattleShout", compareTwo, "DETAILS_PLUGIN_COMPARETWO_WINDOW", MINIMAL_DETAILS_VERSION_REQUIRED, "Terciob", COMPARETWO_VERSION) + if (type(install) == "table" and install.error) then + print(install.error) + end + + --> registering details events we need + Details:RegisterEvent(compareTwo, "COMBAT_PLAYER_ENTER") --when details creates a new segment, not necessary the player entering in combat. + Details:RegisterEvent(compareTwo, "COMBAT_PLAYER_LEAVE") --when details finishs a segment, not necessary the player leaving the combat. + Details:RegisterEvent(compareTwo, "DETAILS_DATA_RESET") --details combat data has been wiped + + compareTwo.InstallAdvancedCompareWindow() + + --this plugin does not show in lists of plugins + compareTwo.NoMenu = true + end + end + end +end \ No newline at end of file diff --git a/plugins/Details_Compare2/Details_Compare2.toc b/plugins/Details_Compare2/Details_Compare2.toc new file mode 100644 index 00000000..3acb3752 --- /dev/null +++ b/plugins/Details_Compare2/Details_Compare2.toc @@ -0,0 +1,6 @@ +## Interface: 100002 +## Title: Details!: Compare 2.0 +## Notes: Replace the Compare tab in the player breakdown window. +## RequiredDeps: Details + +Details_Compare2.lua