From 025d339a445f1b79240cc914920a5e310b7a26b0 Mon Sep 17 00:00:00 2001 From: Tercio Date: Sun, 7 May 2017 16:21:47 -0300 Subject: [PATCH] - fix for tickets #189 and #186. --- boot.lua | 10 ++- classes/classe_combate.lua | 44 +++++++++- classes/classe_energy.lua | 125 +++++++++++++++++++-------- classes/classe_heal.lua | 59 ++++++++++++- classes/classe_heal_habilidade.lua | 5 +- core/parser.lua | 97 ++++++++++++++++----- functions/attributes.lua | 9 +- gumps/janela_info.lua | 5 ++ images/atributos_icones_energyze.blp | Bin 19585 -> 12148 bytes 9 files changed, 283 insertions(+), 71 deletions(-) diff --git a/boot.lua b/boot.lua index a436437f..28fa3fcb 100644 --- a/boot.lua +++ b/boot.lua @@ -3,9 +3,9 @@ _ = nil _detalhes = LibStub("AceAddon-3.0"):NewAddon("_detalhes", "AceTimer-3.0", "AceComm-3.0", "AceSerializer-3.0", "NickTag-1.0") - _detalhes.build_counter = 3653 + _detalhes.build_counter = 3663 _detalhes.userversion = "v7.2.0." .. _detalhes.build_counter - _detalhes.realversion = 117 --core version + _detalhes.realversion = 118 --core version _detalhes.version = _detalhes.userversion .. " (core " .. _detalhes.realversion .. ")" Details = _detalhes @@ -21,15 +21,17 @@ do local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" ) --[[ -|cFFFFFF00v7.2.0.3653.117 (|cFFFFCC00May 05th, 2017|r|cFFFFFF00)|r:\n\n +|cFFFFFF00v7.2.0.3663.118 (|cFFFFCC00May 07th, 2017|r|cFFFFFF00)|r:\n\n |cFFFFFF00-|r Added Heal Absorbed display under Heal bracket.\n\n Heal Absoorb are the heal denied by abilities such like DK's Necrotic Strike or raid boss Chromatic Anomaly's 'Time Release' ability.\n The tooltip of this display shows which players got heal denied, which abilities absorbed the heal, which abilities tried to heal but got the heal denied.\n\n +|cFFFFFF00-|r Added Alternate Power display under Energy bracket.\n\n |cFFFFFF00-|r Ticket #187: Fixed an issue when comparing hunter pets on the player detail window.\n\n +|cFFFFFF00-|r Ticket #189 #186: Fixed a taint issue for some classes when using friendly nameplates on.\n\n --]] -- - Loc ["STRING_VERSION_LOG"] = "|cFFFFFF00v7.2.0.3653.117 (|cFFFFCC00May 05th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Ticket #187: Fixed an issue when comparing hunter pets on the player detail window.\n\n|cFFFFFF00-|r Added Heal Absorbed display under Heal bracket.\n\nHeal Absorbed are the heal denied by abilities such like DK's Necrotic Strike or raid boss Chromatic Anomaly's 'Time Release' ability.The tooltip of this display shows which players got heal denied, which abilities absorbed the heal, which abilities tried to heal but got the heal denied.\n\n|cFFFFFF00v7.2.0.3512.116 (|cFFFFCC00April 27th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Havoc Demon Hunter: your fury energy is being shown under Mana Restored (don't ask me why, the combat log is telling us it's mana).\n\n|cFFFFFF00-|r Pets now are shown on damage tooltips.\n\n|cFFFFFF00-|r Pets are now also shown on the comparison panel.\n\n|cFFFFFF00v7.2.0.3474.116 (|cFFFFCC00April 20th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Plugin: Raid Check > added some food buffs which wasn't being tracked.\n\n|cFFFFFF00v7.2.0.3467.116 (|cFFFFCC00April 07th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fix for the custom display window where apply and cancel buttons where over the edit window.\n\n|cFFFFFF00-|r Fix for an issue on editing a bookmark.\n\n|cFFFFFF00v7.1.5.3459.116 (|cFFFFCC00Mar 21th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fixed an issue on dynamic overall data where it wasn't showing DPS.\n\n|cFFFFFF00-|r Fixed an issue with Apply, Save and Cancel buttons when editing a custom display.\n\n|cFFFFFF00-|r Removed the Damage and Healing presets for custom displays, now is only possible create custom displays by scripting them.\n\n|cFFFFFF00v7.1.5.3431.116 (|cFFFFCC00Mar 15th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fixed an issue with bar orientation right to left where fixed bar color isn't working.\n\n|cFFFFFF00-|r The nickname field now use FrizQuadrataTT font and shall be compatible with Cyrillic.\n\n|cFFFFFF00v7.1.5.3418.116 (|cFFFFCC00Mar 1st, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Ticket #167 fix: Light of the Martyr self-damage now does reduce the healing done (following WCL method).\n\n|cFFFFFF00-|r Ticket #169 fix: Damage Prevented is now working for new segments.\n\n|cFFFFFF00-|r Fixed an issue where sometimes BeastMaster's Hati pet wasn't detected correctly.\n\n|cFFFFFF00v7.1.5.3369.116 (|cFFFFCC00Feb 07th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Added custom display 'Dynamic Overall Damage' for mythic dungeons.\n\n|cFFFFFF00-|r Fix for Ticket #168: 'Auto Hide While [Not] Inside Instance is broken'.\n\n|cFFFFFF00-|r The bar truncate frame 'DetailsLeftTextAntiTruncate' is now created on Details! load instead on demand.\n\n|cFFFFFF00v7.1.5.3315.116 (|cFFFFCC00Jan 23th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Ticket #162: 'no Monochrome font' available, added an experimental slash command: /run _detalhes:UseOutline ('MONOCHROME').\n\n|cFFFFFF00-|r Ticket #158: 'no elapsed time shown on report to chat', added the elapsed time when reporting a segment.\n\n|cFFFFFF00-|r Ticket #164: 'error when browsing segments', an attempt to fix the problem has been made.\n\n|cFFFFFF00v7.1.5.3305.116 (|cFFFFCC00Jan 15th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Another fix for mythic dungeons overall data reset (thanks Tharai @ Curseforge).\n\n|cFFFFFF00-|r Fix for spec detection on PvP Arenas (thanks Pas06 @ Curseforge).\n\n|cFFFFFF00v7.1.0.3276.115 (|cFFFFCC00Jan 08th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fixed the overall data not reseting when starting a new mythic+ dungeon.\n\n|cFFFFFF00v7.1.0.3266.115 (|cFFFFCC00Dec 29th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fixed an issue with overall data not updating correctly at the end of the combat.\n\n|cFFFFFF00-|r Added a tutorial line on the window when the user access overall data.\n\n|cFFFFFF00v7.1.0.3236.115 (|cFFFFCC00Dec 19th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Integration with BigWigs should be working okay now.\n\n|cFFFFFF00v7.1.0.3231.115 (|cFFFFCC00Dec 15th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Disabled the link with BigWigs to avoid the 'RegisterMessage' error on every login.\n\n|cFFFFFF00v7.1.0.3229.115 (|cFFFFCC00Dec 09th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r When a window is locked, resize grips shouldn't be enabled messing with bar mouse over.\n\n|cFFFFFF00v7.0.3.3222.115 (|cFFFFCC00November 28th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Added Unstable Affliction to common spells with the same name.\n\n|cFFFFFF00-|r Fixed few issues with built-in plugins.\n\n|cFFFFFF00v7.0.3.3202.115 (|cFFFFCC00November 08th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Weakauras creator from the Encounter Details plugin and '/details forge' shall work correctly now with Trials of Valor.\n\n|cFFFFFF00-|r Raid history should now be recording your Trials of Valor kills.\n\n|cFFFFFF00-|r Added Trials of Valor raid info, good luck and have fun!.\n\n|cFFFFFF00v7.0.3.3201.115 (|cFFFFCC00November 04th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fix for Paladin holy icon.\n\n|cFFFFFF00-|r Fix for Rogue outlaw icon.\n\n|cFFFFFF00-|r Fixed misc displays with bar sorted by ascending order.\n\n|cFFFFFF00-|r Fix for '/details show' command while the window is on auto hide.\n\n|cFFFFFF00v7.0.3.3114.115 (|cFFFFCC00October 26th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Encounter Details (plugin): tooltip tutorial is now clamped to screen and its close button should be visible.\n\n|cFFFFFF00-|r Raid Check (plugin): now also works on dungeons.\n\n|cFFFFFF00-|r Added Potion of the Prolongued Power to the tracker.\n\n|cFFFFFF00v7.1.0.3097.115 (|cFFFFCC00October 25th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r renamed 'report history' to 'latest reports'.\n\n|cFFFFFF00-|r attempt to make all Details! users on the party or raid to track rogue's akaari's soul." + Loc ["STRING_VERSION_LOG"] = "|cFFFFFF00v7.2.0.3663.118 (|cFFFFCC00May 07th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Added Heal Absorbed display under Heal bracket.\n\nHeal Absoorb are the heal denied by abilities such like DK's Necrotic Strike or raid boss Chromatic Anomaly's 'Time Release' ability.\nThe tooltip of this display shows which players got heal denied, which abilities absorbed the heal, which abilities tried to heal but got the heal denied.\n\n|cFFFFFF00-|r Added Alternate Power display under Energy bracket.\n\n|cFFFFFF00-|r Ticket #187: Fixed an issue when comparing hunter pets on the player detail window.\n\n|cFFFFFF00-|r Ticket #189 #186: Fixed a taint issue for some classes when using friendly nameplates on.\n\n|cFFFFFF00v7.2.0.3512.116 (|cFFFFCC00April 27th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Havoc Demon Hunter: your fury energy is being shown under Mana Restored (don't ask me why, the combat log is telling us it's mana).\n\n|cFFFFFF00-|r Pets now are shown on damage tooltips.\n\n|cFFFFFF00-|r Pets are now also shown on the comparison panel.\n\n|cFFFFFF00v7.2.0.3474.116 (|cFFFFCC00April 20th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Plugin: Raid Check > added some food buffs which wasn't being tracked.\n\n|cFFFFFF00v7.2.0.3467.116 (|cFFFFCC00April 07th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fix for the custom display window where apply and cancel buttons where over the edit window.\n\n|cFFFFFF00-|r Fix for an issue on editing a bookmark.\n\n|cFFFFFF00v7.1.5.3459.116 (|cFFFFCC00Mar 21th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fixed an issue on dynamic overall data where it wasn't showing DPS.\n\n|cFFFFFF00-|r Fixed an issue with Apply, Save and Cancel buttons when editing a custom display.\n\n|cFFFFFF00-|r Removed the Damage and Healing presets for custom displays, now is only possible create custom displays by scripting them.\n\n|cFFFFFF00v7.1.5.3431.116 (|cFFFFCC00Mar 15th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fixed an issue with bar orientation right to left where fixed bar color isn't working.\n\n|cFFFFFF00-|r The nickname field now use FrizQuadrataTT font and shall be compatible with Cyrillic.\n\n|cFFFFFF00v7.1.5.3418.116 (|cFFFFCC00Mar 1st, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Ticket #167 fix: Light of the Martyr self-damage now does reduce the healing done (following WCL method).\n\n|cFFFFFF00-|r Ticket #169 fix: Damage Prevented is now working for new segments.\n\n|cFFFFFF00-|r Fixed an issue where sometimes BeastMaster's Hati pet wasn't detected correctly.\n\n|cFFFFFF00v7.1.5.3369.116 (|cFFFFCC00Feb 07th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Added custom display 'Dynamic Overall Damage' for mythic dungeons.\n\n|cFFFFFF00-|r Fix for Ticket #168: 'Auto Hide While [Not] Inside Instance is broken'.\n\n|cFFFFFF00-|r The bar truncate frame 'DetailsLeftTextAntiTruncate' is now created on Details! load instead on demand.\n\n|cFFFFFF00v7.1.5.3315.116 (|cFFFFCC00Jan 23th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Ticket #162: 'no Monochrome font' available, added an experimental slash command: /run _detalhes:UseOutline ('MONOCHROME').\n\n|cFFFFFF00-|r Ticket #158: 'no elapsed time shown on report to chat', added the elapsed time when reporting a segment.\n\n|cFFFFFF00-|r Ticket #164: 'error when browsing segments', an attempt to fix the problem has been made.\n\n|cFFFFFF00v7.1.5.3305.116 (|cFFFFCC00Jan 15th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Another fix for mythic dungeons overall data reset (thanks Tharai @ Curseforge).\n\n|cFFFFFF00-|r Fix for spec detection on PvP Arenas (thanks Pas06 @ Curseforge).\n\n|cFFFFFF00v7.1.0.3276.115 (|cFFFFCC00Jan 08th, 2017|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fixed the overall data not reseting when starting a new mythic+ dungeon.\n\n|cFFFFFF00v7.1.0.3266.115 (|cFFFFCC00Dec 29th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fixed an issue with overall data not updating correctly at the end of the combat.\n\n|cFFFFFF00-|r Added a tutorial line on the window when the user access overall data.\n\n|cFFFFFF00v7.1.0.3236.115 (|cFFFFCC00Dec 19th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Integration with BigWigs should be working okay now.\n\n|cFFFFFF00v7.1.0.3231.115 (|cFFFFCC00Dec 15th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Disabled the link with BigWigs to avoid the 'RegisterMessage' error on every login.\n\n|cFFFFFF00v7.1.0.3229.115 (|cFFFFCC00Dec 09th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r When a window is locked, resize grips shouldn't be enabled messing with bar mouse over.\n\n|cFFFFFF00v7.0.3.3222.115 (|cFFFFCC00November 28th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Added Unstable Affliction to common spells with the same name.\n\n|cFFFFFF00-|r Fixed few issues with built-in plugins.\n\n|cFFFFFF00v7.0.3.3202.115 (|cFFFFCC00November 08th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Weakauras creator from the Encounter Details plugin and '/details forge' shall work correctly now with Trials of Valor.\n\n|cFFFFFF00-|r Raid history should now be recording your Trials of Valor kills.\n\n|cFFFFFF00-|r Added Trials of Valor raid info, good luck and have fun!.\n\n|cFFFFFF00v7.0.3.3201.115 (|cFFFFCC00November 04th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Fix for Paladin holy icon.\n\n|cFFFFFF00-|r Fix for Rogue outlaw icon.\n\n|cFFFFFF00-|r Fixed misc displays with bar sorted by ascending order.\n\n|cFFFFFF00-|r Fix for '/details show' command while the window is on auto hide.\n\n|cFFFFFF00v7.0.3.3114.115 (|cFFFFCC00October 26th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r Encounter Details (plugin): tooltip tutorial is now clamped to screen and its close button should be visible.\n\n|cFFFFFF00-|r Raid Check (plugin): now also works on dungeons.\n\n|cFFFFFF00-|r Added Potion of the Prolongued Power to the tracker.\n\n|cFFFFFF00v7.1.0.3097.115 (|cFFFFCC00October 25th, 2016|r|cFFFFFF00)|r:\n\n|cFFFFFF00-|r renamed 'report history' to 'latest reports'.\n\n|cFFFFFF00-|r attempt to make all Details! users on the party or raid to track rogue's akaari's soul." Loc ["STRING_DETAILS1"] = "|cffffaeaeDetails!:|r " diff --git a/classes/classe_combate.lua b/classes/classe_combate.lua index d6aa2338..abfe2fa4 100644 --- a/classes/classe_combate.lua +++ b/classes/classe_combate.lua @@ -102,6 +102,10 @@ return self.combat_counter end + function combate:GetAlteranatePower() + return self.alternate_power + end + --return the name of the encounter or enemy function combate:GetCombatName (try_find) if (self.is_pvp) then @@ -166,7 +170,7 @@ end --return the total of a specific attribute - local power_table = {0, 1, 3, 6} + local power_table = {0, 1, 3, 6, 0, "alternatepower"} function combate:GetTotal (attribute, subAttribute, onlyGroup) if (attribute == 1 or attribute == 2) then @@ -197,6 +201,12 @@ return 0 end + + function combate:CreateAlternatePowerTable (actorName) + local t = {last = 0, total = 0} + self.alternate_power [actorName] = t + return t + end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --> internals @@ -252,6 +262,9 @@ esta_tabela.frags = {} esta_tabela.frags_need_refresh = false + --> alternate power + esta_tabela.alternate_power = {} + --> time data container esta_tabela.TimeData = _detalhes:TimeDataCreateCombatTables() esta_tabela.PhaseData = {{1, 1}, damage = {}, heal = {}, damage_section = {}, heal_section = {}} --[1] phase number [2] phase started @@ -290,7 +303,8 @@ [0] = 0, --> mana [1] = 0, --> rage [3] = 0, --> energy (rogues cat) - [6] = 0 --> runepower (dk) + [6] = 0, --> runepower (dk) + alternatepower = 0, }, {--> misc cc_break = 0, --> armazena quantas quebras de CC @@ -316,7 +330,8 @@ [0] = 0, --> mana [1] = 0, --> rage [3] = 0, --> energy (rogues cat) - [6] = 0 --> runepower (dk) + [6] = 0, --> runepower (dk) + alternatepower = 0, }, {--> misc cc_break = 0, --> armazena quantas quebras de CC @@ -467,7 +482,17 @@ end end combate1.frags_need_refresh = true - + + --> alternate power + local overallPowerTable = combate1.alternate_power + for actorName, powerTable in pairs (combate2.alternate_power) do + local power = overallPowerTable [actorName] + if (power) then + power.total = power.total - powerTable.total + end + combate2.alternate_power [actorName].last = 0 + end + return combate1 end @@ -495,6 +520,17 @@ shadow.grupo = actor.grupo end end + + --> alternate power + local overallPowerTable = combate1.alternate_power + for actorName, powerTable in pairs (combate2.alternate_power) do + local power = overallPowerTable [actorName] + if (not power) then + power = combate1:CreateAlternatePowerTable (actorName) + end + power.total = power.total + powerTable.total + combate2.alternate_power [actorName].last = 0 + end return combate1 end diff --git a/classes/classe_energy.lua b/classes/classe_energy.lua index adee5638..4f1f0788 100644 --- a/classes/classe_energy.lua +++ b/classes/classe_energy.lua @@ -76,6 +76,7 @@ function atributo_energy:NovaTabela (serial, nome, link) total = alphabetical, received = alphabetical, resource = alphabetical, + alternatepower = alphabetical, last_value = nil, @@ -146,6 +147,10 @@ local sort_energy = function (t1, t2) end end +local sort_energyalternate = function (t1, t2) + return t1.alternatepower > t2.alternatepower +end + local sort_energy_group = function (t1, t2) if (t1.grupo and t2.grupo) then if (t1.powertype == power_type and t2.powertype == power_type) then @@ -168,6 +173,20 @@ local sort_energy_group = function (t1, t2) end end +local sort_alternateenergy_group = function (t1, t2) + if (t1.grupo and t2.grupo) then + return t1.alternatepower > t2.alternatepower + else + if (t1.grupo) then + return true + elseif (t2.grupo) then + return false + else + return t1.alternatepower > t2.alternatepower + end + end +end + --> resource refresh local function RefreshBarraResources (tabela, barra, instancia) @@ -341,58 +360,93 @@ function atributo_energy:RefreshWindow (instancia, tabela_do_combate, forcar, ex keyName = "received" + if (sub_atributo == 6) then + keyName = "alternatepower" + end + if (exportar) then if (_type (exportar) == "boolean") then - keyName = "received" + --keyName = "received" else keyName = exportar.key modo = exportar.modo end else - keyName = "received" + --keyName = "received" end if (modo == modo_ALL) then - _table_sort (conteudo, sort_energy) + _table_sort (conteudo, sort_energyalternate) - for i = amount, 1, -1 do - if (conteudo[i].received < 1) then - amount = amount-1 - elseif (conteudo[i].powertype ~= power_type) then - amount = amount-1 - else - break - end - end - - - total = tabela_do_combate.totals [class_type] [power_type] - instancia.top = conteudo[1].received - - elseif (modo == modo_GROUP) then - - _table_sort (conteudo, sort_energy_group) - - for index, player in _ipairs (conteudo) do - if (player.grupo) then - if (player.received < 1) then - amount = index - 1 - break - elseif (player.powertype ~= power_type) then - amount = index - 1 + if (keyName == "alternatepower") then + for i = amount, 1, -1 do + if (conteudo[i].alternatepower < 1) then + amount = amount-1 + else break end - - total = total + player.received - else - amount = index-1 - break end + + total = tabela_do_combate.totals [class_type] ["alternatepower"] + instancia.top = conteudo[1].alternatepower + else + for i = amount, 1, -1 do + if (conteudo[i].received < 1) then + amount = amount-1 + elseif (conteudo[i].powertype ~= power_type) then + amount = amount-1 + else + break + end + end + + total = tabela_do_combate.totals [class_type] [power_type] + instancia.top = conteudo[1].received end - instancia.top = conteudo[1].received + elseif (modo == modo_GROUP) then + if (keyName == "alternatepower") then + _table_sort (conteudo, sort_alternateenergy_group) + + for index, player in _ipairs (conteudo) do + if (player.grupo) then + if (player.alternatepower < 1) then + amount = index - 1 + break + end + + total = total + player.alternatepower + else + amount = index-1 + break + end + end + instancia.top = conteudo[1].alternatepower + + else + + _table_sort (conteudo, sort_energy_group) + + for index, player in _ipairs (conteudo) do + if (player.grupo) then + if (player.received < 1) then + amount = index - 1 + break + elseif (player.powertype ~= power_type) then + amount = index - 1 + break + end + + total = total + player.received + else + amount = index-1 + break + end + end + instancia.top = conteudo[1].received + end end showing:remapear() @@ -1369,6 +1423,7 @@ end --> total das energias (captura de dados) shadow.total = shadow.total + actor.total shadow.received = shadow.received + actor.received + shadow.alternatepower = shadow.alternatepower + actor.alternatepower if (not actor.powertype) then --print ("actor without powertype", actor.nome, actor.powertype) @@ -1449,6 +1504,7 @@ atributo_energy.__add = function (tabela1, tabela2) --> total and received tabela1.total = tabela1.total + tabela2.total tabela1.received = tabela1.received + tabela2.received + tabela1.alternatepower = tabela1.alternatepower + tabela2.alternatepower --> targets for target_name, amount in _pairs (tabela2.targets) do @@ -1486,6 +1542,7 @@ atributo_energy.__sub = function (tabela1, tabela2) --> total and received tabela1.total = tabela1.total - tabela2.total tabela1.received = tabela1.received - tabela2.received + tabela1.alternatepower = tabela1.alternatepower - tabela2.alternatepower --> targets for target_name, amount in _pairs (tabela2.targets) do diff --git a/classes/classe_heal.lua b/classes/classe_heal.lua index 880a8c49..5314b609 100644 --- a/classes/classe_heal.lua +++ b/classes/classe_heal.lua @@ -266,7 +266,7 @@ function atributo_heal:RefreshWindow (instancia, tabela_do_combate, forcar, expo --> grava o total instancia.top = conteudo[1][keyName] - elseif (instancia.modo == modo_ALL or sub_atributo == 5) then --> mostrando ALL + elseif (instancia.modo == modo_ALL or sub_atributo == 5 or sub_atributo == 7) then --> mostrando ALL amount = _detalhes:ContainerSortHeal (conteudo, amount, keyName) @@ -974,6 +974,7 @@ function atributo_heal:ToolTip_HealingDenied (instancia, numero, barra, keydown) local spellList = {} --spells the player used to deny heal local targetList = {} --all players affected local spellsDenied = {} --all spells which had heal denied + local healersDenied = {} --heal denied on healers local icon_size = _detalhes.tooltip.icon_size local icon_border = _detalhes.tooltip.icon_border_texcoord @@ -992,6 +993,11 @@ function atributo_heal:ToolTip_HealingDenied (instancia, numero, barra, keydown) for spellID, amount in _pairs (spell.heal_denied) do spellsDenied [spellID] = (spellsDenied [spellID] or 0) + amount end + + --healers denied + for healerName, amount in _pairs (spell.heal_denied_healers) do + healersDenied [healerName] = (healersDenied [healerName] or 0) + amount + end end end @@ -1110,7 +1116,38 @@ function atributo_heal:ToolTip_HealingDenied (instancia, numero, barra, keydown) _detalhes:AddTooltipBackgroundStatusbar() end - + + --healers denied + + _detalhes:AddTooltipSpellHeaderText ("Healers", headerColor, #spellsSorted, [[Interface\TUTORIALFRAME\UI-TutorialFrame-LevelUp]], 0.10546875, 0.89453125, 0.05859375, 0.6796875) + _detalhes:AddTooltipHeaderStatusbar (r, g, b, barAlha) + + local healersSorted = {} + for healerName, amount in _pairs (healersDenied) do + tinsert (healersSorted, {healerName, amount}) + end + table.sort (healersSorted, _detalhes.Sort2) + + for i = 1, #healersSorted do + local playerName, amountDenied = unpack (healersSorted [i]) + + GameCooltip:AddLine (playerName .. ": ", FormatTooltipNumber (_, amountDenied) .." (" .. _cstr ("%.1f", amountDenied / totalDenied * 100) .. "%)") + _detalhes:AddTooltipBackgroundStatusbar() + + local targetActor = container:PegarCombatente (nil, playerName) or instancia.showing [1]:PegarCombatente (nil, playerName) + if (targetActor) then + local classe = targetActor.classe + if (not classe) then + classe = "UNKNOW" + end + if (classe == "UNKNOW") then + GameCooltip:AddIcon ("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, 14, 14, .25, .5, 0, 1) + else + GameCooltip:AddIcon ("Interface\\AddOns\\Details\\images\\classes_small", nil, nil, 14, 14, _unpack (_detalhes.class_coords [classe])) + end + end + end + return true end @@ -2348,12 +2385,18 @@ end if (habilidade.heal_denied) then --> cria o container na shadow de ele não existir habilidade_shadow.heal_denied = habilidade_shadow.heal_denied or {} + habilidade_shadow.heal_denied_healers = habilidade_shadow.heal_denied_healers or {} --> copia for spellID, amount in _pairs (habilidade.heal_denied) do if (not habilidade_shadow.heal_denied [spellID]) then habilidade_shadow.heal_denied [spellID] = 0 end end + for healerName, amount in _pairs (habilidade.heal_denied_healers) do + if (not habilidade_shadow.heal_denied_healers [healerName]) then + habilidade_shadow.heal_denied_healers [healerName] = 0 + end + end end end @@ -2464,10 +2507,14 @@ end if (habilidade.heal_denied) then --> cria o container na shadow de ele não existir habilidade_shadow.heal_denied = habilidade_shadow.heal_denied or {} + habilidade_shadow.heal_denied_healers = habilidade_shadow.heal_denied_healers or {} --> copia for spellID, amount in _pairs (habilidade.heal_denied) do habilidade_shadow.heal_denied [spellID] = (habilidade_shadow.heal_denied [spellID] or 0) + amount end + for healerName, amount in _pairs (habilidade.heal_denied_healers) do + habilidade_shadow.heal_denied_healers [healerName] = (habilidade_shadow.heal_denied_healers [healerName] or 0) + amount + end end --> soma todos os demais valores @@ -2570,10 +2617,14 @@ atributo_heal.__add = function (tabela1, tabela2) if (habilidade.heal_denied) then --> cria o container na shadow de ele não existir habilidade_tabela1.heal_denied = habilidade_tabela1.heal_denied or {} + habilidade_tabela1.heal_denied_healers = habilidade_tabela1.heal_denied_healers or {} --> copia for spellID, amount in _pairs (habilidade.heal_denied) do habilidade_tabela1.heal_denied [spellID] = (habilidade_tabela1.heal_denied [spellID] or 0) + amount end + for healerName, amount in _pairs (habilidade.heal_denied_healers) do + habilidade_tabela1.heal_denied_healers [healerName] = (habilidade_tabela1.heal_denied_healers [healerName] or 0) + amount + end end --> soma os valores da habilidade @@ -2676,10 +2727,14 @@ atributo_heal.__sub = function (tabela1, tabela2) if (habilidade.heal_denied) then --> cria o container na shadow de ele não existir habilidade_tabela1.heal_denied = habilidade_tabela1.heal_denied or {} + habilidade_tabela1.heal_denied_healers = habilidade_tabela1.heal_denied_healers or {} --> copia for spellID, amount in _pairs (habilidade.heal_denied) do habilidade_tabela1.heal_denied [spellID] = (habilidade_tabela1.heal_denied [spellID] or 0) - amount end + for healerName, amount in _pairs (habilidade.heal_denied_healers) do + habilidade_tabela1.heal_denied_healers [healerName] = (habilidade_tabela1.heal_denied_healers [healerName] or 0) - amount + end end --> soma os valores da habilidade diff --git a/classes/classe_heal_habilidade.lua b/classes/classe_heal_habilidade.lua index 428faa64..74bbb6fc 100644 --- a/classes/classe_heal_habilidade.lua +++ b/classes/classe_heal_habilidade.lua @@ -64,13 +64,16 @@ self.counter = self.counter + 1 self.totaldenied = self.totaldenied + amount + local healerName = critical + --create the denied table spells, on the fly if (not self.heal_denied) then self.heal_denied = {} + self.heal_denied_healers = {} end self.heal_denied [extraSpellID] = (self.heal_denied [extraSpellID] or 0) + amount - + self.heal_denied_healers [healerName] = (self.heal_denied_healers [healerName] or 0) + amount else self.total = self.total + amount diff --git a/core/parser.lua b/core/parser.lua index 9203d1bc..26c0ee5a 100644 --- a/core/parser.lua +++ b/core/parser.lua @@ -1063,7 +1063,7 @@ end --return spell:Add (alvo_serial, alvo_name, alvo_flags, cura_efetiva, who_name, absorbed, critical, overhealing) - return spell_heal_func (spell, alvo_serial, alvo_name, alvo_flags, amountDenied, spellidHeal, token, critical, overhealing) + return spell_heal_func (spell, alvo_serial, alvo_name, alvo_flags, amountDenied, spellidHeal, token, nameHealer, overhealing) --print ("|token:", token, "|time:", time, "|whoserial:", who_serial, "|whoname:", who_name, "|whoflags:", who_flags, "|alvoserial:", alvo_serial, "|alvoname:", alvo_name, "|alvoflags", alvo_flags, "|alvoflags2:", alvo_flags2, "|spellidAbsorb:", spellidAbsorb, "|spellnameABsorb", spellnameAbsorb, "|spellschoolAbsorb", spellschoolAbsorb, "|serialhealer:", serialHealer, "|nameHealer:", nameHealer, "|flagsHealer:", flagsHealer, "|flagsHealer2:", flags2Healer, "|spellidHeal:", spellidHeal, "|spellnameHeal:", spellnameHeal, "|typeHeal:", typeHeal, "|amountDenied:", amountDenied) @@ -2122,25 +2122,25 @@ ameHealer: Bombad local PowerEnum = Enum and Enum.PowerType -SPELL_POWER_MANA = SPELL_POWER_MANA or (PowerEnum and PowerEnum.Mana) or 0 -SPELL_POWER_RAGE = SPELL_POWER_RAGE or (PowerEnum and PowerEnum.Rage) or 1 -SPELL_POWER_FOCUS = SPELL_POWER_FOCUS or (PowerEnum and PowerEnum.Focus) or 2 -SPELL_POWER_ENERGY = SPELL_POWER_ENERGY or (PowerEnum and PowerEnum.Energy) or 3 -SPELL_POWER_COMBO_POINTS =SPELL_POWER_COMBO_POINTS or (PowerEnum and PowerEnum.ComboPoints) or 4 -SPELL_POWER_RUNES = SPELL_POWER_RUNES or (PowerEnum and PowerEnum.Runes) or 5 -SPELL_POWER_RUNIC_POWER = SPELL_POWER_RUNIC_POWER or (PowerEnum and PowerEnum.RunicPower) or 6 -SPELL_POWER_SOUL_SHARDS = SPELL_POWER_SOUL_SHARDS or (PowerEnum and PowerEnum.SoulShards) or 7 -SPELL_POWER_LUNAR_POWER = SPELL_POWER_LUNAR_POWER or (PowerEnum and PowerEnum.LunarPower) or 8 -SPELL_POWER_HOLY_POWER = SPELL_POWER_HOLY_POWER or (PowerEnum and PowerEnum.HolyPower) or 9 -SPELL_POWER_ALTERNATE_POWER = SPELL_POWER_ALTERNATE_POWER or (PowerEnum and PowerEnum.Alternate) or 10 -SPELL_POWER_MAELSTROM = SPELL_POWER_MAELSTROM or (PowerEnum and PowerEnum.Maelstrom) or 11 -SPELL_POWER_CHI = SPELL_POWER_CHI or (PowerEnum and PowerEnum.Chi) or 12 -SPELL_POWER_INSANITY = SPELL_POWER_INSANITY or (PowerEnum and PowerEnum.Insanity) or 13 -SPELL_POWER_OBSOLETE = SPELL_POWER_OBSOLETE or (PowerEnum and PowerEnum.Obsolete) or 14 -SPELL_POWER_OBSOLETE2 = SPELL_POWER_OBSOLETE2 or (PowerEnum and PowerEnum.Obsolete2) or 15 -SPELL_POWER_ARCANE_CHARGES = SPELL_POWER_ARCANE_CHARGES or (PowerEnum and PowerEnum.ArcaneCharges) or 16 -SPELL_POWER_FURY = SPELL_POWER_FURY or (PowerEnum and PowerEnum.Fury) or 17 -SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 18 +local SPELL_POWER_MANA = SPELL_POWER_MANA or (PowerEnum and PowerEnum.Mana) or 0 +local SPELL_POWER_RAGE = SPELL_POWER_RAGE or (PowerEnum and PowerEnum.Rage) or 1 +local SPELL_POWER_FOCUS = SPELL_POWER_FOCUS or (PowerEnum and PowerEnum.Focus) or 2 +local SPELL_POWER_ENERGY = SPELL_POWER_ENERGY or (PowerEnum and PowerEnum.Energy) or 3 +local SPELL_POWER_COMBO_POINTS2 = SPELL_POWER_COMBO_POINTS or (PowerEnum and PowerEnum.ComboPoints) or 4 +local SPELL_POWER_RUNES = SPELL_POWER_RUNES or (PowerEnum and PowerEnum.Runes) or 5 +local SPELL_POWER_RUNIC_POWER = SPELL_POWER_RUNIC_POWER or (PowerEnum and PowerEnum.RunicPower) or 6 +local SPELL_POWER_SOUL_SHARDS = SPELL_POWER_SOUL_SHARDS or (PowerEnum and PowerEnum.SoulShards) or 7 +local SPELL_POWER_LUNAR_POWER = SPELL_POWER_LUNAR_POWER or (PowerEnum and PowerEnum.LunarPower) or 8 +local SPELL_POWER_HOLY_POWER = SPELL_POWER_HOLY_POWER or (PowerEnum and PowerEnum.HolyPower) or 9 +local SPELL_POWER_ALTERNATE_POWER = SPELL_POWER_ALTERNATE_POWER or (PowerEnum and PowerEnum.Alternate) or 10 +local SPELL_POWER_MAELSTROM = SPELL_POWER_MAELSTROM or (PowerEnum and PowerEnum.Maelstrom) or 11 +local SPELL_POWER_CHI = SPELL_POWER_CHI or (PowerEnum and PowerEnum.Chi) or 12 +local SPELL_POWER_INSANITY = SPELL_POWER_INSANITY or (PowerEnum and PowerEnum.Insanity) or 13 +local SPELL_POWER_OBSOLETE = SPELL_POWER_OBSOLETE or (PowerEnum and PowerEnum.Obsolete) or 14 +local SPELL_POWER_OBSOLETE2 = SPELL_POWER_OBSOLETE2 or (PowerEnum and PowerEnum.Obsolete2) or 15 +local SPELL_POWER_ARCANE_CHARGES = SPELL_POWER_ARCANE_CHARGES or (PowerEnum and PowerEnum.ArcaneCharges) or 16 +local SPELL_POWER_FURY = SPELL_POWER_FURY or (PowerEnum and PowerEnum.Fury) or 17 +local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 18 local energy_types = { [SPELL_POWER_MANA] = true, @@ -2155,7 +2155,7 @@ SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 18 [SPELL_POWER_HOLY_POWER] = true, --paladins [SPELL_POWER_LUNAR_POWER] = true, --balance druids [SPELL_POWER_SOUL_SHARDS] = true, --warlock affliction - [SPELL_POWER_COMBO_POINTS] = true, --combo points + [SPELL_POWER_COMBO_POINTS2] = true, --combo points [SPELL_POWER_MAELSTROM] = true, --shamans [SPELL_POWER_PAIN] = true, --demonhunter tank [SPELL_POWER_RUNES] = true, --dk @@ -2164,7 +2164,7 @@ SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 18 } local resource_power_type = { - [SPELL_POWER_COMBO_POINTS] = SPELL_POWER_ENERGY, --combo points + [SPELL_POWER_COMBO_POINTS2] = SPELL_POWER_ENERGY, --combo points [SPELL_POWER_SOUL_SHARDS] = SPELL_POWER_MANA, --warlock [SPELL_POWER_LUNAR_POWER] = SPELL_POWER_MANA, --druid [SPELL_POWER_HOLY_POWER] = SPELL_POWER_MANA, --paladin @@ -2178,7 +2178,7 @@ SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 18 } _detalhes.resource_strings = { - [SPELL_POWER_COMBO_POINTS] = "Combo Point", + [SPELL_POWER_COMBO_POINTS2] = "Combo Point", [SPELL_POWER_SOUL_SHARDS] = "Soul Shard", [SPELL_POWER_LUNAR_POWER] = "Lunar Power", [SPELL_POWER_HOLY_POWER] = "Holy Power", @@ -2192,7 +2192,7 @@ SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 18 } _detalhes.resource_icons = { - [SPELL_POWER_COMBO_POINTS] = {file = [[Interface\PLAYERFRAME\ClassOverlayComboPoints]], coords = {58/128, 74/128, 25/64, 39/64}}, + [SPELL_POWER_COMBO_POINTS2] = {file = [[Interface\PLAYERFRAME\ClassOverlayComboPoints]], coords = {58/128, 74/128, 25/64, 39/64}}, [SPELL_POWER_SOUL_SHARDS] = {file = [[Interface\PLAYERFRAME\UI-WARLOCKSHARD]], coords = {3/64, 17/64, 2/128, 16/128}}, [SPELL_POWER_LUNAR_POWER] = {file = [[Interface\PLAYERFRAME\DruidEclipse]], coords = {117/256, 140/256, 83/128, 115/128}}, [SPELL_POWER_HOLY_POWER] = {file = [[Interface\PLAYERFRAME\PALADINPOWERTEXTURES]], coords = {75/256, 94/256, 87/128, 100/128}}, @@ -2204,12 +2204,57 @@ SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 18 [SPELL_POWER_ARCANE_CHARGES] = {file = [[Interface\PLAYERFRAME\MageArcaneCharges]], coords = {68/256, 90/256, 68/128, 91/128}}, [SPELL_POWER_FURY] = {file = [[Interface\PLAYERFRAME\UI-PlayerFrame-Deathknight-Blood-On]], coords = {0, 1, 0, 1}}, } + + local AlternatePowerEnableFrame = CreateFrame ("frame") + local AlternatePowerMonitorFrame = CreateFrame ("frame") + + AlternatePowerEnableFrame:RegisterEvent ("UNIT_POWER_BAR_SHOW") + AlternatePowerEnableFrame:RegisterEvent ("UNIT_POWER_BAR_HIDE") + + AlternatePowerEnableFrame:SetScript ("OnEvent", function (self, event) + if (event == "UNIT_POWER_BAR_SHOW") then + AlternatePowerMonitorFrame:RegisterEvent ("UNIT_POWER") + else + AlternatePowerMonitorFrame:UnregisterEvent ("UNIT_POWER") + end + end) + + AlternatePowerMonitorFrame:SetScript ("OnEvent", function (self, event, unitID, powerType) + if (powerType == "ALTERNATE") then + local actorName = _detalhes:GetCLName (unitID) + if (actorName) then + local power = _current_combat.alternate_power [actorName] + if (not power) then + power = _current_combat:CreateAlternatePowerTable (actorName) + end + local currentPower = UnitPower (unitID, 10) + if (currentPower and currentPower > power.last) then + local addPower = currentPower - power.last + power.total = power.total + addPower + + --> main actor + local este_jogador = energy_cache [actorName] + if (not este_jogador) then --> pode ser um desconhecido ou um pet + este_jogador, meu_dono, actorName = _current_energy_container:PegarCombatente (UnitGUID (unitID), actorName, 0x514, true) + energy_cache [actorName] = este_jogador + end + este_jogador.alternatepower = este_jogador.alternatepower + addPower + + _current_energy_container.need_refresh = true + end + + power.last = currentPower or 0 + end + end + end) function parser:energize (token, time, who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags, alvo_flags2, spellid, spellname, spelltype, amount, powertype, p6, p7) ------------------------------------------------------------------------------------------------ --> early checks and fixes + --print (who_name, alvo_name, spellid, spellname, spelltype, amount, powertype) + if (not who_name) then who_name = "[*] "..spellname elseif (not alvo_name) then @@ -2256,6 +2301,10 @@ SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 18 end end + if (not este_jogador.powertype) then + este_jogador.powertype = powertype + end + --> target local jogador_alvo, alvo_dono = energy_cache [alvo_name] if (not jogador_alvo) then diff --git a/functions/attributes.lua b/functions/attributes.lua index 50a571ff..e4ab012c 100644 --- a/functions/attributes.lua +++ b/functions/attributes.lua @@ -33,6 +33,7 @@ do --[[global]] DETAILS_SUBATTRIBUTE_REGENENERGY = 3 --[[global]] DETAILS_SUBATTRIBUTE_REGENRUNE = 4 --[[global]] DETAILS_SUBATTRIBUTE_RESOURCES = 5 + --[[global]] DETAILS_SUBATTRIBUTE_ALTERNATEPOWER = 6 --[[global]] DETAILS_ATTRIBUTE_MISC = 4 @@ -68,6 +69,7 @@ do "energy", --energy generated "energy", --runic power generated "energy", --resources + "energy", --alternate power "miscdata", --cc breaks "miscdata", --ress @@ -95,7 +97,7 @@ do --[[ ENERGY ]] e_energy = 3,--> identifier - [3] = 5, --> sub attributes + [3] = 6, --> sub attributes --[[ MISC ]] misc = 4, --> identifier @@ -189,12 +191,14 @@ do energy_ganha = 3, --id 3 rune_ganha = 4, --id 6 resources = 5, -- + alternatepower = 6, -- lista = { --[[ String Names ]] Loc ["STRING_ATTRIBUTE_ENERGY_MANA"], Loc ["STRING_ATTRIBUTE_ENERGY_RAGE"], Loc ["STRING_ATTRIBUTE_ENERGY_ENERGY"], Loc ["STRING_ATTRIBUTE_ENERGY_RUNEPOWER"], Loc ["STRING_ATTRIBUTE_ENERGY_RESOURCES"], + "Alternate Power (in testing)", }, icones = { {"Interface\\AddOns\\Details\\images\\atributos_icones_energyze", {0, .125, 0, 1}}, @@ -202,8 +206,9 @@ do {"Interface\\AddOns\\Details\\images\\atributos_icones_energyze", {.25, .375, 0, 1}}, {"Interface\\AddOns\\Details\\images\\atributos_icones_energyze", {.375, .5, 0, 1}}, {"Interface\\AddOns\\Details\\images\\atributos_icones_energyze", {.5, .625, 0, 1}}, + {"Interface\\AddOns\\Details\\images\\atributos_icones_energyze", {.625, .75, 0, 1}}, }, - internal = {"mana", "e_rage", "e_energy", "runepower", "resource"} + internal = {"mana", "e_rage", "e_energy", "runepower", "resource", "alternatepower"} }, { diff --git a/gumps/janela_info.lua b/gumps/janela_info.lua index a1b89824..d1dc1a14 100644 --- a/gumps/janela_info.lua +++ b/gumps/janela_info.lua @@ -1,3 +1,5 @@ +--errors ~pet + local _detalhes = _G._detalhes local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" ) local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0") @@ -2683,6 +2685,8 @@ function gump:CriaJanelaInfo() table.sort (player_2_spells_sorted, _detalhes.Sort2) player_2_top = player_2_spells_sorted [1] [2] + --se não existir uma magia no jogador e o jogador tiver um pet, ele não vai encontrar um valor em [1] e dar + -- ~pet player_2_spell_info = {} for index, spelltable in _ipairs (player_2_spells_sorted) do player_2_spell_info [spelltable[1].id] = index @@ -3037,6 +3041,7 @@ function gump:CriaJanelaInfo() end end table.sort (player_1_skills, _detalhes.Sort2) +-- ~pet local player_1_top = player_1_skills [1] [2] bar1 [2]:SetStatusBarColor (1, 1, 1, 1) diff --git a/images/atributos_icones_energyze.blp b/images/atributos_icones_energyze.blp index 92fc9127be489cf083cb92427211ca07aa23392b..ebc816b19f30a7389b7882783f7c2af3de988bee 100644 GIT binary patch literal 12148 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 ZBc(y#)3r0dsj8~d*&*1opHc?`{%;GfnPmU~ literal 19585 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