local SLE, _, E = unpack(select(2, ...)) local Armory = SLE.Armory_Core local SA = SLE.Armory_Stats local M = E.Misc local _G = _G local math_min = math.min local format = format local GetAverageItemLevel = GetAverageItemLevel SA.totalShown = 0 SA.OriginalPaperdollStats = PAPERDOLL_STATCATEGORIES function SA:BuildNewStats() SA:CreateStatCategory('OffenseCategory', STAT_CATEGORY_ATTACK) SA:CreateStatCategory('DefenceCategory', DEFENSE) SA.AlteredPaperdollStats = { [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 = 'HEALTH', option = true }, [6] = { stat = 'POWER', option = true }, [7] = { stat = 'ALTERNATEMANA', option = true, classes = {'PRIEST', 'SHAMAN', 'DRUID'} }, [8] = { stat = 'MOVESPEED', option = true }, }, }, [2] = { categoryFrame = 'OffenseCategory', stats = { [1] = { stat = 'ATTACK_DAMAGE', option = true, hideAt = 0 }, [2] = { stat = 'ATTACK_AP', option = true, hideAt = 0 }, [3] = { stat = 'ATTACK_ATTACKSPEED', option = true, hideAt = 0 }, [4] = { stat = 'SPELLPOWER', option = true, hideAt = 0 }, [5] = { stat = 'MANAREGEN', option = true, power = 'MANA' }, [6] = { stat = 'ENERGY_REGEN', option = true, power = 'ENERGY', hideAt = 0, roles = {'TANK', 'DAMAGER'}, classes = {'ROUGE', 'DRUID', 'MONK'} }, [7] = { stat = 'FOCUS_REGEN', option = true, power = 'FOCUS', hideAt = 0, classes = {'HUNTER'} }, [8] = { stat = 'RUNE_REGEN', option = true, power = 'RUNIC_POWER', hideAt = 0, classes = {'DEATHKNIGHT'} }, }, }, [3] = { categoryFrame = 'EnhancementsCategory', stats = { [1] = { stat = 'CRITCHANCE', option = true, hideAt = 0 }, [2] = { stat = 'HASTE', option = true, hideAt = 0 }, [3] = { stat = 'MASTERY', option = true, hideAt = 0 }, [4] = { stat = 'VERSATILITY', option = true, hideAt = 0 }, [5] = { stat = 'LIFESTEAL', option = true, hideAt = 0 }, }, }, [4] = { categoryFrame = 'DefenceCategory', stats = { [1] = { stat = 'ARMOR', option = true, }, [2] = { stat = 'AVOIDANCE', option = true, hideAt = 0 }, [3] = { stat = 'DODGE', option = true,}, [4] = { stat = 'PARRY', option = true, hideAt = 0, }, [5] = { stat = 'BLOCK', option = true, hideAt = 0, }, [6] = { stat = 'STAGGER', hideAt = 0, roles = {'TANK'}, classes = {'MONK'} }, }, }, } end function SA:CreateStatCategory(catName, text, noop) if not _G['CharacterStatsPane'][catName] then _G['CharacterStatsPane'][catName] = CreateFrame('Frame', nil, _G.CharacterStatsPane, 'CharacterStatFrameCategoryTemplate') _G['CharacterStatsPane'][catName].Title:SetText(text) _G['CharacterStatsPane'][catName]:StripTextures() _G['CharacterStatsPane'][catName]:CreateBackdrop('Transparent') _G['CharacterStatsPane'][catName].backdrop:ClearAllPoints() _G['CharacterStatsPane'][catName].backdrop:SetPoint('CENTER') _G['CharacterStatsPane'][catName].backdrop:SetWidth(150) _G['CharacterStatsPane'][catName].backdrop:SetHeight(18) end return catName end function SA:BuildScrollBar() --Creating new scroll --Scrollframe Parent Frame SA.ScrollframeParentFrame = CreateFrame('Frame', nil, _G.CharacterFrameInsetRight) SA.ScrollframeParentFrame:SetSize(198, 352) SA.ScrollframeParentFrame:SetPoint('TOP', _G.CharacterFrameInsetRight, 'TOP', 0, -4) --Scrollframe SA.ScrollFrame = CreateFrame('ScrollFrame', 'SLE_Armory_Scroll', SA.ScrollframeParentFrame) SA.ScrollFrame:SetPoint('TOP') SA.ScrollFrame:SetSize(SA.ScrollframeParentFrame:GetSize()) --Scrollbar SA.Scrollbar = CreateFrame('Slider', nil, SA.ScrollFrame, 'UIPanelScrollBarTemplate') SA.Scrollbar:SetPoint('TOPLEFT', _G.CharacterFrameInsetRight, 'TOPRIGHT', -12, -20) SA.Scrollbar:SetPoint('BOTTOMLEFT', _G.CharacterFrameInsetRight, 'BOTTOMRIGHT', -12, 18) SA.Scrollbar:SetMinMaxValues(1, 2) SA.Scrollbar:SetValueStep(1) SA.Scrollbar.scrollStep = 1 SA.Scrollbar:SetValue(0) SA.Scrollbar:SetWidth(8) SA.Scrollbar:SetScript('OnValueChanged', function(frame, value) local offset = value > 1 and frame:GetParent():GetVerticalScrollRange()/(SA.totalShown*Armory.Constants.Stats.ScrollStepMultiplier) or 1 frame:GetParent():SetVerticalScroll(value*offset) end) E.Skins:HandleScrollBar(SA.Scrollbar) SA.Scrollbar:Hide() --SA.ScrollChild Frame SA.ScrollChild = CreateFrame('Frame', nil, SA.ScrollFrame) SA.ScrollChild:SetSize(SA.ScrollFrame:GetSize()) SA.ScrollFrame:SetScrollChild(SA.ScrollChild) CharacterStatsPane:ClearAllPoints() CharacterStatsPane:SetParent(SA.ScrollChild) CharacterStatsPane:SetSize(SA.ScrollChild:GetSize()) CharacterStatsPane:SetPoint('TOP', SA.ScrollChild, 'TOP', 0, 0) CharacterStatsPane.ClassBackground:ClearAllPoints() CharacterStatsPane.ClassBackground:SetParent( _G["CharacterFrameInsetRight"]) CharacterStatsPane.ClassBackground:SetPoint("CENTER") -- Enable mousewheel scrolling SA.ScrollFrame:EnableMouseWheel(true) SA.ScrollFrame:SetScript('OnMouseWheel', function(_, delta) local cur_val = SA.Scrollbar:GetValue() SA.Scrollbar:SetValue(cur_val - delta*SA.totalShown) --This controls the speed of the scroll end) PaperDollSidebarTab1:HookScript('OnShow', function() SA.ScrollframeParentFrame:Show() end) PaperDollSidebarTab1:HookScript('OnClick', function() SA.ScrollframeParentFrame:Show() end) PaperDollSidebarTab2:HookScript('OnClick', function() SA.ScrollframeParentFrame:Hide() end) PaperDollSidebarTab3:HookScript('OnClick', function() SA.ScrollframeParentFrame:Hide() end) end function SA:UpdateCharacterItemLevel(frame, which) if not frame or which ~= 'Character' then return end SA:UpdateIlvlFont() if not E.db.sle.armory.stats.enable or not E.db.general.itemLevel.displayCharacterInfo then return end local total, equipped = GetAverageItemLevel() if E.db.sle.armory.stats.IlvlFull then if E.db.sle.armory.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.stats.AverageColor frame.ItemLevelText:SetFormattedText('%s%.2f|r |cffffffff/|r %s%.2f|r', E:RGBToHex(r, g, b), equipped, E:RGBToHex(avColor.r, avColor.g, avColor.b), total) else frame.ItemLevelText:SetFormattedText('%.2f / %.2f', equipped, total) end end end function SA:PaperDollFrame_UpdateStats() SA.totalShown = 0 local categoryYOffset local statYOffset if E.db.sle.armory.stats.enable then local total, equipped = GetAverageItemLevel() if E.db.sle.armory.stats.IlvlFull then if E.db.sle.armory.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.stats.AverageColor _G.CharacterStatsPane.ItemLevelFrame.Value:SetFormattedText('%s%.2f|r |cffffffff/|r %s%.2f|r', E:RGBToHex(r, g, b), equipped, E:RGBToHex(avColor.r, avColor.g, avColor.b), total) else _G.CharacterStatsPane.ItemLevelFrame.Value:SetFormattedText('%.2f / %.2f', equipped, total) end else _G.CharacterStatsPane.ItemLevelFrame.Value:SetTextColor(GetItemLevelColor()) PaperDollFrame_SetItemLevel(_G.CharacterStatsPane.ItemLevelFrame, 'player') end _G.CharacterStatsPane.ItemLevelCategory:SetPoint('TOP', _G.CharacterStatsPane, 'TOP', 0, 8) _G.CharacterStatsPane.AttributesCategory:SetPoint('TOP', _G.CharacterStatsPane.ItemLevelFrame, 'BOTTOM', 0, 6) categoryYOffset = 8 statYOffset = 0 end _G.CharacterStatsPane.ItemLevelCategory:Show() _G.CharacterStatsPane.ItemLevelCategory.Title:FontTemplate(E.LSM:Fetch('font', E.db.sle.armory.stats.enable and E.db.sle.armory.stats.catFonts.font or E.db.general.itemLevel.itemLevelFont), E.db.sle.armory.stats.enable and E.db.sle.armory.stats.catFonts.size or (E.db.general.itemLevel.itemLevelFontSize or 12), E.db.sle.armory.stats.enable and E.db.sle.armory.stats.catFonts.outline or NONE) _G.CharacterStatsPane.ItemLevelFrame:Show() local spec = GetSpecialization() local role = GetSpecializationRole(spec) local _, powerType = UnitPowerType('player') -- print(GetSpecializationInfo(spec)) _G.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 = _G.CharacterStatsPane.statsFramePool:Acquire() local lastAnchor for catIndex = 1, #PAPERDOLL_STATCATEGORIES do local catFrame = _G['CharacterStatsPane'][PAPERDOLL_STATCATEGORIES[catIndex].categoryFrame] catFrame.Title:FontTemplate(E.LSM:Fetch('font', E.db.sle.armory.stats.enable and E.db.sle.armory.stats.catFonts.font or E.db.general.itemLevel.itemLevelFont), E.db.sle.armory.stats.enable and E.db.sle.armory.stats.catFonts.size or (E.db.general.itemLevel.itemLevelFontSize or 12), E.db.sle.armory.stats.enable and E.db.sle.armory.stats.catFonts.outline or NONE) local numStatInCat = 0 for statIndex = 1, #PAPERDOLL_STATCATEGORIES[catIndex].stats do local stat = PAPERDOLL_STATCATEGORIES[catIndex].stats[statIndex] local showStat = true if E.db.sle.armory.stats.enable and stat.option and not E.db.sle.armory.stats.List[stat.stat] then showStat = false end if ( showStat and stat.primary ) then local primaryStat = select(6, GetSpecializationInfo(spec, nil, nil, nil, UnitSex('player'))) if ( stat.primary ~= primaryStat ) and E.db.sle.armory.stats.OnlyPrimary then showStat = false end end if ( showStat and stat.roles ) then local foundRole = false for _, statRole in pairs(stat.roles) do if ( role == statRole ) then foundRole = true break end end if foundRole and stat.classes then for _, statClass in pairs(stat.classes) do if ( E.myclass == statClass ) then showStat = true break end end else showStat = foundRole end end if showStat and stat.power and stat.power ~= powerType then showStat = false end if ( showStat ) then statFrame.onEnterFunc = nil PAPERDOLL_STATINFO[stat.stat].updateFunc(statFrame, 'player') statFrame.Label:FontTemplate(E.LSM:Fetch('font', E.db.sle.armory.stats.enable and E.db.sle.armory.stats.statFonts.font or E.db.sle.armory.stats.statFonts.font), E.db.sle.armory.stats.enable and E.db.sle.armory.stats.statFonts.size or (E.db.general.itemLevel.itemLevelFontSize or 12), E.db.sle.armory.stats.enable and E.db.sle.armory.stats.statFonts.outline or NONE) statFrame.Value:FontTemplate(E.LSM:Fetch('font', E.db.sle.armory.stats.enable and E.db.sle.armory.stats.statFonts.font or E.db.sle.armory.stats.statFonts.font), E.db.sle.armory.stats.enable and E.db.sle.armory.stats.statFonts.size or (E.db.general.itemLevel.itemLevelFontSize or 12), E.db.sle.armory.stats.enable and E.db.sle.armory.stats.statFonts.outline or NONE) 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 SA.totalShown = SA.totalShown + 1 numStatInCat = numStatInCat + 1 -- statFrame.Background:SetShown((numStatInCat % 2) == 0) statFrame.Background:SetShown(false) if statFrame.leftGrad then statFrame.leftGrad:Hide() end if statFrame.rightGrad then statFrame.rightGrad:Hide() end lastAnchor = statFrame end -- done with this stat frame, get the next one statFrame = _G.CharacterStatsPane.statsFramePool:Acquire() end end end catFrame:SetShown(numStatInCat > 0) end -- release the current stat frame _G.CharacterStatsPane.statsFramePool:Release(statFrame) if SA.Scrollbar then if SA.totalShown > 12 then SA.Scrollbar:SetMinMaxValues(1, SA.totalShown*Armory.Constants.Stats.ScrollStepMultiplier) SA.Scrollbar:Show() else SA.Scrollbar:SetMinMaxValues(1, 1) SA.Scrollbar:Hide() end SA.Scrollbar:SetValue(SA.Scrollbar:GetValue()) end end function SA:UpdateIlvlFont() local db = E.db.sle.armory.stats.itemLevel local font, size, outline font = E.db.sle.armory.stats.enable and E.LSM:Fetch('font', db.font) or nil size = E.db.sle.armory.stats.enable and (db.size or 12) or 20 outline = E.db.sle.armory.stats.enable and db.outline or nil _G.CharacterFrame.ItemLevelText:FontTemplate(font, size, outline) _G.CharacterStatsPane.ItemLevelFrame.Value:FontTemplate(font, size, outline) _G.CharacterStatsPane.ItemLevelFrame:SetHeight(size) _G.CharacterStatsPane.ItemLevelFrame.Background:SetHeight(size) if _G.CharacterStatsPane.ItemLevelFrame.leftGrad then _G.CharacterStatsPane.ItemLevelFrame.leftGrad:SetHeight(size) _G.CharacterStatsPane.ItemLevelFrame.rightGrad:SetHeight(size) end if not E.db.general.itemLevel.displayCharacterInfo then _G.CharacterFrame.ItemLevelText:SetText('') end end function SA:ToggleArmory() PAPERDOLL_STATCATEGORIES = E.db.sle.armory.stats.enable and SA.AlteredPaperdollStats or SA.OriginalPaperdollStats if E.db.sle.armory.stats.enable then _G['CharacterStatsPane']['OffenseCategory']:Show() _G['CharacterStatsPane']['DefenceCategory']:Show() _G.CharacterStatsPane.ItemLevelFrame:SetPoint('TOP', _G.CharacterStatsPane.ItemLevelCategory, 'BOTTOM', 0, 6) _G.CharacterFrame.ItemLevelText:SetText('') -- SA:ToggleDecimals("enable") else _G['CharacterStatsPane']['OffenseCategory']:Hide() _G['CharacterStatsPane']['DefenceCategory']:Hide() _G.CharacterStatsPane.ItemLevelFrame:SetPoint('TOP', _G.CharacterStatsPane.ItemLevelCategory, 'BOTTOM', 0, 0) -- SA:ToggleDecimals("disable") SA.Scrollbar:Hide() end PaperDollFrame_UpdateStats() M:UpdateCharacterItemLevel() if not E.db.general.itemLevel.displayCharacterInfo then _G.CharacterFrame.ItemLevelText:SetText('') end end --Replacing broken Blizz function and adding some decimals function SA:ReplaceBlizzFunctions() function PaperDollFrame_SetAttackSpeed(statFrame, unit) local meleeHaste = GetMeleeHaste() local speed, offhandSpeed = UnitAttackSpeed(unit) local displaySpeedxt 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_SetVersatility(statFrame, unit) if ( unit ~= 'player' ) then statFrame:Hide() return end local versatility = GetCombatRating(CR_VERSATILITY_DAMAGE_DONE) local versatilityDamageBonus = GetCombatRatingBonus(CR_VERSATILITY_DAMAGE_DONE) + GetVersatilityBonus(CR_VERSATILITY_DAMAGE_DONE) local versatilityDamageTakenReduction = GetCombatRatingBonus(CR_VERSATILITY_DAMAGE_TAKEN) + GetVersatilityBonus(CR_VERSATILITY_DAMAGE_TAKEN) if E.db.sle.armory.stats.decimals then --Alters format PaperDollFrame_SetLabelAndText(statFrame, STAT_VERSATILITY, format('%.2f%%', versatilityDamageBonus) .. ' / ' .. format('%.2f%%', versatilityDamageTakenReduction), false, versatilityDamageBonus) else PaperDollFrame_SetLabelAndText(statFrame, STAT_VERSATILITY, versatilityDamageBonus, true, versatilityDamageBonus) end statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE .. format(VERSATILITY_TOOLTIP_FORMAT, STAT_VERSATILITY, versatilityDamageBonus, versatilityDamageTakenReduction) .. FONT_COLOR_CODE_CLOSE statFrame.tooltip2 = format(CR_VERSATILITY_TOOLTIP, versatilityDamageBonus, versatilityDamageTakenReduction, BreakUpLargeNumbers(versatility), versatilityDamageBonus, versatilityDamageTakenReduction) statFrame:Show() end function PaperDollFrame_SetMastery(statFrame, unit) if ( unit ~= 'player' ) then statFrame:Hide() return end local mastery = GetMasteryEffect() if E.db.sle.armory.stats.decimals then PaperDollFrame_SetLabelAndText(statFrame, STAT_MASTERY, format('%.2f%%', mastery), false, mastery) else PaperDollFrame_SetLabelAndText(statFrame, STAT_MASTERY, mastery, true, mastery) end statFrame.onEnterFunc = Mastery_OnEnter statFrame:Show() end function PaperDollFrame_SetLifesteal(statFrame, unit) if ( unit ~= 'player' ) then statFrame:Hide() return end local lifesteal = GetLifesteal() if E.db.sle.armory.stats.decimals then PaperDollFrame_SetLabelAndText(statFrame, STAT_LIFESTEAL, format('%.2f%%', lifesteal), false, lifesteal) else PaperDollFrame_SetLabelAndText(statFrame, STAT_LIFESTEAL, lifesteal, true, lifesteal) end statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE .. format(PAPERDOLLFRAME_TOOLTIP_FORMAT, STAT_LIFESTEAL) .. ' ' .. format('%.2f%%', lifesteal) .. FONT_COLOR_CODE_CLOSE statFrame.tooltip2 = format(CR_LIFESTEAL_TOOLTIP, BreakUpLargeNumbers(GetCombatRating(CR_LIFESTEAL)), GetCombatRatingBonus(CR_LIFESTEAL)) statFrame:Show() end function PaperDollFrame_SetAvoidance(statFrame, unit) if ( unit ~= 'player' ) then statFrame:Hide() return end local avoidance = GetAvoidance() -- PaperDollFrame_SetLabelAndText Format Change if E.db.sle.armory.stats.decimals then PaperDollFrame_SetLabelAndText(statFrame, STAT_AVOIDANCE, format('%.2f%%', avoidance), false, avoidance) else PaperDollFrame_SetLabelAndText(statFrame, STAT_AVOIDANCE, avoidance, true, avoidance) end statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE .. format(PAPERDOLLFRAME_TOOLTIP_FORMAT, STAT_AVOIDANCE) .. ' ' .. format('%.2f%%', avoidance) .. FONT_COLOR_CODE_CLOSE statFrame.tooltip2 = format(CR_AVOIDANCE_TOOLTIP, BreakUpLargeNumbers(GetCombatRating(CR_AVOIDANCE)), GetCombatRatingBonus(CR_AVOIDANCE)) statFrame:Show() end function PaperDollFrame_SetDodge(statFrame, unit) if (unit ~= 'player') then statFrame:Hide() return end local chance = GetDodgeChance() -- PaperDollFrame_SetLabelAndText Format Change if E.db.sle.armory.stats.decimals then PaperDollFrame_SetLabelAndText(statFrame, STAT_DODGE, format('%.2f%%', chance), false, chance) else PaperDollFrame_SetLabelAndText(statFrame, STAT_DODGE, chance, true, chance) end statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, DODGE_CHANCE)..' '..format('%.2f', chance)..'%'..FONT_COLOR_CODE_CLOSE statFrame.tooltip2 = format(CR_DODGE_TOOLTIP, GetCombatRating(CR_DODGE), GetCombatRatingBonus(CR_DODGE)) statFrame:Show() end function PaperDollFrame_SetParry(statFrame, unit) if (unit ~= 'player') then statFrame:Hide() return end local chance = GetParryChance() -- PaperDollFrame_SetLabelAndText Format Change if E.db.sle.armory.stats.decimals then PaperDollFrame_SetLabelAndText(statFrame, STAT_PARRY, format('%.2f%%', chance), false, chance) else PaperDollFrame_SetLabelAndText(statFrame, STAT_PARRY, chance, true, chance) end statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, PARRY_CHANCE)..' '..format('%.2f', chance)..'%'..FONT_COLOR_CODE_CLOSE statFrame.tooltip2 = format(CR_PARRY_TOOLTIP, GetCombatRating(CR_PARRY), GetCombatRatingBonus(CR_PARRY)) statFrame:Show() end function PaperDollFrame_SetCritChance(statFrame, unit) if ( unit ~= 'player' ) then statFrame:Hide() return end local rating local spellCrit, rangedCrit, meleeCrit local critChance -- Start at 2 to skip physical damage local holySchool = 2 local minCrit = GetSpellCritChance(holySchool) statFrame.spellCrit = {} statFrame.spellCrit[holySchool] = minCrit for i=(holySchool+1), MAX_SPELL_SCHOOLS do spellCrit = GetSpellCritChance(i) minCrit = math_min(minCrit, spellCrit) statFrame.spellCrit[i] = spellCrit end spellCrit = minCrit rangedCrit = GetRangedCritChance() meleeCrit = GetCritChance() if (spellCrit >= rangedCrit and spellCrit >= meleeCrit) then critChance = spellCrit rating = CR_CRIT_SPELL elseif (rangedCrit >= meleeCrit) then critChance = rangedCrit rating = CR_CRIT_RANGED else critChance = meleeCrit rating = CR_CRIT_MELEE end -- PaperDollFrame_SetLabelAndText Format Change if E.db.sle.armory.stats.decimals then PaperDollFrame_SetLabelAndText(statFrame, STAT_CRITICAL_STRIKE, format('%.2f%%', critChance), false, critChance) else PaperDollFrame_SetLabelAndText(statFrame, STAT_CRITICAL_STRIKE, critChance, true, critChance) end statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, STAT_CRITICAL_STRIKE)..' '..format('%.2f%%', critChance)..FONT_COLOR_CODE_CLOSE local extraCritChance = GetCombatRatingBonus(rating) local extraCritRating = GetCombatRating(rating) if (GetCritChanceProvidesParryEffect()) then statFrame.tooltip2 = format(CR_CRIT_PARRY_RATING_TOOLTIP, BreakUpLargeNumbers(extraCritRating), extraCritChance, GetCombatRatingBonusForCombatRatingValue(CR_PARRY, extraCritRating)) else statFrame.tooltip2 = format(CR_CRIT_TOOLTIP, BreakUpLargeNumbers(extraCritRating), extraCritChance) end statFrame:Show() end function PaperDollFrame_SetHaste(statFrame, unit) if ( unit ~= 'player' ) then statFrame:Hide() return end local haste = GetHaste() local rating = CR_HASTE_MELEE local hasteFormatString if (haste < 0) then hasteFormatString = RED_FONT_COLOR_CODE..'%s'..FONT_COLOR_CODE_CLOSE else hasteFormatString = '%s' end -- PaperDollFrame_SetLabelAndText Format Change if E.db.sle.armory.stats.decimals then PaperDollFrame_SetLabelAndText(statFrame, STAT_HASTE, format(hasteFormatString, format('%.2f%%', haste)), false, haste) else PaperDollFrame_SetLabelAndText(statFrame, STAT_HASTE, format(hasteFormatString, format('%d%%', haste + 0.5)), false, haste) end statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE .. format(PAPERDOLLFRAME_TOOLTIP_FORMAT, STAT_HASTE) .. ' ' .. format(hasteFormatString, format('%.2f%%', haste)) .. FONT_COLOR_CODE_CLOSE local _, class = UnitClass(unit) statFrame.tooltip2 = _G['STAT_HASTE_'..class..'_TOOLTIP'] if (not statFrame.tooltip2) then statFrame.tooltip2 = STAT_HASTE_TOOLTIP end statFrame.tooltip2 = statFrame.tooltip2 .. format(STAT_HASTE_BASE_TOOLTIP, BreakUpLargeNumbers(GetCombatRating(rating)), GetCombatRatingBonus(rating)) statFrame:Show() end end function SA:LoadAndSetup() if SLE._Compatibility['DejaCharacterStats'] then return end SA:ReplaceBlizzFunctions() hooksecurefunc('PaperDollFrame_UpdateStats', SA.PaperDollFrame_UpdateStats) hooksecurefunc(M, 'UpdateCharacterItemLevel', SA.UpdateCharacterItemLevel) hooksecurefunc(M, 'ToggleItemLevelInfo', SA.UpdateCharacterItemLevel) hooksecurefunc(M, 'UpdateAverageString', SA.UpdateCharacterItemLevel) SA:BuildScrollBar() SA:BuildNewStats() SA:ToggleArmory() _G.CharacterFrame:HookScript('OnShow', SA.UpdateCharacterItemLevel) _G.CharacterFrame.ItemLevelText:SetText('') end