diff --git a/ElvUI_SLE/core/core.lua b/ElvUI_SLE/core/core.lua index 5fdbe8e..f3b7124 100644 --- a/ElvUI_SLE/core/core.lua +++ b/ElvUI_SLE/core/core.lua @@ -101,6 +101,7 @@ local _CompList = { "ElvUI_MerathilisUI", "QuestKing", "ElvUI_Enhanced", + "DejaCharacterStats", } for i = 1, #_CompList do if GetAddOnEnableState(E.myname, _CompList[i]) == 0 then SLE._Compatibility[_CompList[i]] = nil else SLE._Compatibility[_CompList[i]] = true end diff --git a/ElvUI_SLE/locales/english.lua b/ElvUI_SLE/locales/english.lua index 3b55460..4242e87 100644 --- a/ElvUI_SLE/locales/english.lua +++ b/ElvUI_SLE/locales/english.lua @@ -160,6 +160,14 @@ L["Only Damaged"] = true L["Gem Sockets"] = true L["Socket Size"] = true L["Inspect Armory"] = true +L["Full Item Level"] = true +L["Show both equipped and average item levels."] = true +L["Item Level Coloring"] = true +L["Color code item levels values. Equipped will be gradient, avarage - selected color."] = true +L["Color of Average"] = true +L["Sets the color of avarage item level."] = true +L["Only Relevant Stats"] = true +L["Show only those primary stats relevant to your spec."] = true --AFK L["You Are Away From Keyboard for"] = true @@ -863,6 +871,7 @@ Benik, The Slacker Blazeflack Boradan Camealion +Dejablue Nils Ruesch Omega1970 Pvtschlag diff --git a/ElvUI_SLE/locales/russian.lua b/ElvUI_SLE/locales/russian.lua index f367839..9d1bb87 100644 --- a/ElvUI_SLE/locales/russian.lua +++ b/ElvUI_SLE/locales/russian.lua @@ -157,6 +157,14 @@ L["Only Damaged"] = "Только поврежденные" L["Gem Sockets"] = "Слоты камней" L["Socket Size"] = "Размер слотов" L["Inspect Armory"] = "Осмотр" +L["Full Item Level"] = "Полный уровень предметов" +L["Show both equipped and average item levels."] = "Отображать и уровень одетых предметов, и общий средний уровень." +L["Item Level Coloring"] = "Окраска уровней предметов" +L["Color code item levels values. Equipped will be gradient, avarage - selected color."] = "Окрашивает значения уровней предметов. Цвет уровня одетых вещей будет градиентом, цвет среднего урвоня по выбору." +L["Color of Average"] = "Цвет стреднего" +L["Sets the color of avarage item level."] = "Устанавливает цвет среднего уровня предметов." +L["Only Relevant Stats"] = "Только подходящие" +L["Show only those primary stats relevant to your spec."] = "Отображает только те основные характеристики, что подходят вашей текущей специализации." --AFK L["You Are Away From Keyboard for"] = "Вы отошли на" diff --git a/ElvUI_SLE/modules/Armory/CharacterArmory/CharacterArmory.lua b/ElvUI_SLE/modules/Armory/CharacterArmory/CharacterArmory.lua index 903b525..9cd2329 100644 --- a/ElvUI_SLE/modules/Armory/CharacterArmory/CharacterArmory.lua +++ b/ElvUI_SLE/modules/Armory/CharacterArmory/CharacterArmory.lua @@ -241,10 +241,10 @@ function CA:Setup_CharacterArmory() _G["CharacterLevelText"]:SetText('|c'..RAID_CLASS_COLORS[E.myclass].colorStr.._G["CharacterLevelText"]:GetText()) _G["CharacterFrameTitleText"]:ClearAllPoints() - _G["CharacterFrameTitleText"]:Point('TOP', self, 0, 23) + _G["CharacterFrameTitleText"]:Point('TOP', self, 0, 35) _G["CharacterFrameTitleText"]:SetParent(self) _G["CharacterLevelText"]:ClearAllPoints() - _G["CharacterLevelText"]:SetPoint('TOP', _G["CharacterFrameTitleText"], 'BOTTOM', 0, -13) + _G["CharacterLevelText"]:SetPoint('TOP', _G["CharacterFrameTitleText"], 'BOTTOM', 0, 2) _G["CharacterLevelText"]:SetParent(self) end end) @@ -262,13 +262,6 @@ function CA:Setup_CharacterArmory() --<< Change Model Frame's frameLevel >>-- _G["CharacterModelFrame"]:SetFrameLevel(self:GetFrameLevel() + 2) - --<< Average Item Level >>-- - KF:TextSetting(self, nil, { Tag = 'AverageItemLevel', FontSize = 12 }, 'BOTTOM', _G["CharacterModelFrame"], 'TOP', 0, 14) - local function ValueColorUpdate() - self.AverageItemLevel:SetText(KF:Color_Value(L["Average"])..' : '..format('%.2f', T.select(2, T.GetAverageItemLevel()))) - end - E.valueColorUpdateFuncs[ValueColorUpdate] = true - -- Create each equipment slots gradation, text, gem socket icon. local Slot for i, SlotName in T.pairs(Info.Armory_Constants.GearList) do @@ -744,8 +737,6 @@ function CA:Update_Gear() end end - self.AverageItemLevel:SetText(KF:Color_Value(STAT_AVERAGE_ITEM_LEVEL)..' : '..format('%.2f', T.select(2, T.GetAverageItemLevel()))) - if NeedUpdateList then self.GearUpdated = NeedUpdateList return true @@ -852,7 +843,6 @@ function CA:Update_Display(Force) end end - KF.Modules[#KF.Modules + 1] = 'CharacterArmory' KF.Modules.CharacterArmory = function() if E.db.sle.Armory.Character.Enable ~= false then @@ -940,4 +930,14 @@ KF.Modules.CharacterArmory = function() KF_KnightArmory_NoticeMissing.CheckButton:SetTexture('Interface\\Buttons\\UI-CheckBox-Check-Disabled') ]] end + if SLE._Compatibility["DejaCharacterStats"] then return end + --Resize and reposition god damned ilevel text + CharacterStatsPane.ItemLevelFrame:SetPoint("TOP", CharacterStatsPane.ItemLevelCategory, "BOTTOM", 0, 6) + CharacterStatsPane.ItemLevelFrame:SetHeight(15) + CharacterStatsPane.ItemLevelFrame.Background:SetHeight(15) + CharacterStatsPane.ItemLevelFrame.leftGrad:SetHeight(15) + CharacterStatsPane.ItemLevelFrame.rightGrad:SetHeight(15) + CharacterStatsPane.ItemLevelFrame.Value:FontTemplate() + hooksecurefunc("PaperDollFrame_UpdateStats", CA.PaperDollFrame_UpdateStats) + CA:ToggleStats() end \ No newline at end of file diff --git a/ElvUI_SLE/modules/Armory/CharacterArmory/Load_CharacterArmory.xml b/ElvUI_SLE/modules/Armory/CharacterArmory/Load_CharacterArmory.xml index 0686a7b..a16c3f8 100644 --- a/ElvUI_SLE/modules/Armory/CharacterArmory/Load_CharacterArmory.xml +++ b/ElvUI_SLE/modules/Armory/CharacterArmory/Load_CharacterArmory.xml @@ -1,4 +1,5 @@ <Ui xmlns="http://www.blizzard.com/wow/ui/"> <Script file="Profile.lua"/> <Script file="CharacterArmory.lua"/> + <Script file="Stats.lua"/> </Ui> \ No newline at end of file diff --git a/ElvUI_SLE/modules/Armory/CharacterArmory/Profile.lua b/ElvUI_SLE/modules/Armory/CharacterArmory/Profile.lua index 5f0a19d..f61e560 100644 --- a/ElvUI_SLE/modules/Armory/CharacterArmory/Profile.lua +++ b/ElvUI_SLE/modules/Armory/CharacterArmory/Profile.lua @@ -49,5 +49,25 @@ P.sle.Armory.Character = { Display = 'Always', -- Always, MouseoverOnly, Hide SocketSize = 10, WarningSize = 12 - } + }, + + Stats = { + IlvlFull = false, + IlvlColor = false, + AverageColor = {r = 0, g = 1, b = .59}, + OnlyPrimary = true, + List = { + HEALTH = false, + POWER = false, + ALTERNATEMANA = false, + ATTACK_DAMAGE = false, + ATTACK_AP = false, + ATTACK_ATTACKSPEED = false, + SPELLPOWER = false, + ENERGY_REGEN = false, + RUNE_REGEN = false, + FOCUS_REGEN = false, + MOVESPEED = false, + }, + }, } \ No newline at end of file diff --git a/ElvUI_SLE/modules/Armory/CharacterArmory/Stats.lua b/ElvUI_SLE/modules/Armory/CharacterArmory/Stats.lua new file mode 100644 index 0000000..cf50260 --- /dev/null +++ b/ElvUI_SLE/modules/Armory/CharacterArmory/Stats.lua @@ -0,0 +1,250 @@ +local SLE, T, E, L, V, P, G = unpack(select(2, ...)) +if SLE._Compatibility["DejaCharacterStats"] then return end +--Credits: Dejablue + +--GLOBALS: PAPERDOLL_STATCATEGORIES +local CA = CharacterArmory +local totalShown = 0 + +--Replacing broken Blizz function +function PaperDollFrame_SetAttackSpeed(statFrame, unit) + local meleeHaste = GetMeleeHaste(); + local speed, offhandSpeed = UnitAttackSpeed(unit); + + local displaySpeed = format("%.2f", speed); + if ( offhandSpeed ) then + offhandSpeed = format("%.2f", offhandSpeed); + end + if ( offhandSpeed ) then + displaySpeedxt = BreakUpLargeNumbers(displaySpeed).." / ".. offhandSpeed; + else + displaySpeedxt = BreakUpLargeNumbers(displaySpeed); + end + PaperDollFrame_SetLabelAndText(statFrame, WEAPON_SPEED, displaySpeed, false, speed); + + statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, ATTACK_SPEED).." "..displaySpeed..FONT_COLOR_CODE_CLOSE; + statFrame.tooltip2 = format(STAT_ATTACK_SPEED_BASE_TOOLTIP, BreakUpLargeNumbers(meleeHaste)); + + statFrame:Show(); +end + +function PaperDollFrame_SetMovementSpeed(statFrame, unit) + statFrame.wasSwimming = nil; + statFrame.unit = unit; + MovementSpeed_OnUpdate(statFrame); + + statFrame.onEnterFunc = MovementSpeed_OnEnter; + -- TODO: Fix if we decide to show movement speed + -- statFrame:SetScript("OnUpdate", MovementSpeed_OnUpdate); + + statFrame:Show(); +end + +local PAPERDOLL_AttributesIndexDefaultStats ={ + [1] = "HEALTH", + [2] = "POWER", + [3] = "ALTERNATEMANA", + [4] = "ATTACK_DAMAGE", + [5] = "ATTACK_AP", + [6] = "ATTACK_ATTACKSPEED", + [7] = "SPELLPOWER", + [8] = "ENERGY_REGEN", + [9] = "RUNE_REGEN", + [10] = "FOCUS_REGEN", + [11] = "MOVESPEED", +} + +function CA:ResetAllStats() + PAPERDOLL_STATCATEGORIES= { + [1] = { + categoryFrame = "AttributesCategory", + stats = { + [1] = { stat = "STRENGTH", primary = LE_UNIT_STAT_STRENGTH }, + [2] = { stat = "AGILITY", primary = LE_UNIT_STAT_AGILITY }, + [3] = { stat = "INTELLECT", primary = LE_UNIT_STAT_INTELLECT }, + [4] = { stat = "STAMINA" }, + [5] = { stat = "ARMOR" }, + [6] = { stat = "MANAREGEN", roles = { "HEALER" } }, + }, + }, + [2] = { + categoryFrame = "EnhancementsCategory", + stats = { + [1] = { stat = "CRITCHANCE", hideAt = 0 }, + [2] = { stat = "HASTE", hideAt = 0 }, + [3] = { stat = "MASTERY", hideAt = 0 }, + [4] = { stat = "VERSATILITY", hideAt = 0 }, + [5] = { stat = "LIFESTEAL", hideAt = 0 }, + [6] = { stat = "AVOIDANCE", hideAt = 0 }, + [7] = { stat = "DODGE", roles = { "TANK" } }, + [8] = { stat = "PARRY", hideAt = 0, roles = { "TANK" } }, + [9] = { stat = "BLOCK", hideAt = 0, roles = { "TANK" } }, + }, + }, + }; +end + +function CA:ToggleStats() + CA:ResetAllStats() + for _, value in T.pairs(PAPERDOLL_AttributesIndexDefaultStats) do + local checked = E.db.sle.Armory.Character.Stats.List[value] + if checked then + T.tinsert(PAPERDOLL_STATCATEGORIES[1].stats, { stat = T.format("%s", value) }) + end + end + PaperDollFrame_UpdateStats(); +end + +function CA:PaperDollFrame_UpdateStats() + totalShown = 0 + local total, equipped = T.GetAverageItemLevel() + if E.db.sle.Armory.Character.Stats.IlvlFull then + if E.db.sle.Armory.Character.Stats.IlvlColor then + local R, G, B = E:ColorGradient((equipped / total), 1, 0, 0, 1, 1, 0, 0, 1, 0) + local avColor = E.db.sle.Armory.Character.Stats.AverageColor + CharacterStatsPane.ItemLevelFrame.Value:SetFormattedText("%s%.2f|r / %s%.2f|r", E:RGBToHex(R, G, B), equipped, E:RGBToHex(avColor.r, avColor.g, avColor.b), total) + else + CharacterStatsPane.ItemLevelFrame.Value:SetFormattedText("%.2f / %.2f", equipped, total) + end + else + CharacterStatsPane.ItemLevelFrame.Value:SetTextColor(GetItemLevelColor()) + PaperDollFrame_SetItemLevel(CharacterStatsPane.ItemLevelFrame, "player"); + end + + CharacterStatsPane.AttributesCategory:SetPoint("TOP", CharacterStatsPane.ItemLevelFrame, "BOTTOM", 0, 6) + + local level = UnitLevel("player"); + local categoryYOffset = 6; + local statYOffset = 0; + + CharacterStatsPane.ItemLevelCategory:Show(); + CharacterStatsPane.ItemLevelFrame:Show(); + + local spec = GetSpecialization(); + local role = GetSpecializationRole(spec); + + CharacterStatsPane.statsFramePool:ReleaseAll(); + -- we need a stat frame to first do the math to know if we need to show the stat frame + -- so effectively we'll always pre-allocate + local statFrame = CharacterStatsPane.statsFramePool:Acquire(); + + local lastAnchor; + + for catIndex = 1, #PAPERDOLL_STATCATEGORIES do + local catFrame = CharacterStatsPane[PAPERDOLL_STATCATEGORIES[catIndex].categoryFrame]; + local numStatInCat = 0; + for statIndex = 1, #PAPERDOLL_STATCATEGORIES[catIndex].stats do + local stat = PAPERDOLL_STATCATEGORIES[catIndex].stats[statIndex]; + local showStat = true; + if ( showStat and stat.primary ) then + local primaryStat = select(7, GetSpecializationInfo(spec, nil, nil, nil, UnitSex("player"))); + if ( stat.primary ~= primaryStat ) and E.db.sle.Armory.Character.Stats.OnlyPrimary then + showStat = false; + end + end + if ( showStat and stat.roles ) then + local foundRole = false; + -- local foundRole = true; + for _, statRole in pairs(stat.roles) do + if ( role == statRole ) then + foundRole = true; + break; + end + end + showStat = foundRole; + end + if ( showStat ) then + statFrame.onEnterFunc = nil; + PAPERDOLL_STATINFO[stat.stat].updateFunc(statFrame, "player"); + if ( not stat.hideAt or stat.hideAt ~= statFrame.numericValue ) then + if ( numStatInCat == 0 ) then + if ( lastAnchor ) then + catFrame:SetPoint("TOP", lastAnchor, "BOTTOM", 0, categoryYOffset); + end + lastAnchor = catFrame; + statFrame:SetPoint("TOP", catFrame, "BOTTOM", 0, 6); + else + statFrame:SetPoint("TOP", lastAnchor, "BOTTOM", 0, statYOffset); + end + if statFrame:IsShown() then + totalShown = totalShown + 1 + numStatInCat = numStatInCat + 1; + statFrame.Background:SetShown((numStatInCat % 2) == 0); + lastAnchor = statFrame; + end + -- done with this stat frame, get the next one + statFrame = CharacterStatsPane.statsFramePool:Acquire(); + end + end + end + catFrame:SetShown(numStatInCat > 0); + end + -- release the current stat frame + CharacterStatsPane.statsFramePool:Release(statFrame); + if totalShown > 16 then + CA.Scrollbar:Show() + else + CA.Scrollbar:Hide() + end +end + +--Creating new scroll +--Scrollframe Parent Frame +CA.ScrollframeParentFrame = CreateFrame("Frame", nil, CharacterFrameInsetRight) +CA.ScrollframeParentFrame:SetSize(198, 352) +CA.ScrollframeParentFrame:SetPoint("TOP", CharacterFrameInsetRight, "TOP", 0, -4) + +--Scrollframe +CA.ScrollFrame = CreateFrame("ScrollFrame", nil, CA.ScrollframeParentFrame) +CA.ScrollFrame:SetPoint("TOP") +CA.ScrollFrame:SetSize(CA.ScrollframeParentFrame:GetSize()) + +--Scrollbar +CA.Scrollbar = CreateFrame("Slider", nil, CA.ScrollFrame, "UIPanelScrollBarTemplate") +CA.Scrollbar:SetPoint("TOPLEFT", CharacterFrameInsetRight, "TOPRIGHT", -12, -20) +CA.Scrollbar:SetPoint("BOTTOMLEFT", CharacterFrameInsetRight, "BOTTOMRIGHT", -12, 18) +CA.Scrollbar:SetMinMaxValues(1, 2) +CA.Scrollbar:SetValueStep(1) +CA.Scrollbar.scrollStep = 1 +CA.Scrollbar:SetValue(0) +CA.Scrollbar:SetWidth(8) +CA.Scrollbar:SetScript("OnValueChanged", function (self, value) + self:GetParent():SetVerticalScroll(value) +end) +E:GetModule("Skins"):HandleScrollBar(CA.Scrollbar) +CA.Scrollbar:Hide() + +--CA.ScrollChild Frame +CA.ScrollChild = CreateFrame("Frame", nil, CA.ScrollFrame) +CA.ScrollChild:SetSize(CA.ScrollFrame:GetSize()) +CA.ScrollFrame:SetScrollChild(CA.ScrollChild) + +CharacterStatsPane:ClearAllPoints() +CharacterStatsPane:SetParent(CA.ScrollChild) +CharacterStatsPane:SetSize(CA.ScrollChild:GetSize()) +CharacterStatsPane:SetPoint("TOP", CA.ScrollChild, "TOP", 0, 0) + +CharacterStatsPane.ClassBackground:ClearAllPoints() +CharacterStatsPane.ClassBackground:SetParent(CharacterFrameInsetRight) +CharacterStatsPane.ClassBackground:SetPoint("CENTER") + +-- Enable mousewheel scrolling +CA.ScrollFrame:EnableMouseWheel(true) +CA.ScrollFrame:SetScript("OnMouseWheel", function(self, delta) + if totalShown > 16 then + CA.Scrollbar:SetMinMaxValues(1, 45) + else + CA.Scrollbar:SetMinMaxValues(1, 1) + end + + local cur_val = CA.Scrollbar:GetValue() + local min_val, max_val = CA.Scrollbar:GetMinMaxValues() + + if delta < 0 and cur_val < max_val then + cur_val = math.min(max_val, cur_val + 22) + CA.Scrollbar:SetValue(cur_val) + elseif delta > 0 and cur_val > min_val then + cur_val = math.max(min_val, cur_val - 22) + CA.Scrollbar:SetValue(cur_val) + end +end) \ No newline at end of file diff --git a/ElvUI_SLE/modules/Armory/Config.lua b/ElvUI_SLE/modules/Armory/Config.lua index 404c97e..956b5cd 100644 --- a/ElvUI_SLE/modules/Armory/Config.lua +++ b/ElvUI_SLE/modules/Armory/Config.lua @@ -277,6 +277,76 @@ local function LoadArmoryConfigTable() end, disabled = function() return not E.db.sle.Armory.Character.Enable or not E.db.sle.Armory.Character.NoticeMissing end, }, + Stats = { + type = 'group', + name = STAT_CATEGORY_ATTRIBUTES, + order = 3, + guiInline = true, + disabled = function() return SLE._Compatibility["DejaCharacterStats"] end, + get = function(info) return E.db.sle.Armory.Character.Stats[ info[#info] ] end, + set = function(info, value) E.db.sle.Armory.Character.Stats[ info[#info] ] = value; PaperDollFrame_UpdateStats() end, + args = { + IlvlFull = { + order = 1, + type = "toggle", + name = L["Full Item Level"], + desc = L["Show both equipped and average item levels."], + }, + IlvlColor = { + order = 2, + type = "toggle", + name = L["Item Level Coloring"], + desc = L["Color code item levels values. Equipped will be gradient, avarage - selected color."], + disabled = function() return SLE._Compatibility["DejaCharacterStats"] or not E.db.sle.Armory.Character.Stats.IlvlFull end, + }, + AverageColor = { + type = 'color', + order = 3, + name = L["Color of Average"], + desc = L["Sets the color of avarage item level."], + hasAlpha = false, + disabled = function() return SLE._Compatibility["DejaCharacterStats"] or not E.db.sle.Armory.Character.Stats.IlvlFull end, + get = function(info) + local t = E.db.sle.Armory.Character.Stats[ info[#info] ] + local d = P.sle.Armory.Character.Stats[info[#info]] + return t.r, t.g, t.b, t.a, d.r, d.g, d.b, d.a + end, + set = function(info, r, g, b, a) + E.db.sle.Armory.Character.Stats[ info[#info] ] = {} + local t = E.db.sle.Armory.Character.Stats[ info[#info] ] + t.r, t.g, t.b, t.a = r, g, b, a + PaperDollFrame_UpdateStats() + end, + }, + OnlyPrimary = { + order = 4, + type = "toggle", + name = L["Only Relevant Stats"], + desc = L["Show only those primary stats relevant to your spec."], + }, + Stats = { + type = 'group', + name = STAT_CATEGORY_ATTRIBUTES, + order = 6, + guiInline = true, + get = function(info) return E.db.sle.Armory.Character.Stats.List[ info[#info] ] end, + set = function(info, value) E.db.sle.Armory.Character.Stats.List[ info[#info] ] = value; CharacterArmory:ToggleStats() end, + args = { + HEALTH = { order = 1,type = "toggle",name = HEALTH,}, + POWER = { order = 2,type = "toggle",name = _G[select(2, UnitPowerType("player"))],}, + ALTERNATEMANA = { order = 3,type = "toggle",name = ALTERNATE_RESOURCE_TEXT,}, + ATTACK_DAMAGE = { order = 4,type = "toggle",name = DAMAGE,}, + ATTACK_AP = { order = 5,type = "toggle",name = ATTACK_POWER,}, + ATTACK_ATTACKSPEED = { order = 6,type = "toggle",name = ATTACK_SPEED,}, + SPELLPOWER = { order = 7,type = "toggle",name = STAT_SPELLPOWER,}, + ENERGY_REGEN = { order = 8,type = "toggle",name = STAT_ENERGY_REGEN,}, + RUNE_REGEN = { order = 9,type = "toggle",name = STAT_RUNE_REGEN,}, + FOCUS_REGEN = { order = 10,type = "toggle",name = STAT_FOCUS_REGEN,}, + MOVESPEED = { order = 11,type = "toggle",name = STAT_SPEED,}, + }, + }, + }, + }, Backdrop = { type = 'group', name = L["Backdrop"],