local E, L, V, P, G = unpack(ElvUI) local module = E:NewModule("Enhanced_CharacterFrame", "AceHook-3.0", "AceEvent-3.0") local S = E:GetModule("Skins") local _G = _G local select, next, ipairs, pairs, tonumber, getmetatable = select, next, ipairs, pairs, tonumber, getmetatable local abs, floor, max, min = math.abs, math.floor, math.max, math.min local find, format, gmatch, lower, sub, trim = string.find, string.format, string.gmatch, string.lower, string.sub, string.trim local tconcat, tinsert, tremove, sort, wipe = table.concat, table.insert, table.remove, table.sort, table.wipe local CreateFrame = CreateFrame local GetActiveTalentGroup = GetActiveTalentGroup local GetAttackPowerForStat = GetAttackPowerForStat local GetBlockChance = GetBlockChance local GetCombatRating = GetCombatRating local GetCombatRatingBonus = GetCombatRatingBonus local GetCompanionCooldown = GetCompanionCooldown local GetCompanionInfo = GetCompanionInfo local GetCritChance = GetCritChance local GetCritChanceFromAgility = GetCritChanceFromAgility local GetCurrentTitle = GetCurrentTitle local GetCursorPosition = GetCursorPosition local GetDodgeChance = GetDodgeChance local GetEquipmentSetInfo = GetEquipmentSetInfo local GetEquipmentSetInfoByName = GetEquipmentSetInfoByName local GetInventoryItemLink = GetInventoryItemLink local GetItemInfo = GetItemInfo local GetMaxCombatRatingBonus = GetMaxCombatRatingBonus local GetNumCompanions = GetNumCompanions local GetNumEquipmentSets = GetNumEquipmentSets local GetNumTitles = GetNumTitles local GetParryChance = GetParryChance local GetScreenHeightScale = GetScreenHeightScale local GetShieldBlock = GetShieldBlock local GetSpellCritChanceFromIntellect = GetSpellCritChanceFromIntellect local GetTitleName = GetTitleName local GetUnitHealthModifier = GetUnitHealthModifier local GetUnitHealthRegenRateFromSpirit = GetUnitHealthRegenRateFromSpirit local GetUnitManaRegenRateFromSpirit = GetUnitManaRegenRateFromSpirit local GetUnitMaxHealthModifier = GetUnitMaxHealthModifier local GetUnitPowerModifier = GetUnitPowerModifier local HasPetUI = HasPetUI local IsTitleKnown = IsTitleKnown local PlaySound = PlaySound local SetPortraitTexture = SetPortraitTexture local UnitAttackSpeed = UnitAttackSpeed local UnitClass = UnitClass local UnitDamage = UnitDamage local UnitHasMana = UnitHasMana local UnitHasRelicSlot = UnitHasRelicSlot local UnitLevel = UnitLevel local UnitRace = UnitRace local UnitResistance = UnitResistance local UnitStat = UnitStat local CharacterRangedDamageFrame_OnEnter = CharacterRangedDamageFrame_OnEnter local CharacterSpellCritChance_OnEnter = CharacterSpellCritChance_OnEnter local CooldownFrame_SetTimer = CooldownFrame_SetTimer local GameTooltip_Hide = GameTooltip_Hide local GearManagerDialogSaveSet_OnClick = GearManagerDialogSaveSet_OnClick local PaperDollFrameItemPopoutButton_HideAll = PaperDollFrameItemPopoutButton_HideAll local PaperDollFrameItemPopoutButton_ShowAll = PaperDollFrameItemPopoutButton_ShowAll local PaperDollFrame_ClearIgnoredSlots = PaperDollFrame_ClearIgnoredSlots local PaperDollFrame_SetArmor = PaperDollFrame_SetArmor local PaperDollFrame_SetAttackPower = PaperDollFrame_SetAttackPower local PaperDollFrame_SetAttackSpeed = PaperDollFrame_SetAttackSpeed local PaperDollFrame_SetDamage = PaperDollFrame_SetDamage local PaperDollFrame_SetDefense = PaperDollFrame_SetDefense local PaperDollFrame_SetExpertise = PaperDollFrame_SetExpertise local PaperDollFrame_SetManaRegen = PaperDollFrame_SetManaRegen local PaperDollFrame_SetRangedAttackPower = PaperDollFrame_SetRangedAttackPower local PaperDollFrame_SetRangedAttackSpeed = PaperDollFrame_SetRangedAttackSpeed local PaperDollFrame_SetRangedCritChance = PaperDollFrame_SetRangedCritChance local PaperDollFrame_SetRangedDamage = PaperDollFrame_SetRangedDamage local PaperDollFrame_SetRating = PaperDollFrame_SetRating local PaperDollFrame_SetSpellBonusDamage = PaperDollFrame_SetSpellBonusDamage local PaperDollFrame_SetSpellBonusHealing = PaperDollFrame_SetSpellBonusHealing local PaperDollFrame_SetSpellCritChance = PaperDollFrame_SetSpellCritChance local PaperDollFrame_SetSpellHaste = PaperDollFrame_SetSpellHaste local PetPaperDollFrameCompanionFrame = PetPaperDollFrameCompanionFrame local PetPaperDollFrame_FindCompanionIndex = PetPaperDollFrame_FindCompanionIndex local GearManagerDialog = GearManagerDialog local ARMOR_PER_AGILITY = ARMOR_PER_AGILITY local BLOCK_CHANCE = BLOCK_CHANCE local BLOCK_PER_STRENGTH = BLOCK_PER_STRENGTH local CR_BLOCK = CR_BLOCK local CR_BLOCK_TOOLTIP = CR_BLOCK_TOOLTIP local CR_CRIT_MELEE = CR_CRIT_MELEE local CR_CRIT_MELEE_TOOLTIP = CR_CRIT_MELEE_TOOLTIP local CR_CRIT_TAKEN_MELEE = CR_CRIT_TAKEN_MELEE local CR_CRIT_TAKEN_RANGED = CR_CRIT_TAKEN_RANGED local CR_CRIT_TAKEN_SPELL = CR_CRIT_TAKEN_SPELL local CR_DODGE = CR_DODGE local CR_DODGE_TOOLTIP = CR_DODGE_TOOLTIP local CR_HIT_MELEE = CR_HIT_MELEE local CR_HIT_RANGED = CR_HIT_RANGED local CR_HIT_SPELL = CR_HIT_SPELL local CR_PARRY = CR_PARRY local CR_PARRY_TOOLTIP = CR_PARRY_TOOLTIP local DAMAGE_PER_SECOND = DAMAGE_PER_SECOND local DEFENSE = DEFENSE local DODGE_CHANCE = DODGE_CHANCE local FONT_COLOR_CODE_CLOSE = FONT_COLOR_CODE_CLOSE local GREEN_FONT_COLOR = GREEN_FONT_COLOR local GREEN_FONT_COLOR_CODE = GREEN_FONT_COLOR_CODE local HEALTH_PER_STAMINA = HEALTH_PER_STAMINA local HIGHLIGHT_FONT_COLOR_CODE = HIGHLIGHT_FONT_COLOR_CODE local INVSLOT_BODY = INVSLOT_BODY local INVSLOT_RANGED = INVSLOT_RANGED local INVSLOT_MAINHAND = INVSLOT_MAINHAND local MANA_PER_INTELLECT = MANA_PER_INTELLECT local MANA_REGEN_FROM_SPIRIT = MANA_REGEN_FROM_SPIRIT local MAX_EQUIPMENT_SETS_PER_PLAYER = MAX_EQUIPMENT_SETS_PER_PLAYER local MELEE_CRIT_CHANCE = MELEE_CRIT_CHANCE local NONE = NONE local NORMAL_FONT_COLOR = NORMAL_FONT_COLOR local PAPERDOLLFRAME_TOOLTIP_FORMAT = PAPERDOLLFRAME_TOOLTIP_FORMAT local PARRY_CHANCE = PARRY_CHANCE local PET_BONUS_TOOLTIP_INTELLECT = PET_BONUS_TOOLTIP_INTELLECT local PET_BONUS_TOOLTIP_RESISTANCE = PET_BONUS_TOOLTIP_RESISTANCE local PET_BONUS_TOOLTIP_STAMINA = PET_BONUS_TOOLTIP_STAMINA local RAID_CLASS_COLORS = RAID_CLASS_COLORS local RED_FONT_COLOR_CODE = RED_FONT_COLOR_CODE local RESILIENCE_CRIT_CHANCE_TO_CONSTANT_DAMAGE_REDUCTION_MULTIPLIER = RESILIENCE_CRIT_CHANCE_TO_CONSTANT_DAMAGE_REDUCTION_MULTIPLIER local RESILIENCE_CRIT_CHANCE_TO_DAMAGE_REDUCTION_MULTIPLIER = RESILIENCE_CRIT_CHANCE_TO_DAMAGE_REDUCTION_MULTIPLIER local RESILIENCE_TOOLTIP = RESILIENCE_TOOLTIP local RESISTANCE_EXCELLENT = RESISTANCE_EXCELLENT local RESISTANCE_FAIR = RESISTANCE_FAIR local RESISTANCE_GOOD = RESISTANCE_GOOD local RESISTANCE_NONE = RESISTANCE_NONE local RESISTANCE_POOR = RESISTANCE_POOR local RESISTANCE_TOOLTIP_SUBTEXT = RESISTANCE_TOOLTIP_SUBTEXT local RESISTANCE_VERYGOOD = RESISTANCE_VERYGOOD local STAT_ATTACK_POWER = STAT_ATTACK_POWER local STAT_BLOCK = STAT_BLOCK local STAT_BLOCK_TOOLTIP = STAT_BLOCK_TOOLTIP local STAT_DODGE = STAT_DODGE local STAT_FORMAT = STAT_FORMAT local STAT_PARRY = STAT_PARRY local STAT_RESILIENCE = STAT_RESILIENCE -- GLOBALS: CharacterAmmoSlot, CharacterAttributesFrame, CharacterDamageFrame_OnEnter, CharacterFrame, CharacterFrameCloseButton, CharacterFrameExpandButton, CharacterFrameTab2 -- GLOBALS: CharacterLevelText, CharacterMicroButton, CharacterModelFrame, CharacterNameFrame, CharacterNameText, CharacterResistanceFrame, CharacterSpellBonusDamage_OnEnter -- GLOBALS: CharacterStatsPane, CharacterStatsPaneScrollBar, CharacterStatsPaneScrollBarScrollDownButton, CharacterStatsPaneScrollBarScrollUpButton, CharacterStatsPaneScrollChild -- GLOBALS: CompanionModelFrame, CompanionModelFrameRotateLeftButton, CompanionNextPageButton, CompanionPageNumber, CompanionPrevPageButton, CompanionSelectedName -- GLOBALS: CompanionSummonButton, ComputePetBonus, CreateAnimationGroup, EquipmentManager_EquipSet, GS_Data, GameTooltip, GearManagerDialogPopup, GearManagerToggleButton -- GLOBALS: GearScore2, GearScore_GetQuality, GearScore_GetScore, HybridScrollFrame_CreateButtons, HybridScrollFrame_GetOffset, HybridScrollFrame_OnLoad, HybridScrollFrame_Update -- GLOBALS: InspectFrame, InspectModelFrame, PaperDollEquipmentManagerPane, PaperDollEquipmentManagerPaneEquipSet, PaperDollEquipmentManagerPaneSaveSet, PaperDollFormatStat -- GLOBALS: PaperDollFrame, PaperDollSidebarTab1, PaperDollSidebarTabs, PaperDollStatTooltip, PaperDollTitlesPane, PersonalGearScore, PetAttributesFrame, PetExpBar_Update -- GLOBALS: PetLevelText, PetModelFrame, PetModelFrameRotateLeftButton, PetNameText, PetPaperDollCloseButton, PetPaperDollCompanionPane, PetPaperDollFrame, PetPaperDollFrameExpBar -- GLOBALS: PetPaperDollFramePetFrame, PetPaperDollFrame_Update, PetPaperDollFrame_UpdateCompanionCooldowns, PetPaperDollFrame_UpdateTabs, PetResistanceFrame, PlayerTitleFrame -- GLOBALS: PlayerTitlePickerFrame, SetButtonPulse, SetCVar, StaticPopup_Hide, UIFrameFadeIn, UIFrameFadeOut, hooksecurefunc, table -- GLOBALS: EQUIPSET_EQUIP, SAVE local CHARACTERFRAME_EXPANDED_WIDTH = 197 local STATCATEGORY_MOVING_INDENT = 4 local MOVING_STAT_CATEGORY local PAPERDOLL_SIDEBARS = { { name = L["Character Stats"], frame = "CharacterStatsPane", icon = nil, texCoords = {0.109375, 0.890625, 0.09375, 0.90625} }, { name = L["Titles"], frame = "PaperDollTitlesPane", icon = "Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\PaperDollSidebarTabs", texCoords = {0.01562500, 0.53125000, 0.32421875, 0.46093750} }, { name = L["Equipment Manager"], frame = "PaperDollEquipmentManagerPane", icon = "Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\PaperDollSidebarTabs", texCoords = {0.01562500, 0.53125000, 0.46875000, 0.60546875} }, { name = "Mystic Enchants", frame = "PaperDollMysticEnchantPane", icon = "Interface\\Icons\\inv_custom_ReforgeToken", texCoords = {0.1, 0.9, 0.1, 0.9} } } local PAPERDOLL_STATINFO = { ["ITEM_LEVEL"] = { updateFunc = function(statFrame, unit) module:ItemLevel(statFrame, unit) end }, ["PRIMARY_STAT"] = { updateFunc = function(statFrame, unit) module:PrimaryStat(statFrame, unit) end }, ["PVE_POWER"] = { updateFunc = function(statFrame, unit) module:PvEPower(statFrame, unit) end }, ["PVP_POWER"] = { updateFunc = function(statFrame, unit) module:PvPPower(statFrame, unit) end }, ["FEL_COMM"] = { updateFunc = function(statFrame, unit) module:FelComm(statFrame, unit) end }, ["STRENGTH"] = { updateFunc = function(statFrame, unit) module:SetStat(statFrame, unit, 1) end }, ["AGILITY"] = { updateFunc = function(statFrame, unit) module:SetStat(statFrame, unit, 2) end }, ["STAMINA"] = { updateFunc = function(statFrame, unit) module:SetStat(statFrame, unit, 3) end }, ["INTELLECT"] = { updateFunc = function(statFrame, unit) module:SetStat(statFrame, unit, 4) end }, ["SPIRIT"] = { updateFunc = function(statFrame, unit) module:SetStat(statFrame, unit, 5) end }, ["MELEE_DAMAGE"] = { updateFunc = function(statFrame, unit) PaperDollFrame_SetDamage(statFrame, unit) end, updateFunc2 = function(statFrame) CharacterDamageFrame_OnEnter(statFrame) end }, ["MELEE_DPS"] = { updateFunc = function(statFrame, unit) module:SetMeleeDPS(statFrame, unit) end }, ["MELEE_AP"] = { updateFunc = function(statFrame, unit) PaperDollFrame_SetAttackPower(statFrame, unit) end }, ["MELEE_ATTACKSPEED"] = { updateFunc = function(statFrame, unit) PaperDollFrame_SetAttackSpeed(statFrame, unit) end }, ["HITCHANCE"] = { updateFunc = function(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end PaperDollFrame_SetRating(statFrame, CR_HIT_MELEE) end }, ["CRITCHANCE"] = { updateFunc = function(statFrame, unit) module:SetMeleeCritChance(statFrame, unit) end }, ["EXPERTISE"] = { updateFunc = function(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end PaperDollFrame_SetExpertise(statFrame, unit) end }, ["RANGED_COMBAT1"] = { updateFunc = function(statFrame, unit) PaperDollFrame_SetRangedDamage(statFrame, unit) end, updateFunc2 = function(statFrame) CharacterRangedDamageFrame_OnEnter(statFrame) end }, ["RANGED_COMBAT2"] = { updateFunc = function(statFrame, unit) PaperDollFrame_SetRangedAttackSpeed(statFrame, unit) end }, ["RANGED_COMBAT3"] = { updateFunc = function(statFrame, unit) PaperDollFrame_SetRangedAttackPower(statFrame, unit) end }, ["RANGED_COMBAT4"] = { updateFunc = function(statFrame) PaperDollFrame_SetRating(statFrame, CR_HIT_RANGED) end }, ["RANGED_COMBAT5"] = { updateFunc = function(statFrame, unit) PaperDollFrame_SetRangedCritChance(statFrame, unit) end }, ["SPELL_COMBAT1"] = { updateFunc = function(statFrame, unit) PaperDollFrame_SetSpellBonusDamage(statFrame, unit) end, updateFunc2 = function(statFrame) CharacterSpellBonusDamage_OnEnter(statFrame) end }, ["SPELL_COMBAT2"] = { updateFunc = function(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end PaperDollFrame_SetSpellBonusHealing(statFrame, unit) end }, ["SPELL_COMBAT3"] = { updateFunc = function(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end PaperDollFrame_SetRating(statFrame, CR_HIT_SPELL) end }, ["SPELL_COMBAT4"] = { updateFunc = function(statFrame, unit) PaperDollFrame_SetSpellCritChance(statFrame, unit) end, updateFunc2 = function(statFrame) CharacterSpellCritChance_OnEnter(statFrame) end }, ["SPELL_COMBAT5"] = { updateFunc = function(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end PaperDollFrame_SetSpellHaste(statFrame, unit) end }, ["SPELL_COMBAT6"] = { updateFunc = function(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end PaperDollFrame_SetManaRegen(statFrame, unit) end }, ["DEFENSES1"] = { updateFunc = function(statFrame, unit) PaperDollFrame_SetArmor(statFrame, unit) end }, ["DEFENSES2"] = { updateFunc = function(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end PaperDollFrame_SetDefense(statFrame, unit) end }, ["DEFENSES3"] = { updateFunc = function(statFrame, unit) module:SetDodge(statFrame, unit) end }, ["DEFENSES4"] = { updateFunc = function(statFrame, unit) module:SetParry(statFrame, unit) end }, ["DEFENSES5"] = { updateFunc = function(statFrame, unit) module:SetBlock(statFrame, unit) end }, ["DEFENSES6"] = { updateFunc = function(statFrame, unit) module:SetResilience(statFrame, unit) end }, ["ARCANE"] = { updateFunc = function(statFrame, unit) module:SetResistance(statFrame, unit, 6) end }, ["FIRE"] = { updateFunc = function(statFrame, unit) module:SetResistance(statFrame, unit, 2) end }, ["FROST"] = { updateFunc = function(statFrame, unit) module:SetResistance(statFrame, unit, 4) end }, ["NATURE"] = { updateFunc = function(statFrame, unit) module:SetResistance(statFrame, unit, 3) end }, ["SHADOW"] = { updateFunc = function(statFrame, unit) module:SetResistance(statFrame, unit, 5) end } } local PAPERDOLL_STATCATEGORIES = { ["ITEM_LEVEL"] = { id = 1, stats = { "ITEM_LEVEL" } }, ["PRIMARY_STAT"] = { id = 2, stats = { "PRIMARY_STAT" } }, ["PVE_POWER"] = { id = 3, stats = { "PVE_POWER" } }, ["PVP_POWER"] = { id = 4, stats = { "PVP_POWER" } }, ["FEL_COMM"] = { id = 5, stats = { "FEL_COMM" } }, ["BASE_STATS"] = { id = 6, stats = { "STRENGTH", "AGILITY", "STAMINA", "INTELLECT", "SPIRIT" } }, ["MELEE_COMBAT"] = { id = 7, stats = { "MELEE_DAMAGE", "MELEE_DPS", "MELEE_AP", "MELEE_ATTACKSPEED", "HITCHANCE", "CRITCHANCE", "EXPERTISE" } }, ["RANGED_COMBAT"] = { id = 8, stats = { "RANGED_COMBAT1", "RANGED_COMBAT2", "RANGED_COMBAT3", "RANGED_COMBAT4", "RANGED_COMBAT5" } }, ["SPELL_COMBAT"] = { id = 9, stats = { "SPELL_COMBAT1", "SPELL_COMBAT2", "SPELL_COMBAT3", "SPELL_COMBAT4", "SPELL_COMBAT5", "SPELL_COMBAT6" } }, ["DEFENSES"] = { id = 10, stats = { "DEFENSES1", "DEFENSES2", "DEFENSES3", "DEFENSES4", "DEFENSES5", "DEFENSES6" } }, ["RESISTANCE"] = { id = 11, stats = { "ARCANE", "FIRE", "FROST", "NATURE", "SHADOW" } } } local PAPERDOLL_STATCATEGORY_DEFAULTORDER = { "ITEM_LEVEL", "PRIMARY_STAT", "PVE_POWER", "PVP_POWER", "FEL_COMM", "BASE_STATS", "MELEE_COMBAT", "RANGED_COMBAT", "SPELL_COMBAT", "DEFENSES", "RESISTANCE" } local PETPAPERDOLL_STATCATEGORY_DEFAULTORDER = { "BASE_STATS", "MELEE_COMBAT", -- "RANGED_COMBAT", "SPELL_COMBAT", "DEFENSES", "RESISTANCE" } local _PLAYER_LEVEL, _PLAYER_LEVEL_NO_SPEC do local locale = GetLocale() if locale == "deDE" then _PLAYER_LEVEL = "Stufe %s, |c%s%s-%s|r" _PLAYER_LEVEL_NO_SPEC = "Stufe %s, |c%s%s|r" elseif locale == "esES" or locale == "esMX" then _PLAYER_LEVEL = "|c%2$s%4$s %3$s|r de nivel %1$s" _PLAYER_LEVEL_NO_SPEC = "|c%2$s%3$s|r de nivel %1$s" elseif locale == "frFR" then _PLAYER_LEVEL = "|c%2$s%4$s %3$s|r de niveau %1$s" _PLAYER_LEVEL_NO_SPEC = "|c%2$s%3$s|r de niveau %1$s" elseif locale == "koKR" then _PLAYER_LEVEL = "%s 레벨 |c%s%s %s|r" _PLAYER_LEVEL_NO_SPEC = "%s 레벨 |c%s%s|r" elseif locale == "ruRU" then _PLAYER_LEVEL = "|c%2$s%4$s (%3$s)|r %1$s-го уровня" _PLAYER_LEVEL_NO_SPEC = "|c%2$s%3$s|r %1$s-го уровня" elseif locale == "zhCN" then _PLAYER_LEVEL = "等级%s |c%s%s %s|r" _PLAYER_LEVEL_NO_SPEC = "等级%s |c%s%s|r" elseif locale == "zhTW" then _PLAYER_LEVEL = "等級%s|c%s%s%s|r" _PLAYER_LEVEL_NO_SPEC = "等級%s|c%s%s|r" else _PLAYER_LEVEL = "Level %s |c%s%s %s|r" _PLAYER_LEVEL_NO_SPEC = "Level %s |c%s%s|r" end end function module:PaperDollFrame_SetLevel() local specName = NONE local classColor = RAID_CLASS_COLORS[E.myclass] local classColorString = format("FF%02x%02x%02x", classColor.r*255, classColor.g*255, classColor.b*255) if specName == NONE then CharacterLevelText:SetFormattedText(_PLAYER_LEVEL_NO_SPEC, E.mylevel, classColorString, E.myLocalizedClass) else CharacterLevelText:SetFormattedText(_PLAYER_LEVEL, E.mylevel, classColorString, specName, E.myLocalizedClass) end if CharacterLevelText:GetWidth() > 205 then if PaperDollSidebarTab1:IsVisible() then CharacterLevelText:Point("TOP", CharacterNameText, "BOTTOM", -10, -6) else CharacterLevelText:Point("TOP", CharacterNameText, "BOTTOM", 10, -6) end else CharacterLevelText:Point("TOP", CharacterNameText, "BOTTOM", 0, -6) end end function module:PaperDollSidebarTab(button) button:Size(33, 35) button:SetTemplate("Default") button.Icon = button:CreateTexture(nil, "ARTWORK") button.Icon:SetInside() button.Icon:SetTexture(PAPERDOLL_SIDEBARS[button:GetID()].icon) local tcoords = PAPERDOLL_SIDEBARS[button:GetID()].texCoords button.Icon:SetTexCoord(tcoords[1], tcoords[2], tcoords[3], tcoords[4]) button.Hider = button:CreateTexture(nil, "OVERLAY") button.Hider:SetTexture(0, 0, 0, 0.8) button.Hider:SetInside() button.Highlight = button:CreateTexture(nil, "HIGHLIGHT") button.Highlight:SetTexture(1, 1, 1, 0.3) button.Highlight:SetInside() button:SetScript("OnClick", function(self) module:PaperDollFrame_SetSidebar(self, self:GetID()) PlaySound("igMainMenuOption") end) button:SetScript("OnEnter", function(self) GameTooltip:SetOwner(self, "ANCHOR_RIGHT") GameTooltip:SetText(PAPERDOLL_SIDEBARS[self:GetID()].name, 1, 1, 1) end) button:SetScript("OnLeave", function(self) GameTooltip:Hide() end) end function module:CharacterFrame_Collapse(sizeOnly) if self.skinEnabled then CharacterFrame.backdrop:Width(341) S:SetBackdropHitRect(PaperDollFrame, CharacterFrame.backdrop) S:SetBackdropHitRect(PetPaperDollFrame, CharacterFrame.backdrop) else CharacterFrame:Width(384) S:SetBackdropHitRect(PaperDollFrame) S:SetBackdropHitRect(PetPaperDollFrame) end S:SetUIPanelWindowInfo(CharacterFrame, "width") if sizeOnly then return end CharacterFrame.Expanded = false S:SetNextPrevButtonDirection(CharacterFrameExpandButton, "right") for i = 1, #PAPERDOLL_SIDEBARS do _G[PAPERDOLL_SIDEBARS[i].frame]:Hide() end PaperDollSidebarTabs:Hide() end function module:CharacterFrame_Expand(sizeOnly) if self.skinEnabled then CharacterFrame.backdrop:Width(341 + CHARACTERFRAME_EXPANDED_WIDTH) S:SetBackdropHitRect(PaperDollFrame, CharacterFrame.backdrop) S:SetBackdropHitRect(PetPaperDollFrame, CharacterFrame.backdrop) else CharacterFrame:Width(352 + CHARACTERFRAME_EXPANDED_WIDTH) S:SetBackdropHitRect(PaperDollFrame) S:SetBackdropHitRect(PetPaperDollFrame) end S:SetUIPanelWindowInfo(CharacterFrame, "width") if sizeOnly then return end CharacterFrame.Expanded = true S:SetNextPrevButtonDirection(CharacterFrameExpandButton, "left") if PaperDollFrame:IsShown() and PaperDollFrame.currentSideBar then CharacterStatsPane:Hide() PaperDollFrame.currentSideBar:Show() else CharacterStatsPane:Show() end self:PaperDollFrame_UpdateSidebarTabs() PaperDollSidebarTabs:Show() end local StatCategoryFrames = {} local titanGrip local qualityColors = {} do for i = 0, 7 do qualityColors[i] = {GetItemQualityColor(i)} end if E.myclass == "WARRIOR" then local GetTalentInfo = GetTalentInfo local titanGripCheck = CreateFrame("Frame") titanGripCheck:RegisterEvent("PLAYER_ENTERING_WORLD") titanGripCheck:RegisterEvent("SPELL_UPDATE_USABLE") titanGripCheck:RegisterEvent("CHARACTER_POINTS_CHANGED") titanGripCheck:SetScript("OnEvent", function(self, event, ...) titanGrip = CA_IsSpellKnown(46917) if event == "PLAYER_ENTERING_WORLD" or event == "SPELL_UPDATE_USABLE" then self:UnregisterEvent(event) end end) end end --[[ local function OnEvent(event, bagID, slotID) if event == "ITEM_UNLOCKED" then if not slotID then -- equiped item removed else -- bag item removed end end end local slots = { ["HeadSlot"] = "INVTYPE_HEAD", ["NeckSlot"] = "INVTYPE_NECK", ["ShoulderSlot"] = "INVTYPE_SHOULDER", ["BackSlot"] = "INVTYPE_CLOAK", ["ChestSlot"] = "INVTYPE_ROBE", ["WristSlot"] = "INVTYPE_WRIST", ["HandsSlot"] = "INVTYPE_HAND", ["WaistSlot"] = "INVTYPE_WAIST", ["LegsSlot"] = "INVTYPE_LEGS", ["FeetSlot"] = "INVTYPE_FEET", ["Finger0Slot"] = "INVTYPE_FINGER", ["Finger1Slot"] = "INVTYPE_FINGER", ["Trinket0Slot"] = "INVTYPE_TRINKET", ["Trinket1Slot"] = "INVTYPE_TRINKET", ["MainHandSlot"] = {"INVTYPE_WEAPONMAINHAND", "INVTYPE_2HWEAPON", "INVTYPE_WEAPON"}, ["SecondaryHandSlot"] = {"INVTYPE_WEAPONOFFHAND", "INVTYPE_SHIELD", "INVTYPE_HOLDABLE", "INVTYPE_WEAPON"}, ["RangedSlot"] = {"INVTYPE_RANGED", "INVTYPE_RANGEDRIGHT", "INVTYPE_THROWN", "INVTYPE_RELIC"} } local bagsTable = {} local function sortItemLevel(a, b) return a > b end local function GetAverageItemLevel() local _, itemLink, itemLevel, itemEquipLoc, slotID local totalItemLevel, totalEquippedItemLevel = 0, 0 local items = 16 for bag = 0, 4 do for slot = 1, GetContainerNumSlots(bag) do itemLink = GetContainerItemLink(bag, slot) if itemLink then _, _, _, itemLevel, _, _, _, _, itemEquipLoc = GetItemInfo(itemLink) if itemEquipLoc and itemEquipLoc ~= "" then if itemEquipLoc == "INVTYPE_WEAPON" or (titanGrip and itemEquipLoc == "INVTYPE_2HWEAPON") then if not bagsTable[itemEquipLoc] then bagsTable[itemEquipLoc] = {itemLevel} elseif #bagsTable[itemEquipLoc] == 1 then bagsTable[itemEquipLoc][2] = itemLevel sort(bagsTable[itemEquipLoc], sortItemLevel) elseif itemLevel > bagsTable[itemEquipLoc][1] then bagsTable[itemEquipLoc][2] = bagsTable[itemEquipLoc][1] bagsTable[itemEquipLoc][1] = itemLevel elseif itemLevel > bagsTable[itemEquipLoc][2] then bagsTable[itemEquipLoc][2] = itemLevel end else if not bagsTable[itemEquipLoc] then bagsTable[itemEquipLoc] = itemLevel elseif itemLevel > bagsTable[itemEquipLoc] then bagsTable[itemEquipLoc] = itemLevel end end end end end end local hasMainHandBag, maxBagItemLevel, countBagOffhand local hasTwoHandBag = bagsTable["INVTYPE_2HWEAPON"] for slotName, itemLoc in pairs(slots) do slotID = GetInventorySlotInfo(slotName) itemLink = GetInventoryItemLink("player", slotID) if itemLink then _, _, _, itemLevel, _, _, _, _, itemEquipLoc = GetItemInfo(itemLink) if itemLevel and itemLevel > 0 then if type(itemLoc) == "table" then local maxLocItemLevel = 0 for _, bagItemLoc in ipairs(itemLoc) do maxBagItemLevel = bagsTable[bagItemLoc] if maxBagItemLevel and maxBagItemLevel > maxLocItemLevel then maxLocItemLevel = maxBagItemLevel end end maxBagItemLevel = maxLocItemLevel ~= 0 and maxLocItemLevel else maxBagItemLevel = bagsTable[itemEquipLoc] end if maxBagItemLevel and maxBagItemLevel > itemLevel then totalItemLevel = totalItemLevel + maxBagItemLevel else totalItemLevel = totalItemLevel + itemLevel end totalEquippedItemLevel = totalEquippedItemLevel + itemLevel if slotName == "MainHandSlot" and (itemEquipLoc ~= "INVTYPE_2HWEAPON" or titanGrip) then items = 17 countBagOffhand = true end end else if type(itemLoc) == "table" then local maxLocItemLevel = 0 if slotName == "SecondaryHandSlot" then if titanGrip then maxLocItemLevel = bagsTable["INVTYPE_2HWEAPON"] end if not titanGrip or maxLocItemLevel < bagsTable["INVTYPE_WEAPON"] then maxLocItemLevel = bagsTable["INVTYPE_WEAPON"] end end for _, bagItemLoc in ipairs(itemLoc) do maxBagItemLevel = bagsTable[bagItemLoc] if maxBagItemLevel and maxBagItemLevel > maxLocItemLevel then maxLocItemLevel = maxBagItemLevel end end maxBagItemLevel = maxLocItemLevel ~= 0 and maxLocItemLevel else maxBagItemLevel = bagsTable[itemLoc] end if maxBagItemLevel and (slotName ~= "SecondaryHandSlot" or countBagOffhand) then totalItemLevel = totalItemLevel + maxBagItemLevel end if slotName == "MainHandSlot" then if hasTwoHandBag then if maxBagItemLevel then if hasTwoHandBag > maxBagItemLevel then hasMainHandBag = hasTwoHandBag end else hasMainHandBag = hasTwoHandBag end end end end end wipe(bagsTable) if hasMainHandBag then totalItemLevel = totalItemLevel + hasMainHandBag end return (totalItemLevel / 17), (totalEquippedItemLevel / items) end local function GetItemLevelColor(unit) if not unit then unit = "player" end local i = 0 local sumR, sumG, sumB = 0, 0, 0 for slotName in pairs(slots) do local slotID = GetInventorySlotInfo(slotName) if GetInventoryItemTexture(unit, slotID) then local itemLink = GetInventoryItemLink(unit, slotID) if itemLink then local quality = select(3, GetItemInfo(itemLink)) if quality then i = i + 1 local r, g, b = GetItemQualityColor(quality) sumR = sumR + r sumG = sumG + g sumB = sumB + b end end end end if i > 0 then return (sumR / i), (sumG / i), (sumB / i) else return 1, 1, 1 end end ]] local function GetAverageItemLevel() local items = 15 local ilvl = 0 local colorCount, sumR, sumG, sumB = 0, 0, 0, 0 -- same ilvl calculation as C_Player:GetAverageItemLevel() for slot = INVSLOT_FIRST_EQUIPPED, INVSLOT_LAST_EQUIPPED do if slot ~= INVSLOT_BODY and slot ~= INVSLOT_TABARD then local itemLink = GetInventoryItemLink("player", slot) if itemLink then local _, _, quality, itemLevel, _, _, _, _, itemEquipLoc = GetItemInfo(itemLink) if itemLevel then if slot == INVSLOT_RANGED or slot == INVSLOT_OFFHAND then items = items + 1 end ilvl = ilvl + itemLevel colorCount = colorCount + 1 sumR = sumR + qualityColors[quality][1] sumG = sumG + qualityColors[quality][2] sumB = sumB + qualityColors[quality][3] end end end end if colorCount == 0 then return ilvl / items, 1, 1, 1 else return ilvl / items, (sumR / colorCount), (sumG / colorCount), (sumB / colorCount) end end function module:SetLabelAndText(statFrame, label, text, isPercentage) statFrame.Label:SetFormattedText(STAT_FORMAT, label) if isPercentage then statFrame.Value:SetFormattedText("%.2F%%", text) else statFrame.Value:SetText(text) end end function module:ItemLevel(statFrame, unit) if not self.Initialized then return end if GearScore_GetScore then if not self.gearScore or not GS_PlayerIsInCombat then local gearScore = GearScore_GetScore(E.myname, "player") if not gearScore then if GS_Data and GS_Data[E.myrealm] then gearScore = GS_Data[E.myrealm].Players[E.myname].GearScore end end if gearScore then local r, b, g = GearScore_GetQuality(gearScore) self.gearScore = gearScore self.gearScoreR = r self.gearScoreG = g self.gearScoreB = b statFrame.Label:SetText(gearScore) statFrame.Label:SetTextColor(r, g, b) return end else statFrame.Label:SetText(self.gearScore) statFrame.Label:SetTextColor(self.gearScoreR, self.gearScoreG, self.gearScoreB) return end end -- local avgItemLevel, avgItemLevelEquipped = GetAverageItemLevel() -- if avgItemLevelEquipped == avgItemLevel then -- statFrame.Label:SetFormattedText("%.2f", avgItemLevelEquipped) -- else -- statFrame.Label:SetFormattedText("%.2f / %.2f", avgItemLevelEquipped, avgItemLevel) -- end -- statFrame.Label:SetTextColor(GetItemLevelColor()) local avgItemLevel, r, g, b = GetAverageItemLevel() statFrame.Label:SetFormattedText("%.1f", avgItemLevel) statFrame.Label:SetTextColor(r, g, b) end function module:PvEPower(statFrame, unit) if not self.Initialized then return end statFrame.Label:SetText(PVE_POWER) statFrame.Label:SetTextColor(ColorUtil:Lerp(ITEM_QUALITY_COLORS[1], ITEM_QUALITY_COLORS[4], PVE_POWER/PVE_POWER_CAP):GetRGB()) statFrame.tooltip = "PvE Power" local text = format("Increases damage against creatures by: |cffFFFFFF%s%%|r", PVE_POWER * PVE_POWER_DAMAGE_MULTIPLIER) text = text .. format("\nReduces damage taken from creatures by: |cffFFFFFF%s%%|r", PVE_POWER * PVE_POWER_DAMAGE_TAKEN_MULTIPLIER) text = text .. format("\nIncreases healing done and absorption in |cffFFFFFFinstances|r by: |cffFFFFFF%s%%|r", PVE_POWER * PVE_POWER_HEALING_MULTIPLIER) if UnitLevel("player") < GetMaxLevel() then text = text .. "\n" .. format("|cffFF0000Does not apply below level: %d|r", GetMaxLevel()) end statFrame.tooltip2 = text end function module:PvPPower(statFrame, unit) if not self.Initialized then return end statFrame.Label:SetText(PVP_POWER) statFrame.Label:SetTextColor(ColorUtil:Lerp(ITEM_QUALITY_COLORS[1], ITEM_QUALITY_COLORS[5], PVP_POWER/PVP_POWER_CAP):GetRGB()) statFrame.tooltip = "PvE Power" local text = format("Increases damage against players by: |cffFFFFFF%s%%|r", PVP_POWER * PVP_POWER_DAMAGE_MULTIPLIER) text = text .. format("\nWhile your Primary Stat is |cffFFFFFFSpirit|r your healing and absorption in |cffFFFFFFArenas and Battlegrounds|r is increased by: |cffFFFFFF%s%%|r", PVP_POWER * PVP_POWER_DAMAGE_MULTIPLIER) if UnitLevel("player") < GetMaxLevel() then text = text .. "\n" .. format("|cffFF0000Does not apply below level: %d|r", GetMaxLevel()) end statFrame.tooltip2 = text end local felCommText = AscensionUI.CharacterFrame.Extension.StatPanel.FelCommutation.Content.CostText function module:FelComm(statFrame, unit) if not self.Initialized then return end if felCommText:GetText() then statFrame.Label:SetText(felCommText:GetText()) else statFrame.Label:SetText(GetMoneyString(0)) end statFrame.tooltip = "Fel Commutation" statFrame.tooltip2 = "Maximum gold lost on death.\n|cffFF8888Only applies in High Risk|r" end function module:PrimaryStat(statFrame, unit) if not self.Initialized then return end local statID = C_PrimaryStat:GetActivePrimaryStat() if not statID then statFrame.Label:SetFormattedText("No Primary Stat") statFrame.Label:SetTextColor(0.5, 0.5, 0.5) statFrame.tooltip = nil return end local _, _, _, name, tooltip = C_PrimaryStat:GetPrimaryStatInfo(statID) statFrame.Label:SetFormattedText(name) statFrame.Label:SetTextColor(STAT_COLORS[statID]:GetRGBA()) statFrame.tooltip = name statFrame.tooltip2 = tooltip end function module:SetStat(statFrame, unit, statIndex) local stat, effectiveStat, posBuff, negBuff = UnitStat(unit, statIndex) local statName = _G["SPELL_STAT"..statIndex.."_NAME"] statFrame.Label:SetFormattedText(STAT_FORMAT, statName) local tooltipText = HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, statName).." " if posBuff == 0 and negBuff == 0 then statFrame.Value:SetText(effectiveStat) statFrame.tooltip = tooltipText..effectiveStat..FONT_COLOR_CODE_CLOSE else tooltipText = tooltipText..effectiveStat if posBuff > 0 or negBuff < 0 then tooltipText = tooltipText.." ("..(stat - posBuff - negBuff)..FONT_COLOR_CODE_CLOSE end if posBuff > 0 then tooltipText = tooltipText..FONT_COLOR_CODE_CLOSE..GREEN_FONT_COLOR_CODE.."+"..posBuff..FONT_COLOR_CODE_CLOSE end if negBuff < 0 then tooltipText = tooltipText..RED_FONT_COLOR_CODE.." "..negBuff..FONT_COLOR_CODE_CLOSE end if posBuff > 0 or negBuff < 0 then tooltipText = tooltipText..HIGHLIGHT_FONT_COLOR_CODE..")"..FONT_COLOR_CODE_CLOSE end statFrame.tooltip = tooltipText if negBuff < 0 then statFrame.Value:SetText(RED_FONT_COLOR_CODE..effectiveStat..FONT_COLOR_CODE_CLOSE) else statFrame.Value:SetText(GREEN_FONT_COLOR_CODE..effectiveStat..FONT_COLOR_CODE_CLOSE) end end statFrame.tooltip2 = _G["DEFAULT_STAT"..statIndex.."_TOOLTIP"] if unit == "player" then local _, unitClass = UnitClass("player") if statIndex == 1 then local attackPower = GetAttackPowerForStat(statIndex, effectiveStat) statFrame.tooltip2 = format(statFrame.tooltip2, attackPower) if unitClass == "WARRIOR" or unitClass == "SHAMAN" or unitClass == "PALADIN" then statFrame.tooltip2 = statFrame.tooltip2.."\n"..format(STAT_BLOCK_TOOLTIP, max(0, effectiveStat * BLOCK_PER_STRENGTH - 10)) end elseif statIndex == 3 then local baseStam = min(20, effectiveStat) local moreStam = effectiveStat - baseStam statFrame.tooltip2 = format(statFrame.tooltip2, (baseStam + (moreStam * HEALTH_PER_STAMINA)) * GetUnitMaxHealthModifier("player")) local petStam = ComputePetBonus("PET_BONUS_STAM", effectiveStat) if petStam > 0 then statFrame.tooltip2 = statFrame.tooltip2.."\n"..format(PET_BONUS_TOOLTIP_STAMINA, petStam) end elseif statIndex == 2 then local attackPower = GetAttackPowerForStat(statIndex, effectiveStat) local meleeCrit = GetCritChanceFromAgility("player") if attackPower > 0 then statFrame.tooltip2 = format(STAT_ATTACK_POWER, attackPower)..format(statFrame.tooltip2, meleeCrit, effectiveStat * ARMOR_PER_AGILITY) else statFrame.tooltip2 = format(statFrame.tooltip2, meleeCrit, effectiveStat * ARMOR_PER_AGILITY) end statFrame.tooltip2 = statFrame.tooltip2 .. "\n" .. format(_G["DEFAULT_STAT"..statIndex.."_EXTRA"], meleeCrit*AGI_TO_SPELL_CRIT_PCT) elseif statIndex == 4 then local baseInt = min(20, effectiveStat) local moreInt = effectiveStat - baseInt local spellCrit = GetSpellCritChanceFromIntellect("player") if UnitHasMana("player") then statFrame.tooltip2 = format(statFrame.tooltip2, baseInt + moreInt * MANA_PER_INTELLECT, spellCrit, (baseInt + moreInt) * INT_TO_MELEE_CRIT_PCT) statFrame.tooltip2 = statFrame.tooltip2 .. "\n" .. format(_G["DEFAULT_STAT"..statIndex.."_EXTRA"], spellCrit * INT_TO_MELEE_CRIT_PCT) else statFrame.tooltip2 = nil end local petInt = ComputePetBonus("PET_BONUS_INT", effectiveStat) if petInt > 0 then if not statFrame.tooltip2 then statFrame.tooltip2 = "" end statFrame.tooltip2 = statFrame.tooltip2.."\n"..format(PET_BONUS_TOOLTIP_INTELLECT, petInt) end elseif statIndex == 5 then statFrame.tooltip2 = format(statFrame.tooltip2, GetUnitHealthRegenRateFromSpirit("player")) if UnitHasMana("player") then local regen = GetUnitManaRegenRateFromSpirit("player") regen = floor(regen * 5.0) statFrame.tooltip2 = statFrame.tooltip2.."\n"..format(MANA_REGEN_FROM_SPIRIT, regen) end end elseif unit == "pet" then if statIndex == 1 then local attackPower = effectiveStat - 20 statFrame.tooltip2 = format(statFrame.tooltip2, attackPower) elseif statIndex == 2 then local newLineIndex = find(statFrame.tooltip2, "|n") + 1 statFrame.tooltip2 = sub(statFrame.tooltip2, 1, newLineIndex) statFrame.tooltip2 = format(statFrame.tooltip2, GetCritChanceFromAgility("pet")) elseif statIndex == 3 then local expectedHealthGain = (((stat - posBuff - negBuff) - 20) * 10 + 20) * GetUnitHealthModifier("pet") local realHealthGain = ((effectiveStat - 20) * 10 + 20) * GetUnitHealthModifier("pet") local healthGain = (realHealthGain - expectedHealthGain) * GetUnitMaxHealthModifier("pet") statFrame.tooltip2 = format(statFrame.tooltip2, healthGain) elseif statIndex == 4 then if UnitHasMana("pet") then local manaGain = ((effectiveStat - 20) * 15 + 20) * GetUnitPowerModifier("pet") statFrame.tooltip2 = format(statFrame.tooltip2, manaGain, GetSpellCritChanceFromIntellect("pet")) else local newLineIndex = find(statFrame.tooltip2, "|n") + 2 statFrame.tooltip2 = sub(statFrame.tooltip2, newLineIndex) statFrame.tooltip2 = format(statFrame.tooltip2, GetSpellCritChanceFromIntellect("pet")) end elseif statIndex == 5 then statFrame.tooltip2 = format(statFrame.tooltip2, GetUnitHealthRegenRateFromSpirit("pet")) if UnitHasMana("pet") then statFrame.tooltip2 = statFrame.tooltip2.."\n"..format(MANA_REGEN_FROM_SPIRIT, GetUnitManaRegenRateFromSpirit("pet")) end end end statFrame:Show() end function module:SetResistance(statFrame, unit, resistanceIndex) local base, resistance, positive, negative = UnitResistance(unit, resistanceIndex) local petBonus = ComputePetBonus("PET_BONUS_RES", resistance) local resistanceNameShort = _G["SPELL_SCHOOL"..resistanceIndex.."_CAP"] local resistanceName = _G["RESISTANCE"..resistanceIndex.."_NAME"] local resistanceIconCode = "|TInterface\\PaperDollInfoFrame\\SpellSchoolIcon"..(resistanceIndex + 1)..":14:14:2:2:16:16:2:14:2:14|t" statFrame.Label:SetText(resistanceIconCode.." "..format(STAT_FORMAT, resistanceNameShort)) local text = _G[statFrame:GetName().."StatText"] PaperDollFormatStat(resistanceName, base, positive, negative, statFrame, text) statFrame.tooltip = resistanceIconCode.." "..HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, resistanceName).." "..resistance..FONT_COLOR_CODE_CLOSE if positive ~= 0 or negative ~= 0 then statFrame.tooltip = statFrame.tooltip.." ( "..HIGHLIGHT_FONT_COLOR_CODE..base if positive > 0 then statFrame.tooltip = statFrame.tooltip..GREEN_FONT_COLOR_CODE.." +"..positive end if negative < 0 then statFrame.tooltip = statFrame.tooltip.." "..RED_FONT_COLOR_CODE..negative end statFrame.tooltip = statFrame.tooltip..FONT_COLOR_CODE_CLOSE.." )" end local resistanceLevel local unitLevel = UnitLevel(unit) unitLevel = max(unitLevel, 20) local magicResistanceNumber = resistance / unitLevel if magicResistanceNumber > 5 then resistanceLevel = RESISTANCE_EXCELLENT elseif magicResistanceNumber > 3.75 then resistanceLevel = RESISTANCE_VERYGOOD elseif magicResistanceNumber > 2.5 then resistanceLevel = RESISTANCE_GOOD elseif magicResistanceNumber > 1.25 then resistanceLevel = RESISTANCE_FAIR elseif magicResistanceNumber > 0 then resistanceLevel = RESISTANCE_POOR else resistanceLevel = RESISTANCE_NONE end statFrame.tooltip2 = format(RESISTANCE_TOOLTIP_SUBTEXT, _G["RESISTANCE_TYPE"..resistanceIndex], unitLevel, resistanceLevel) if petBonus > 0 then statFrame.tooltip2 = statFrame.tooltip2.."\n"..format(PET_BONUS_TOOLTIP_RESISTANCE, petBonus) end end function module:SetDodge(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end local chance = GetDodgeChance() module:SetLabelAndText(statFrame, STAT_DODGE, chance, 1) statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, DODGE_CHANCE).." "..format("%.02f", chance).."%"..FONT_COLOR_CODE_CLOSE statFrame.tooltip2 = format(CR_DODGE_TOOLTIP, GetCombatRating(CR_DODGE), GetCombatRatingBonus(CR_DODGE)) statFrame:Show() end function module:SetBlock(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end local chance = GetBlockChance() module:SetLabelAndText(statFrame, STAT_BLOCK, chance, 1) statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, BLOCK_CHANCE).." "..format("%.02f", chance).."%"..FONT_COLOR_CODE_CLOSE statFrame.tooltip2 = format(CR_BLOCK_TOOLTIP, GetCombatRating(CR_BLOCK), GetCombatRatingBonus(CR_BLOCK), GetShieldBlock()) statFrame:Show() end function module:SetParry(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end local chance = GetParryChance() module:SetLabelAndText(statFrame, STAT_PARRY, chance, 1) statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, PARRY_CHANCE).." "..format("%.02f", chance).."%"..FONT_COLOR_CODE_CLOSE statFrame.tooltip2 = format(CR_PARRY_TOOLTIP, GetCombatRating(CR_PARRY), GetCombatRatingBonus(CR_PARRY)) statFrame:Show() end function module:SetResilience(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end local melee = GetCombatRating(CR_CRIT_TAKEN_MELEE) local ranged = GetCombatRating(CR_CRIT_TAKEN_RANGED) local spell = GetCombatRating(CR_CRIT_TAKEN_SPELL) local minResilience = min(melee, ranged) minResilience = min(minResilience, spell) local lowestRating if melee == minResilience then lowestRating = CR_CRIT_TAKEN_MELEE elseif ranged == minResilience then lowestRating = CR_CRIT_TAKEN_RANGED else lowestRating = CR_CRIT_TAKEN_SPELL end local maxRatingBonus = GetMaxCombatRatingBonus(lowestRating) local lowestRatingBonus = GetCombatRatingBonus(lowestRating) module:SetLabelAndText(statFrame, STAT_RESILIENCE, minResilience) statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, STAT_RESILIENCE).." "..minResilience..FONT_COLOR_CODE_CLOSE statFrame.tooltip2 = format(RESILIENCE_TOOLTIP, min(lowestRatingBonus * RESILIENCE_CRIT_CHANCE_TO_CONSTANT_DAMAGE_REDUCTION_MULTIPLIER,maxRatingBonus)) statFrame:Show() end function module:SetMeleeDPS(statFrame, unit) statFrame.Label:SetFormattedText(STAT_FORMAT, L["Damage Per Second"]) local speed, offhandSpeed = UnitAttackSpeed(unit) local minDamage, maxDamage, minOffHandDamage, maxOffHandDamage, physicalBonusPos, physicalBonusNeg, percent = UnitDamage(unit) minDamage = (minDamage / percent) - physicalBonusPos - physicalBonusNeg maxDamage = (maxDamage / percent) - physicalBonusPos - physicalBonusNeg local baseDamage = (minDamage + maxDamage) * 0.5 local fullDamage = (baseDamage + physicalBonusPos + physicalBonusNeg) * percent local totalBonus = (fullDamage - baseDamage) local damagePerSecond = (max(fullDamage, 1) / speed) local colorPos = "|cff20ff20" local colorNeg = "|cffff2020" local text if totalBonus < 0.1 and totalBonus > -0.1 then totalBonus = 0.0 end if totalBonus == 0 then text = format("%.1F", damagePerSecond) else local color if totalBonus > 0 then color = colorPos else color = colorNeg end text = color..format("%.1F", damagePerSecond).."|r" end if offhandSpeed then minOffHandDamage = (minOffHandDamage / percent) - physicalBonusPos - physicalBonusNeg maxOffHandDamage = (maxOffHandDamage / percent) - physicalBonusPos - physicalBonusNeg local offhandBaseDamage = (minOffHandDamage + maxOffHandDamage) * 0.5 local offhandFullDamage = (offhandBaseDamage + physicalBonusPos + physicalBonusNeg) * percent local offhandDamagePerSecond = (max(offhandFullDamage, 1) / offhandSpeed) local offhandTotalBonus = (offhandFullDamage - offhandBaseDamage) if offhandTotalBonus < 0.1 and offhandTotalBonus > -0.1 then offhandTotalBonus = 0.0 end local separator = " / " if damagePerSecond > 1000 and offhandDamagePerSecond > 1000 then separator = "/" end if offhandTotalBonus == 0 then text = text..separator..format("%.1F", offhandDamagePerSecond) else local color if offhandTotalBonus > 0 then color = colorPos else color = colorNeg end text = text..separator..color..format("%.1F", offhandDamagePerSecond).."|r" end end statFrame.Value:SetText(text) statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE..DAMAGE_PER_SECOND..FONT_COLOR_CODE_CLOSE statFrame:Show() end function module:SetMeleeCritChance(statFrame, unit) if unit ~= "player" then statFrame:Hide() return end statFrame.Label:SetFormattedText(STAT_FORMAT, MELEE_CRIT_CHANCE) local critChance = GetCritChance() statFrame.Value:SetFormattedText("%.2F%%", critChance) statFrame.tooltip = HIGHLIGHT_FONT_COLOR_CODE..format(PAPERDOLLFRAME_TOOLTIP_FORMAT, MELEE_CRIT_CHANCE).." "..format("%.2F%%", critChance)..FONT_COLOR_CODE_CLOSE statFrame.tooltip2 = format(CR_CRIT_MELEE_TOOLTIP, GetCombatRating(CR_CRIT_MELEE), GetCombatRatingBonus(CR_CRIT_MELEE)) end local function PaperDollFrame_CollapseStatCategory(categoryFrame) if not categoryFrame.collapsed then categoryFrame.collapsed = true --categoryFrame.Toolbar:SetTemplate("NoBackdrop") categoryFrame.Toolbar:SetAlpha(0.4) local index = 1 while categoryFrame.Stats[index] do categoryFrame.Stats[index]:Hide() index = index + 1 end categoryFrame:Height(18) module:PaperDollFrame_UpdateStatScrollChildHeight() end end local function PaperDollFrame_ExpandStatCategory(categoryFrame) if categoryFrame.collapsed then categoryFrame.collapsed = false --categoryFrame.Toolbar:SetTemplate("Default", true) categoryFrame.Toolbar:SetAlpha(1) module:PaperDollFrame_UpdateStatCategory(categoryFrame) module:PaperDollFrame_UpdateStatScrollChildHeight() end end local function PaperDollFrame_QueuedUpdate(self) module:PaperDollFrame_UpdateStats() self:SetScript("OnUpdate", nil) end local function PetPaperDollFrame_QueuedUpdate(self) PetPaperDollFrame_Update() self:SetScript("OnUpdate", nil) end function module:PaperDollFrame_UpdateStatCategory(categoryFrame) if not categoryFrame.Category then categoryFrame:Hide() return end local category = categoryFrame.Category local categoryInfo = PAPERDOLL_STATCATEGORIES[category] if category == "ITEM_LEVEL" then if PersonalGearScore then categoryFrame.NameText:SetText("Gear Score") else categoryFrame.NameText:SetText(L["Item Level"]) end elseif category == "PRIMARY_STAT" then categoryFrame.NameText:SetText("Primary Stat") elseif category == "FEL_COMM" then categoryFrame.NameText:SetText("Fel Comm Cost") elseif category == "PVE_POWER" then categoryFrame.NameText:SetText("PvE Power") elseif category == "PVP_POWER" then categoryFrame.NameText:SetText("PvP Power") elseif category == "RESISTANCE" then categoryFrame.NameText:SetText(L["Resistance"]) elseif category == "DEFENSES" then categoryFrame.NameText:SetText(DEFENSE) else categoryFrame.NameText:SetText(_G["PLAYERSTAT_"..category]) end if categoryFrame.collapsed then return end local totalHeight = categoryFrame.NameText:GetHeight() + 10 local numVisible = 0 if categoryInfo then local prevStatFrame = nil for _, stat in next, categoryInfo.stats do local statInfo = PAPERDOLL_STATINFO[stat] if statInfo then local statFrame = categoryFrame.Stats[numVisible + 1] if not statFrame then statFrame = CreateFrame("Frame", "$parentStat"..numVisible + 1, categoryFrame, "CharacterStatFrameTemplate") if prevStatFrame then statFrame:SetPoint("TOPLEFT", prevStatFrame, "BOTTOMLEFT") statFrame:SetPoint("TOPRIGHT", prevStatFrame, "BOTTOMRIGHT") end categoryFrame.Stats[numVisible + 1] = statFrame end statFrame:Show() if stat == "ITEM_LEVEL" or stat == "PVP_POWER" or stat == "PVE_POWER" then statFrame:Height(30) local label = statFrame.Label label:Width(187) label:ClearAllPoints() label:SetPoint("CENTER") label:FontTemplate(nil, 20, "NONE") label:SetJustifyH("CENTER") statFrame.Value:SetText("") if statFrame.leftGrad then statFrame.leftGrad:Show() statFrame.rightGrad:Show() end elseif stat == "FEL_COMM" or stat == "PRIMARY_STAT" then statFrame:Height(30) local label = statFrame.Label label:Width(187) label:ClearAllPoints() label:SetPoint("CENTER") label:FontTemplate(nil, 16, "NONE") label:SetJustifyH("CENTER") statFrame.Value:SetText("") if statFrame.leftGrad then statFrame.leftGrad:Show() statFrame.rightGrad:Show() end elseif statFrame:GetHeight() > 22 then statFrame:Height(15) local label = statFrame.Label label:Width(122) label:ClearAllPoints() label:Point("LEFT", 7, 0) label:FontTemplate(nil, nil, "NONE") label:SetJustifyH("LEFT") label:SetTextColor(1, 0.82, 0) if statFrame.leftGrad then statFrame.leftGrad:Hide() statFrame.rightGrad:Hide() end end if statInfo.updateFunc2 then statFrame:SetScript("OnEnter", PaperDollStatTooltip) statFrame:SetScript("OnEnter", statInfo.updateFunc2) else statFrame:SetScript("OnEnter", PaperDollStatTooltip) end statFrame.tooltip = nil statFrame.tooltip2 = nil statFrame.UpdateTooltip = nil statFrame:SetScript("OnUpdate", nil) statInfo.updateFunc(statFrame, CharacterStatsPane.unit) if statFrame:IsShown() then numVisible = numVisible + 1 totalHeight = totalHeight + statFrame:GetHeight() prevStatFrame = statFrame if GameTooltip:GetOwner() == statFrame then statFrame:GetScript("OnEnter")(statFrame) end end end end end for index = 1, numVisible do local isSpecial = categoryInfo == PAPERDOLL_STATCATEGORIES["ITEM_LEVEL"] or categoryInfo == PAPERDOLL_STATCATEGORIES["PVE_POWER"] or categoryInfo == PAPERDOLL_STATCATEGORIES["FEL_COMM"] if index % 2 == 0 or isSpecial then local statFrame = categoryFrame.Stats[index] if not statFrame.leftGrad then statFrame.leftGrad = statFrame:CreateTexture(nil, "BACKGROUND") statFrame.leftGrad:Size(80, statFrame:GetHeight()) statFrame.leftGrad:SetPoint("LEFT", statFrame, "CENTER") statFrame.leftGrad:SetTexture(E.media.blankTex) statFrame.leftGrad:SetGradientAlpha("Horizontal", 0.8,0.8,0.8,0.35, 0.8,0.8,0.8,0) statFrame.rightGrad = statFrame:CreateTexture(nil, "BACKGROUND") statFrame.rightGrad:Size(80, statFrame:GetHeight()) statFrame.rightGrad:SetPoint("RIGHT", statFrame, "CENTER") statFrame.rightGrad:SetTexture(E.media.blankTex) statFrame.rightGrad:SetGradientAlpha("Horizontal", 0.8,0.8,0.8,0, 0.8,0.8,0.8,0.35) end end end local index = numVisible + 1 while categoryFrame.Stats[index] do categoryFrame.Stats[index]:Hide() index = index + 1 end categoryFrame:Height(totalHeight) end function module:PaperDollFrame_UpdateStats() local index = 1 while CharacterStatsPane.Categories[index] do self:PaperDollFrame_UpdateStatCategory(CharacterStatsPane.Categories[index]) index = index + 1 end self:PaperDollFrame_UpdateStatScrollChildHeight() end function module:PaperDollFrame_UpdateStatScrollChildHeight() local index = 1 local totalHeight = 0 while CharacterStatsPane.Categories[index] do if CharacterStatsPane.Categories[index]:IsShown() then totalHeight = totalHeight + CharacterStatsPane.Categories[index]:GetHeight() + 4 end index = index + 1 end CharacterStatsPaneScrollChild:Height(totalHeight + 10 -(CharacterStatsPane.initialOffsetY or 0)) end local function FindCategoryById(id) for categoryName, category in pairs(PAPERDOLL_STATCATEGORIES) do if category.id == id then return categoryName end end end function module:PaperDoll_InitStatCategories(defaultOrder, orderData, collapsedData, unit) local order = defaultOrder local orderString = orderData local savedOrder = {} if orderString and orderString ~= "" then for i in gmatch(orderString, "(%d+),?") do i = tonumber(i) if i then local categoryName = FindCategoryById(i) if categoryName then tinsert(savedOrder, categoryName) end end end local valid = true if #savedOrder == #defaultOrder then for _, category1 in ipairs(defaultOrder) do local found = false for _, category2 in ipairs(savedOrder) do if category1 == category2 then found = true break end end if not found then valid = false break end end else valid = false end if valid then order = savedOrder else orderData = "" end end wipe(StatCategoryFrames) for index = 1, #order do local frame = CharacterStatsPane.Categories[index] tinsert(StatCategoryFrames, frame) frame.Category = order[index] frame:Show() local categoryInfo = PAPERDOLL_STATCATEGORIES[frame.Category] if categoryInfo and collapsedData[frame.Category] then PaperDollFrame_CollapseStatCategory(frame) else PaperDollFrame_ExpandStatCategory(frame) end end local index = #order + 1 while CharacterStatsPane.Categories[index] do CharacterStatsPane.Categories[index]:Hide() CharacterStatsPane.Categories[index].Category = nil index = index + 1 end CharacterStatsPane.defaultOrder = defaultOrder CharacterStatsPane.orderData = orderData CharacterStatsPane.collapsedData = collapsedData CharacterStatsPane.unit = unit self:PaperDoll_UpdateCategoryPositions() self:PaperDollFrame_UpdateStats() end local function PaperDoll_SaveStatCategoryOrder() if CharacterStatsPane.defaultOrder and #CharacterStatsPane.defaultOrder == #StatCategoryFrames then local same = true for index = 1, #StatCategoryFrames do if StatCategoryFrames[index].Category ~= CharacterStatsPane.defaultOrder[index] then same = false break end end if same then E.private.enhanced.character[CharacterStatsPane.unit].orderName = "" return end end local order = {} for index = 1, #StatCategoryFrames do order[index] = PAPERDOLL_STATCATEGORIES[StatCategoryFrames[index].Category].id end E.private.enhanced.character[CharacterStatsPane.unit].orderName = tconcat(order, ",") end function module:PaperDoll_UpdateCategoryPositions() local prevFrame for index = 1, #StatCategoryFrames do local frame = StatCategoryFrames[index] local xOffset = 0 if frame == MOVING_STAT_CATEGORY then xOffset = STATCATEGORY_MOVING_INDENT elseif prevFrame and prevFrame == MOVING_STAT_CATEGORY then xOffset = -STATCATEGORY_MOVING_INDENT end frame:ClearAllPoints() if prevFrame then frame:Point("TOPLEFT", prevFrame, "BOTTOMLEFT", 0 + xOffset, -4) else frame:Point("TOPLEFT", 1 + xOffset, -4 + (CharacterStatsPane.initialOffsetY or 0)) end prevFrame = frame end end local function StatCategory_OnDragUpdate(self) local _, cursorY = GetCursorPosition() cursorY = cursorY * GetScreenHeightScale() local myIndex, insertIndex, closestPos for index = 1, #StatCategoryFrames + 1 do if StatCategoryFrames[index] == self then myIndex = index end local frameY if index <= #StatCategoryFrames then frameY = StatCategoryFrames[index]:GetTop() else frameY = StatCategoryFrames[#StatCategoryFrames]:GetBottom() end frameY = frameY - 8 if myIndex and index > myIndex then frameY = frameY + self:GetHeight() end if not closestPos or abs(cursorY - frameY) < closestPos then insertIndex = index closestPos = abs(cursorY - frameY) end end if insertIndex > myIndex then insertIndex = insertIndex - 1 end if myIndex ~= insertIndex then tremove(StatCategoryFrames, myIndex) tinsert(StatCategoryFrames, insertIndex, self) module:PaperDoll_UpdateCategoryPositions() end end local function PaperDollStatCategory_OnDragStart(self) MOVING_STAT_CATEGORY = self module:PaperDoll_UpdateCategoryPositions() GameTooltip:Hide() self:SetScript("OnUpdate", StatCategory_OnDragUpdate) for i, frame in next, StatCategoryFrames do if frame ~= self then if E.db.enhanced.character.animations then UIFrameFadeIn(frame, 0.2, 1, 0.6) else frame:SetAlpha(0.6) end end end end local function PaperDollStatCategory_OnDragStop(self) MOVING_STAT_CATEGORY = nil module:PaperDoll_UpdateCategoryPositions() self:SetScript("OnUpdate", nil) for i, frame in next, StatCategoryFrames do if frame ~= self then if E.db.enhanced.character.animations then UIFrameFadeOut(frame, 0.2, 0.6, 1) else frame:SetAlpha(1) end end end PaperDoll_SaveStatCategoryOrder() end function module:PaperDollFrame_UpdateSidebarTabs() for i = 1, #PAPERDOLL_SIDEBARS do local tab = _G["PaperDollSidebarTab"..i] if _G[PAPERDOLL_SIDEBARS[i].frame]:IsShown() then tab.Hider:Hide() tab.Highlight:Hide() else tab.Hider:Show() tab.Highlight:Show() end end end function module:PaperDollFrame_SetSidebar(button, index) if not _G[PAPERDOLL_SIDEBARS[index].frame]:IsShown() then for i = 1, #PAPERDOLL_SIDEBARS do if _G[PAPERDOLL_SIDEBARS[i].frame]:IsShown() then if E.db.enhanced.character.animations then UIFrameFadeOut(_G[PAPERDOLL_SIDEBARS[i].frame], 0.2, 1, 0) _G[PAPERDOLL_SIDEBARS[i].frame].fadeInfo.finishedFunc = function() _G[PAPERDOLL_SIDEBARS[i].frame]:Hide() end else _G[PAPERDOLL_SIDEBARS[i].frame]:Hide() end _G["PaperDollSidebarTab"..i].Hider:Show() _G["PaperDollSidebarTab"..i].Highlight:Show() end end _G[PAPERDOLL_SIDEBARS[index].frame]:Show() if E.db.enhanced.character.animations then UIFrameFadeIn(_G[PAPERDOLL_SIDEBARS[index].frame], 0.2, 0, 1) end PaperDollFrame.currentSideBar = _G[PAPERDOLL_SIDEBARS[index].frame] PaperDollFrame.currentSideBarID = index _G["PaperDollSidebarTab"..index].Hider:Hide() _G["PaperDollSidebarTab"..index].Highlight:Hide() end end function module:PaperDollTitlesPane_UpdateScrollFrame() local buttons = PaperDollTitlesPane.buttons local playerTitles = PaperDollTitlesPane.titles local numButtons = #buttons local scrollOffset = HybridScrollFrame_GetOffset(PaperDollTitlesPane) local button, playerTitle for i = 1, numButtons do button = buttons[i] playerTitle = playerTitles[i + scrollOffset] if playerTitle then button:Show() button.text:SetText(playerTitle.name) button.titleId = playerTitle.id local highlight = button:GetHighlightTexture() highlight:SetTexture(E.Media.Textures.Highlight) highlight:SetInside() highlight:SetVertexColor(1, 1, 1, 0.35) if PaperDollTitlesPane.selected == playerTitle.id then button.Check:SetAlpha(1) button.SelectedBar:SetTexture(E.Media.Textures.Highlight) button.SelectedBar:SetVertexColor(1, 0.80, 0.10, 0.3) button.SelectedBar:SetInside() button.SelectedBar:Show() else button.Check:SetAlpha(0) button.SelectedBar:Hide() end if (i + scrollOffset) % 2 == 0 then button.Stripe:SetTexture(0.9, 0.9, 1, 0.1) button.Stripe:Show() else button.Stripe:Hide() end else button:Hide() end end end local function PlayerTitleSort(a, b) return a.name < b.name end function module:PaperDollTitlesPane_Update() local playerTitles = {} local currentTitle = GetCurrentTitle() local titleCount = 1 local buttons = PaperDollTitlesPane.buttons local fontstringText = buttons[1].text PaperDollTitlesPane.selected = -1 playerTitles[1] = {} playerTitles[1].name = " " playerTitles[1].id = -1 for i = 1, GetNumTitles() do if IsTitleKnown(i) ~= 0 then titleCount = titleCount + 1 playerTitles[titleCount] = playerTitles[titleCount] or {} playerTitles[titleCount].name = trim(GetTitleName(i)) playerTitles[titleCount].id = i if i == currentTitle then PaperDollTitlesPane.selected = i end fontstringText:SetText(playerTitles[titleCount].name) end end sort(playerTitles, PlayerTitleSort) playerTitles[1].name = NONE PaperDollTitlesPane.titles = playerTitles HybridScrollFrame_Update(PaperDollTitlesPane, (titleCount * 22) + 20 , PaperDollTitlesPane:GetHeight()) if not PaperDollTitlesPane.scrollBar.thumbTexture:IsShown() then PaperDollTitlesPane.scrollBar.thumbTexture:Show() end self:PaperDollTitlesPane_UpdateScrollFrame() end function module:PaperDollEquipmentManagerPane_Update() local _, setID = GetEquipmentSetInfoByName(PaperDollEquipmentManagerPane.selectedSetName or "") if setID then PaperDollEquipmentManagerPaneSaveSet:Enable() PaperDollEquipmentManagerPaneEquipSet:Enable() else PaperDollEquipmentManagerPaneSaveSet:Disable() PaperDollEquipmentManagerPaneEquipSet:Disable() if PaperDollEquipmentManagerPane.selectedSetName then PaperDollEquipmentManagerPane.selectedSetName = nil PaperDollFrame_ClearIgnoredSlots() end end local numSets = GetNumEquipmentSets() local numRows = numSets if numSets < MAX_EQUIPMENT_SETS_PER_PLAYER then numRows = numRows + 1 end HybridScrollFrame_Update(PaperDollEquipmentManagerPane, numRows * 44 + PaperDollEquipmentManagerPaneEquipSet:GetHeight() + 20 , PaperDollEquipmentManagerPane:GetHeight()) if not PaperDollEquipmentManagerPane.scrollBar.thumbTexture:IsShown() then PaperDollEquipmentManagerPane.scrollBar.thumbTexture:Show() end local scrollOffset = HybridScrollFrame_GetOffset(PaperDollEquipmentManagerPane) local buttons = PaperDollEquipmentManagerPane.buttons local selectedName = PaperDollEquipmentManagerPane.selectedSetName local name, texture, button for i = 1, #buttons do button = buttons[i] if (i + scrollOffset) <= numRows then button:Show() button:Enable() if (i + scrollOffset) <= numSets then name, texture = GetEquipmentSetInfo(i + scrollOffset) button.name = name button.text:SetText(name) button.text:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b) if texture then button.icon:SetTexture(texture) else button.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark") end if selectedName and button.name == selectedName then button.SelectedBar:Show() GearManagerDialog.selectedSet = button else button.SelectedBar:Hide() end else button.name = nil button.text:SetText(L["New Set"]) button.text:SetTextColor(GREEN_FONT_COLOR.r, GREEN_FONT_COLOR.g, GREEN_FONT_COLOR.b) button.icon:SetTexture("Interface\\Icons\\Spell_ChargePositive") button.SelectedBar:Hide() end if (i + scrollOffset) % 2 == 0 then button.Stripe:SetTexture(0.9, 0.9, 1) button.Stripe:SetAlpha(0.1) button.Stripe:Show() else button.Stripe:Hide() end else button:Hide() end end end local EnchantSlots = { {INVSLOT_HEAD, "HEADSLOT"}, {INVSLOT_NECK, "NECKSLOT"}, {INVSLOT_SHOULDER, "SHOULDERSLOT"}, {INVSLOT_CHEST, "CHESTSLOT"}, {INVSLOT_WAIST, "WAISTSLOT"}, {INVSLOT_LEGS, "LEGSSLOT"}, {INVSLOT_FEET, "FEETSLOT"}, {INVSLOT_WRIST, "WRISTSLOT"}, {INVSLOT_HAND, "HANDSSLOT"}, {INVSLOT_FINGER1, "FINGER0SLOT"}, {INVSLOT_FINGER2, "FINGER1SLOT"}, {INVSLOT_TRINKET1, "TRINKET0SLOT"}, {INVSLOT_TRINKET2, "TRINKET1SLOT"}, {INVSLOT_BACK, "BACKSLOT"}, {INVSLOT_MAINHAND, "MAINHANDSLOT"}, {INVSLOT_OFFHAND, "SECONDARYHANDSLOT"}, {INVSLOT_RANGED, "RANGEDSLOT"}, } function module:MysticEnchantPane_Update() HybridScrollFrame_Update(PaperDollMysticEnchantPane, 768, PaperDollMysticEnchantPane:GetHeight()) if not PaperDollMysticEnchantPane.scrollBar.thumbTexture:IsShown() then PaperDollMysticEnchantPane.scrollBar.thumbTexture:Show() end local scrollOffset = HybridScrollFrame_GetOffset(PaperDollMysticEnchantPane) local buttons = PaperDollMysticEnchantPane.buttons local name, texture, button local enchantCount = {} local equippedEnchants = {} for index, slotInfo in ipairs(EnchantSlots) do local enchant = GetInventoryItemMysticEnchant("player", slotInfo[1]) local RE if enchant then RE = GetREData(enchant) if not enchantCount[RE.spellID] then enchantCount[RE.spellID] = 1 else enchantCount[RE.spellID] = enchantCount[RE.spellID] + 1 end end equippedEnchants[index] = { slotID = slotInfo[1], slotName = slotInfo[2], spellID = RE and RE.spellID, quality = RE and RE.quality, limit = RE and RE.stackable, } end for i = 1, #buttons do button = buttons[i] if (i + scrollOffset) <= 17 then button:Show() button:Enable() local slotInfo = equippedEnchants[i + scrollOffset] if slotInfo.spellID then name, _, texture = GetSpellInfo(slotInfo.spellID) if not name then name = "|cffFF0000Unknown Enchant: " .. slotInfo.spellID .. "|r" texture = nil else name = ITEM_QUALITY_COLORS[slotInfo.quality]:WrapText(name) end if enchantCount[slotInfo.spellID] > slotInfo.limit then name = name .. " |cffFF0000" .. enchantCount[slotInfo.spellID] .. "/" .. slotInfo.limit .. "|r" else name = name .. " " .. enchantCount[slotInfo.spellID] .. "/" .. slotInfo.limit end else name = nil texture = select(2, GetInventorySlotInfo(slotInfo.slotName)) end local slotName = _G[slotInfo.slotName] if name then button.name = slotName .. "\n" .. name else button.name = slotName end button.enchant = enchant button.text:SetText(button.name) button.text:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b) if texture then button.icon:SetTexture(texture) else button.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark") end if (i + scrollOffset) % 2 == 0 then button.Stripe:SetTexture(0.9, 0.9, 1) button.Stripe:SetAlpha(0.1) button.Stripe:Show() else button.Stripe:Hide() end else button:Hide() end end end function module:PetPaperDollCompanionPane_Update() local scrollFrame = PetPaperDollCompanionPane local offset = HybridScrollFrame_GetOffset(scrollFrame) local buttons = scrollFrame.buttons local selected, text local button, displayIndex, index local creatureID, creatureName, spellID, icon, active if PetPaperDollFrameCompanionFrame.mode == "CRITTER" then selected = PetPaperDollFrame_FindCompanionIndex(PetPaperDollFrameCompanionFrame.idCritter) text = L["Total Companions"] elseif PetPaperDollFrameCompanionFrame.mode == "MOUNT" then selected = PetPaperDollFrame_FindCompanionIndex(PetPaperDollFrameCompanionFrame.idMount) text = L["Total Mounts"] end local numCompanions = GetNumCompanions(PetPaperDollFrameCompanionFrame.mode) scrollFrame.text:SetFormattedText("%s: %d", text, numCompanions) for i = 1, #buttons do button = buttons[i] displayIndex = i + offset if displayIndex <= numCompanions then index = displayIndex creatureID, creatureName, spellID, icon, active = GetCompanionInfo(PetPaperDollFrameCompanionFrame.mode, index) button:Show() button:SetID(index) _G[button:GetName().."Cooldown"]:SetInside() button.creatureID = creatureID button.spellID = spellID button.active = active if creatureID then button.name:SetText(creatureName) button.icon:SetTexture(icon) button:Enable() local start, duration, enable = GetCompanionCooldown(PetPaperDollFrameCompanionFrame.mode, index) if start and duration and enable then CooldownFrame_SetTimer(_G[button:GetName().."Cooldown"], start, duration, enable) end else button.name:SetText("") _G[button:GetName().."Cooldown"]:Hide() button:Disable() end if (index == selected) and creatureID then button.SelectedBar:Show() button.SelectedBar:SetTexture(1, 1, 1, 0.2) elseif active then button.SelectedBar:Show() button.SelectedBar:SetTexture(1, 1, 0, 0.2) else button.SelectedBar:Hide() end if (i + offset) % 2 == 0 then button.Stripe:SetTexture(0.9, 0.9, 1) button.Stripe:SetAlpha(0.1) button.Stripe:Show() else button.Stripe:Hide() end else button:Hide() end end local totalHeight = numCompanions * 44 HybridScrollFrame_Update(scrollFrame, totalHeight, scrollFrame:GetHeight()) if not scrollFrame.scrollBar.thumbTexture:IsShown() then scrollFrame.scrollBar.thumbTexture:Show() end end function module:UpdateCharacterModelFrame() if not module.Initialized then return end if E.db.enhanced.character.characterBackground then if not CharacterModelFrame.backdrop then CharacterModelFrame:CreateBackdrop() CharacterModelFrame.backdrop:SetAllPoints(CharacterModelFrame) CharacterModelFrame.textureTopLeft = CharacterModelFrame:CreateTexture("$parentTextureTopLeft", "BACKGROUND") CharacterModelFrame.textureTopLeft:Point("TOPLEFT", 1, -1) CharacterModelFrame.textureTopLeft:Size(216, 246) -- texWidth, texHeight, cropWidth, cropHeight, offsetX, offsetY = 256, 256, 216, 248, 40, 8 CharacterModelFrame.textureTopLeft:SetTexCoord(0.15625, 1, 0.03125, 1) CharacterModelFrame.textureTopRight = CharacterModelFrame:CreateTexture("$parentTextureTopRight", "BACKGROUND") CharacterModelFrame.textureTopRight:Point("TOPLEFT", CharacterModelFrame.textureTopLeft, "TOPRIGHT") CharacterModelFrame.textureTopRight:Size(19, 246) -- texWidth, texHeight, cropWidth, cropHeight, offsetX, offsetY = 64, 256, 19, 248, 0, 8 CharacterModelFrame.textureTopRight:SetTexCoord(0, 0.296875, 0.03125, 1) CharacterModelFrame.textureBotLeft = CharacterModelFrame:CreateTexture("$parentTextureBotLeft", "BACKGROUND") CharacterModelFrame.textureBotLeft:Point("TOPLEFT", CharacterModelFrame.textureTopLeft, "BOTTOMLEFT") CharacterModelFrame.textureBotLeft:Size(216, 76) -- texWidth, texHeight, cropWidth, cropHeight, offsetX, offsetY = 256, 128, 216, 76, 40, 0 CharacterModelFrame.textureBotLeft:SetTexCoord(0.15625, 1, 0, 0.59375) CharacterModelFrame.textureBotRight = CharacterModelFrame:CreateTexture("$parentTextureBotRight", "BACKGROUND") CharacterModelFrame.textureBotRight:Point("TOPLEFT", CharacterModelFrame.textureTopLeft, "BOTTOMRIGHT") CharacterModelFrame.textureBotRight:Size(19, 76) -- texWidth, texHeight, cropWidth, cropHeight, offsetX, offsetY = 64, 128, 19, 76, 0, 0 CharacterModelFrame.textureBotRight:SetTexCoord(0, 0.296875, 0, 0.59375) CharacterModelFrame.backgroundOverlay = CharacterModelFrame:CreateTexture("$parentBackgroundOverlay", "BORDER") CharacterModelFrame.backgroundOverlay:SetInside(CharacterModelFrame.backdrop) CharacterModelFrame.backgroundOverlay:SetTexture(0, 0, 0) else CharacterModelFrame.backdrop:Show() end local desaturate = E.db.enhanced.character.desaturateCharacter and true or false local raceEng = lower(E.myrace) CharacterModelFrame.textureTopLeft:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\"..raceEng.."_1.blp") CharacterModelFrame.textureTopLeft:SetDesaturated(desaturate) CharacterModelFrame.textureTopLeft:Show() CharacterModelFrame.textureTopRight:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\"..raceEng.."_2.blp") CharacterModelFrame.textureTopRight:SetDesaturated(desaturate) CharacterModelFrame.textureTopRight:Show() CharacterModelFrame.textureBotLeft:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\"..raceEng.."_3.blp") CharacterModelFrame.textureBotLeft:SetDesaturated(desaturate) CharacterModelFrame.textureBotLeft:Show() CharacterModelFrame.textureBotRight:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\"..raceEng.."_4.blp") CharacterModelFrame.textureBotRight:SetDesaturated(desaturate) CharacterModelFrame.textureBotRight:Show() CharacterModelFrame.backgroundOverlay:Show() if raceEng == "scourge" then CharacterModelFrame.backgroundOverlay:SetAlpha(0.2) elseif raceEng == "bloodelf" or raceEng == "nightelf" then CharacterModelFrame.backgroundOverlay:SetAlpha(0.7) elseif raceEng == "troll" or raceEng == "orc" then CharacterModelFrame.backgroundOverlay:SetAlpha(0.5) else CharacterModelFrame.backgroundOverlay:SetAlpha(0.6) end elseif CharacterModelFrame.textureTopLeft then CharacterModelFrame.backdrop:Hide() CharacterModelFrame.textureTopLeft:Hide() CharacterModelFrame.textureTopRight:Hide() CharacterModelFrame.textureBotLeft:Hide() CharacterModelFrame.textureBotRight:Hide() CharacterModelFrame.backgroundOverlay:Hide() end end function module:UpdateInspectModelFrame() if not module.Initialized or not InspectModelFrame then return end if E.db.enhanced.character.inspectBackground then if not InspectModelFrame.backdrop then InspectModelFrame:CreateBackdrop("Default") InspectModelFrame.backdrop:SetAllPoints(InspectModelFrame) InspectModelFrame.textureTopLeft = InspectModelFrame:CreateTexture("$parentTextureTopLeft", "BACKGROUND") InspectModelFrame.textureTopLeft:Point("TOPLEFT", 1, -1) InspectModelFrame.textureTopLeft:Size(216, 246) -- texWidth, texHeight, cropWidth, cropHeight, offsetX, offsetY = 256, 256, 216, 248, 40, 8 InspectModelFrame.textureTopLeft:SetTexCoord(0.15625, 1, 0.03125, 1) InspectModelFrame.textureTopRight = InspectModelFrame:CreateTexture("$parentTextureTopRight", "BACKGROUND") InspectModelFrame.textureTopRight:Point("TOPLEFT", InspectModelFrame.textureTopLeft, "TOPRIGHT") InspectModelFrame.textureTopRight:Size(19, 246) -- texWidth, texHeight, cropWidth, cropHeight, offsetX, offsetY = 64, 256, 19, 248, 0, 8 InspectModelFrame.textureTopRight:SetTexCoord(0, 0.296875, 0.03125, 1) InspectModelFrame.textureBotLeft = InspectModelFrame:CreateTexture("$parentTextureBotLeft", "BACKGROUND") InspectModelFrame.textureBotLeft:Point("TOPLEFT", InspectModelFrame.textureTopLeft, "BOTTOMLEFT") InspectModelFrame.textureBotLeft:Size(216, 76) -- texWidth, texHeight, cropWidth, cropHeight, offsetX, offsetY = 256, 128, 216, 76, 40, 0 InspectModelFrame.textureBotLeft:SetTexCoord(0.15625, 1, 0, 0.59375) InspectModelFrame.textureBotRight = InspectModelFrame:CreateTexture("$parentTextureBotRight", "BACKGROUND") InspectModelFrame.textureBotRight:Point("TOPLEFT", InspectModelFrame.textureTopLeft, "BOTTOMRIGHT") InspectModelFrame.textureBotRight:Size(19, 76) -- texWidth, texHeight, cropWidth, cropHeight, offsetX, offsetY = 64, 128, 19, 76, 0, 0 InspectModelFrame.textureBotRight:SetTexCoord(0, 0.296875, 0, 0.59375) InspectModelFrame.backgroundOverlay = InspectModelFrame:CreateTexture("$parentBackgroundOverlay", "BORDER") InspectModelFrame.backgroundOverlay:SetInside(InspectModelFrame.backdrop) InspectModelFrame.backgroundOverlay:SetTexture(0, 0, 0) else InspectModelFrame.backdrop:Show() end local _, raceEng = UnitRace(InspectFrame.unit) raceEng = lower(raceEng) local desaturate = E.db.enhanced.character.desaturateInspect and true or false InspectModelFrame.textureTopLeft:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\"..raceEng.."_1.blp") InspectModelFrame.textureTopLeft:SetDesaturated(desaturate) InspectModelFrame.textureTopLeft:Show() InspectModelFrame.textureTopRight:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\"..raceEng.."_2.blp") InspectModelFrame.textureTopRight:SetDesaturated(desaturate) InspectModelFrame.textureTopRight:Show() InspectModelFrame.textureBotLeft:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\"..raceEng.."_3.blp") InspectModelFrame.textureBotLeft:SetDesaturated(desaturate) InspectModelFrame.textureBotLeft:Show() InspectModelFrame.textureBotRight:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\"..raceEng.."_4.blp") InspectModelFrame.textureBotRight:SetDesaturated(desaturate) InspectModelFrame.textureBotRight:Show() InspectModelFrame.backgroundOverlay:Show() if raceEng == "scourge" then InspectModelFrame.backgroundOverlay:SetAlpha(0.2) elseif raceEng == "bloodelf" or raceEng == "nightelf" then InspectModelFrame.backgroundOverlay:SetAlpha(0.7) elseif raceEng == "troll" or raceEng == "orc" then InspectModelFrame.backgroundOverlay:SetAlpha(0.5) else InspectModelFrame.backgroundOverlay:SetAlpha(0.6) end elseif InspectModelFrame.textureTopLeft then InspectModelFrame.backdrop:Hide() InspectModelFrame.textureTopLeft:Hide() InspectModelFrame.textureTopRight:Hide() InspectModelFrame.textureBotLeft:Hide() InspectModelFrame.textureBotRight:Hide() InspectModelFrame.backgroundOverlay:Hide() end end function module:UpdatePetModelFrame() if not module.Initialized then return end if E.db.enhanced.character.petBackground then if not PetModelFrame.backdrop then PetModelFrame:CreateBackdrop("Default") PetModelFrame.backdrop:SetAllPoints(PetModelFrame) PetModelFrame.petPaperDollPetModelBg = PetModelFrame:CreateTexture("$parentPetPaperDollPetModelBg", "BACKGROUND") PetModelFrame.petPaperDollPetModelBg:SetInside(PetModelFrame.backdrop) PetModelFrame.petPaperDollPetModelBg:SetTexCoord(0.00390625, 0.623046875, 0.00390625, 0.689453125) PetModelFrame.backgroundOverlay = PetModelFrame:CreateTexture("$parentBackgroundOverlay", "BORDER") PetModelFrame.backgroundOverlay:SetInside(PetModelFrame.backdrop) PetModelFrame.backgroundOverlay:SetTexture(0, 0, 0) else PetModelFrame.backdrop:Show() end if E.myclass == "HUNTER" then PetModelFrame.petPaperDollPetModelBg:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\petHunter.blp") PetModelFrame.backgroundOverlay:SetAlpha(0.4) elseif E.myclass == "WARLOCK" then PetModelFrame.petPaperDollPetModelBg:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\petWarlock.blp") PetModelFrame.backgroundOverlay:SetAlpha(0.2) elseif E.myclass == "DEATHKNIGHT" then PetModelFrame.petPaperDollPetModelBg:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\petDeathKnight.blp") PetModelFrame.backgroundOverlay:SetAlpha(0.1) else PetModelFrame.petPaperDollPetModelBg:Hide() end PetModelFrame.petPaperDollPetModelBg:SetDesaturated(E.db.enhanced.character.desaturatePet and true or false) PetModelFrame.petPaperDollPetModelBg:Show() PetModelFrame.backgroundOverlay:Show() elseif PetModelFrame.petPaperDollPetModelBg then PetModelFrame.backdrop:Hide() PetModelFrame.petPaperDollPetModelBg:Hide() PetModelFrame.backgroundOverlay:Hide() end end function module:UpdateCompanionModelFrame() if not module.Initialized then return end if E.db.enhanced.character.companionBackground then if not CompanionModelFrame.backdrop then CompanionModelFrame:CreateBackdrop("Default") CompanionModelFrame.backdrop:SetAllPoints(CompanionModelFrame) CompanionModelFrame.backgroundTex = CompanionModelFrame:CreateTexture("$parentBackgroundTex", "BACKGROUND") CompanionModelFrame.backgroundTex:SetTexture("Interface\\AddOns\\ElvUI_Enhanced\\Media\\Textures\\backgrounds\\MountJournal-BG") CompanionModelFrame.backgroundTex:SetInside(CompanionModelFrame.backdrop) CompanionModelFrame.backgroundTex:SetTexCoord(0.00390625, 0.783203125, 0.0078125, 0.984375) CompanionModelFrame.backgroundOverlay = CompanionModelFrame:CreateTexture("$parentBackgroundOverlay", "BORDER") CompanionModelFrame.backgroundOverlay:SetInside(CompanionModelFrame.backdrop) CompanionModelFrame.backgroundOverlay:SetTexture(0, 0, 0) CompanionModelFrame.backgroundOverlay:SetAlpha(0.3) else CompanionModelFrame.backdrop:Show() end CompanionModelFrame.backgroundTex:SetDesaturated(E.db.enhanced.character.desaturateCompanion and true or false) CompanionModelFrame.backgroundTex:Show() CompanionModelFrame.backgroundOverlay:Show() elseif CompanionModelFrame.backgroundTex then CompanionModelFrame.backdrop:Hide() CompanionModelFrame.backgroundTex:Hide() CompanionModelFrame.backgroundOverlay:Hide() end end local function SetScrollValue(self, value) if self.scrollBar.anim:IsPlaying() then self.scrollBar.anim:Stop() end self.scrollBar.anim.progress:SetChange(value) self.scrollBar.anim:Play() end local function Animation_OnMouseWheel(self, delta, stepSize) if not self.scrollBar:IsVisible() then return end self.times = self.times + 1 if self.direction ~= delta then self.direction = delta self.times = 1 end local minVal, maxVal = 0, self.range stepSize = stepSize or self.stepSize or self.buttonHeight or self.scrollBar.scrollStep if delta == 1 then SetScrollValue(self, max(minVal, self.scrollBar:GetValue() - (stepSize * self.times))) else SetScrollValue(self, min(maxVal, self.scrollBar:GetValue() + (stepSize * self.times))) end end local function CreateSmoothScrollAnimation(scrollBar, hybridScroll) if not E.db.enhanced.character.animations then return end local scrollFrame = scrollBar:GetParent() scrollFrame.times = 0 scrollFrame.direction = -1 scrollBar.anim = CreateAnimationGroup(scrollBar) scrollBar.anim.progress = scrollBar.anim:CreateAnimation("Progress") scrollBar.anim.progress:SetSmoothing("Out") scrollBar.anim.progress:SetDuration(0.5) scrollBar.anim.progress:SetScript("OnPlay", function(self) if (self:GetChange() >= self.Parent:GetParent().range) or (self:GetChange() <= 0) then self.Parent:GetParent().times = self.Parent:GetParent().times - 1 end end) scrollBar.anim.progress:SetScript("OnFinished", function(self) self.Parent:GetParent().times = 0 end) scrollFrame:SetScript("OnMouseWheel", Animation_OnMouseWheel) if not hybridScroll then scrollFrame:HookScript("OnScrollRangeChanged", function(self) self.range = select(2, self.scrollBar:GetMinMaxValues()) end) end end function module:Initialize() if not E.private.enhanced.character.enable then return end self.skinEnabled = (E.private.skins.blizzard.enable and E.private.skins.blizzard.character) and true or false if PersonalGearScore then PersonalGearScore:Hide() end if GearScore2 then GearScore2:Hide() end PlayerTitleFrame:Kill() PlayerTitlePickerFrame:Kill() CharacterAttributesFrame:Kill() CharacterResistanceFrame:Kill() GearManagerToggleButton:Kill() SetCVar("equipmentManager", 1) if self.skinEnabled then AscensionCharacterFrame:Hide() CharacterFrameCloseButton:Point("CENTER", CharacterFrame.backdrop, "TOPRIGHT", -12, -13) CharacterFrame.backdrop:ClearAllPoints() CharacterFrame.backdrop:Point("TOPLEFT", 11, -12) CharacterFrame.backdrop:Size(341, 424) S:SetUIPanelWindowInfo(CharacterFrame, "width") S:SetBackdropHitRect(PaperDollFrame, CharacterFrame.backdrop) S:SetBackdropHitRect(PetPaperDollFrame, CharacterFrame.backdrop) S:SetBackdropHitRect(PetPaperDollFrameCompanionFrame, CharacterFrame.backdrop) S:SetBackdropHitRect(PetPaperDollFramePetFrame, CharacterFrame.backdrop) end local function FixHybridScrollBarSkin(frame, h1, h2) frame.scrollUp:Size(18) frame.scrollDown:Size(18) frame.scrollBar.thumbTexture:Size(18, 24) frame.scrollBar.backdrop:Point("TOPLEFT", frame.scrollBar.Thumb, "TOPLEFT", 2, h1 or -5) frame.scrollBar.backdrop:Point("BOTTOMRIGHT", frame.scrollBar.Thumb, "BOTTOMRIGHT", -2, h2 or 1) end local expandButton = CreateFrame("Button", "CharacterFrameExpandButton", CharacterFrame) expandButton:Point("BOTTOMLEFT", CharacterFrame, 325, 85) expandButton:SetFrameLevel(CharacterFrame:GetFrameLevel() + 5) S:HandleNextPrevButton(expandButton) expandButton:Size(19) expandButton:SetScript("OnClick", function(self) if CharacterFrame.Expanded then E.private.enhanced.character.collapsed = true module:CharacterFrame_Collapse() PlaySound("igCharacterInfoClose") else E.private.enhanced.character.collapsed = false module:CharacterFrame_Expand() PlaySound("igCharacterInfoOpen") end if GameTooltip:GetOwner() == self then self:GetScript("OnEnter")(self) end end) expandButton:SetScript("OnEnter", function(self) S.SetModifiedBackdrop(self) GameTooltip:SetOwner(self, "ANCHOR_RIGHT") if CharacterFrame.Expanded then GameTooltip:SetText(self.collapseTooltip) else GameTooltip:SetText(self.expandTooltip) end end) expandButton:SetScript("OnLeave", function(self) S.SetOriginalBackdrop(self) GameTooltip_Hide() end) do -- CharacterFrame local sidebarTabs = CreateFrame("Frame", "PaperDollSidebarTabs", PaperDollFrame) sidebarTabs:Hide() sidebarTabs:Size(152, 35) sidebarTabs:Point("BOTTOMRIGHT", CharacterFrame.backdrop, "TOPRIGHT", -29, -59) local sidebarTabs4 = CreateFrame("Button", "PaperDollSidebarTab4", sidebarTabs) sidebarTabs4:SetID(4) sidebarTabs4:Point("BOTTOMRIGHT", 0, 0) self:PaperDollSidebarTab(sidebarTabs4) local sidebarTabs3 = CreateFrame("Button", "PaperDollSidebarTab3", sidebarTabs) sidebarTabs3:SetID(3) sidebarTabs3:Point("RIGHT", "PaperDollSidebarTab4", "LEFT", -5, 0) self:PaperDollSidebarTab(sidebarTabs3) local sidebarTabs2 = CreateFrame("Button", "PaperDollSidebarTab2", sidebarTabs) sidebarTabs2:SetID(2) sidebarTabs2:Point("RIGHT", "PaperDollSidebarTab3", "LEFT", -5, 0) self:PaperDollSidebarTab(sidebarTabs2) local sidebarTabs1 = CreateFrame("Button", "PaperDollSidebarTab1", sidebarTabs) sidebarTabs1:SetID(1) sidebarTabs1:Point("RIGHT", "PaperDollSidebarTab2", "LEFT", -5, 0) self:PaperDollSidebarTab(sidebarTabs1) sidebarTabs1:RegisterEvent("UNIT_PORTRAIT_UPDATE") sidebarTabs1:RegisterEvent("PLAYER_ENTERING_WORLD") local tcoords = PAPERDOLL_SIDEBARS[1].texCoords sidebarTabs1.Icon:SetTexCoord(tcoords[1], tcoords[2], tcoords[3], tcoords[4]) sidebarTabs1:SetScript("OnEvent", function(self, event, unit) if event == "UNIT_PORTRAIT_UPDATE" then if not unit or unit == "player" then SetPortraitTexture(self.Icon, "player") end elseif event == "PLAYER_ENTERING_WORLD" then SetPortraitTexture(self.Icon, "player") end end) -- -- Title Pane -- local titlePane = CreateFrame("ScrollFrame", "PaperDollTitlesPane", PaperDollFrame, "HybridScrollFrameTemplate") titlePane:Hide() titlePane:Size(169, 350) titlePane:Point("TOPRIGHT", CharacterFrame.backdrop, -29, -64) titlePane.scrollBar = CreateFrame("Slider", "$parentScrollBar", titlePane, "HybridScrollBarTemplate") titlePane.scrollBar:Point("TOPLEFT", titlePane, "TOPRIGHT", 2, -16) titlePane.scrollBar:Point("BOTTOMLEFT", titlePane, "BOTTOMRIGHT", 2, 14) S:HandleScrollBar(titlePane.scrollBar) FixHybridScrollBarSkin(titlePane) CreateSmoothScrollAnimation(titlePane.scrollBar, true) titlePane:SetScript("OnShow", function(self) module:PaperDollTitlesPane_Update() end) titlePane.scrollBar.Show = function(self) titlePane:Width(169) titlePane:Point("TOPRIGHT", CharacterFrame.backdrop, -29, -64) for _, button in next, titlePane.buttons do button:Width(169) end getmetatable(self).__index.Show(self) end titlePane.scrollBar.Hide = function(self) titlePane:Width(190) titlePane:Point("TOPRIGHT", CharacterFrame.backdrop, -8, -64) for _, button in next, titlePane.buttons do button:Width(190) end getmetatable(self).__index.Hide(self) end titlePane:SetFrameLevel(CharacterFrame:GetFrameLevel() + 1) HybridScrollFrame_OnLoad(titlePane) titlePane.update = self.PaperDollTitlesPane_UpdateScrollFrame HybridScrollFrame_CreateButtons(PaperDollTitlesPane, "PlayerTitleButtonTemplate2", 2, -4) local statsPane = CreateFrame("ScrollFrame", "CharacterStatsPane", CharacterFrame, "UIPanelScrollFrameTemplate") statsPane:Hide() statsPane:Size(169, 350) statsPane:Point("TOPRIGHT", CharacterFrame.backdrop, -29, -64) statsPane.Categories = {} statsPane.scrollBar = CharacterStatsPaneScrollBar CharacterStatsPaneScrollBar:Point("TOPLEFT", CharacterStatsPane, "TOPRIGHT", 4, -18) CharacterStatsPaneScrollBar:Point("BOTTOMLEFT", CharacterStatsPane, "BOTTOMRIGHT", 4, 16) S:HandleScrollBar(CharacterStatsPaneScrollBar) CharacterStatsPaneScrollBar.scrollStep = 50 CharacterStatsPane.scrollBarHideable = 1 statsPane:SetScript("OnMouseWheel", function(self, value, scrollBar) scrollBar = scrollBar or self.scrollBar local scrollStep = scrollBar.scrollStep or scrollBar:GetHeight() / 2 if value > 0 then scrollBar:SetValue(scrollBar:GetValue() - scrollStep) else scrollBar:SetValue(scrollBar:GetValue() + scrollStep) end end) CharacterStatsPaneScrollBarScrollUpButton:SetScript("OnClick", function(self) local parent = self:GetParent() local scrollStep = parent.scrollStep or (parent:GetHeight() / 2) parent:SetValue(parent:GetValue() - scrollStep) PlaySound("UChatScrollButton") end) CharacterStatsPaneScrollBarScrollDownButton:SetScript("OnClick", function(self) local parent = self:GetParent() local scrollStep = parent.scrollStep or (parent:GetHeight() / 2) parent:SetValue(parent:GetValue() + scrollStep) PlaySound("UChatScrollButton") end) CreateSmoothScrollAnimation(CharacterStatsPaneScrollBar) -- -- Stats Pane -- local statsPaneScrollChild = CreateFrame("Frame", "CharacterStatsPaneScrollChild", statsPane) statsPaneScrollChild:Size(169, 0) statsPaneScrollChild:Point("TOPLEFT") for i = 1, 12 do local button = CreateFrame("Frame", "CharacterStatsPaneCategory"..i, statsPaneScrollChild) button:Size(169, 0) button.Toolbar = CreateFrame("Button", nil, button) button.Toolbar:RegisterForDrag("LeftButton") button.Toolbar:Size(150, 18) button.Toolbar:Point("TOP") button.Toolbar:SetTemplate("Default", true) button.Toolbar:HookScript("OnEnter", S.SetModifiedBackdrop) button.Toolbar:HookScript("OnLeave", S.SetOriginalBackdrop) button.Toolbar:SetScript("OnClick", function(self) if self:GetParent().collapsed then PaperDollFrame_ExpandStatCategory(self:GetParent()) CharacterStatsPane.collapsedData[self:GetParent().Category] = false else PaperDollFrame_CollapseStatCategory(self:GetParent()) CharacterStatsPane.collapsedData[self:GetParent().Category] = true end end) button.Toolbar:SetScript("OnDragStart", function(self) PaperDollStatCategory_OnDragStart(self:GetParent()) end) button.Toolbar:SetScript("OnDragStop", function(self) PaperDollStatCategory_OnDragStop(self:GetParent()) end) button.NameText = button.Toolbar:CreateFontString(nil, "OVERLAY", "GameFontHighlight") button.NameText:Point("CENTER") button.Stats = {} button.Stats[1] = CreateFrame("Frame", "$parentStat1", button, "CharacterStatFrameTemplate") button.Stats[1]:Point("TOPLEFT", 0, -23) button.Stats[1]:Point("RIGHT", -4, 0) statsPane.Categories[i] = button end statsPane:SetScrollChild(statsPaneScrollChild) CharacterStatsPaneScrollBar.Show = function(self) statsPane:Width(169) statsPane:Point("TOPRIGHT", CharacterFrame.backdrop, -29, -64) for _, button in next, statsPane.Categories do button:Width(169) button.Toolbar:Width(132) end getmetatable(self).__index.Show(self) end CharacterStatsPaneScrollBar.Hide = function(self) statsPane:Width(190) statsPane:Point("TOPRIGHT", CharacterFrame.backdrop, -8, -64) for _, button in next, statsPane.Categories do button:Width(190) button.Toolbar:Width(150) end getmetatable(self).__index.Hide(self) end -- -- Equipment Manager Pane -- local equipmentManagerPane = CreateFrame("ScrollFrame", "PaperDollEquipmentManagerPane", PaperDollFrame, "HybridScrollFrameTemplate") equipmentManagerPane:Hide() equipmentManagerPane:Size(169, 350) equipmentManagerPane:Point("TOPRIGHT", CharacterFrame.backdrop, -29, -64) equipmentManagerPane.EquipSet = CreateFrame("Button", "$parentEquipSet", equipmentManagerPane, "UIPanelButtonTemplate") equipmentManagerPane.EquipSet:SetText(EQUIPSET_EQUIP) equipmentManagerPane.EquipSet:Size(78, 22) equipmentManagerPane.EquipSet:Point("TOPLEFT") S:HandleButton(equipmentManagerPane.EquipSet) equipmentManagerPane.EquipSet:SetScript("OnClick", function() local selectedSetName = PaperDollEquipmentManagerPane.selectedSetName if selectedSetName and selectedSetName ~= "" then PlaySound("igCharacterInfoTab") EquipmentManager_EquipSet(selectedSetName) end end) equipmentManagerPane.SaveSet = CreateFrame("Button", "$parentSaveSet", equipmentManagerPane, "UIPanelButtonTemplate") equipmentManagerPane.SaveSet:SetText(SAVE) equipmentManagerPane.SaveSet:Size(78, 22) equipmentManagerPane.SaveSet:Point("LEFT", "$parentEquipSet", "RIGHT", 3, 0) S:HandleButton(equipmentManagerPane.SaveSet) equipmentManagerPane.SaveSet:SetScript("OnClick", GearManagerDialogSaveSet_OnClick) equipmentManagerPane.SendToBank = CreateFrame("CheckButton", "$parentSendToBank", equipmentManagerPane, "OptionsCheckButtonTemplate") equipmentManagerPane.SendToBank:Size(28, 28) equipmentManagerPane.SendToBank:Point("LEFT", "$parentSaveSet", "RIGHT", 12, 0) S:HandleCheckBox(equipmentManagerPane.SendToBank) equipmentManagerPane.SendToBank.Icon = equipmentManagerPane.SendToBank:CreateTexture(nil, "OVERLAY") equipmentManagerPane.SendToBank.Icon:SetPoint("RIGHT", equipmentManagerPane.SendToBank, "LEFT", 2, 0) equipmentManagerPane.SendToBank.Icon:SetSize(14, 14) equipmentManagerPane.SendToBank.Icon:SetTexture("Interface\\GossipFrame\\BankerGossipIcon") local cvar = C_CVar.GetBool("bankEquipmentManager") equipmentManagerPane.SendToBank:SetChecked(cvar) C_EquipmentSet.SetDstBank(cvar) equipmentManagerPane.SendToBank:SetScript("OnClick", GearManagerDialogSendItemsToBank_OnClick) equipmentManagerPane.SendToBank:SetScript("OnEnter", function(self) GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT") GameTooltip:SetText(EQUIPMENT_MANAGER_STORE_SETS_IN_BANK, 1, 1, 1, 1) GameTooltip:AddLine(EQUIPMENT_MANAGER_STORE_SETS_IN_BANK_TOOLTIP, 1, 0.82, 0, true) GameTooltip:Show() end) equipmentManagerPane.SendToBank:SetScript("OnLeave", GameTooltip_Hide) equipmentManagerPane.scrollBar = CreateFrame("Slider", "$parentScrollBar", equipmentManagerPane, "HybridScrollBarTemplate") equipmentManagerPane.scrollBar:Point("TOPLEFT", equipmentManagerPane, "TOPRIGHT", 2, -16) equipmentManagerPane.scrollBar:Point("BOTTOMLEFT", equipmentManagerPane, "BOTTOMRIGHT", 2, 14) S:HandleScrollBar(equipmentManagerPane.scrollBar) FixHybridScrollBarSkin(equipmentManagerPane) CreateSmoothScrollAnimation(equipmentManagerPane.scrollBar, true) equipmentManagerPane.scrollBar.Show = function(self) equipmentManagerPane.EquipSet:Width(64) equipmentManagerPane.SaveSet:Width(64) equipmentManagerPane:Width(169) equipmentManagerPane:Point("TOPRIGHT", CharacterFrame.backdrop, -29, -64) for _, button in next, equipmentManagerPane.buttons do button:Width(169) end getmetatable(self).__index.Show(self) end equipmentManagerPane.scrollBar.Hide = function(self) equipmentManagerPane.EquipSet:Width(76) equipmentManagerPane.SaveSet:Width(76) equipmentManagerPane:Width(190) equipmentManagerPane:Point("TOPRIGHT", CharacterFrame.backdrop, -8, -64) for _, button in next, equipmentManagerPane.buttons do button:Width(190) end getmetatable(self).__index.Hide(self) end equipmentManagerPane:SetFrameLevel(CharacterFrame:GetFrameLevel() + 1) equipmentManagerPane.EquipSet:SetFrameLevel(equipmentManagerPane:GetFrameLevel() + 3) equipmentManagerPane.SaveSet:SetFrameLevel(equipmentManagerPane:GetFrameLevel() + 3) HybridScrollFrame_OnLoad(equipmentManagerPane) equipmentManagerPane.update = self.PaperDollEquipmentManagerPane_Update HybridScrollFrame_CreateButtons(equipmentManagerPane, "GearSetButtonTemplate2", 2, -(equipmentManagerPane.EquipSet:GetHeight() + 4)) equipmentManagerPane:RegisterEvent("EQUIPMENT_SWAP_FINISHED") equipmentManagerPane:RegisterEvent("EQUIPMENT_SETS_CHANGED") equipmentManagerPane:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") equipmentManagerPane:RegisterEvent("BAG_UPDATE") equipmentManagerPane:SetScript("OnShow", function(self) module:PaperDollEquipmentManagerPane_Update() PaperDollFrameItemPopoutButton_ShowAll() end) equipmentManagerPane:SetScript("OnHide", function() PaperDollFrame_ClearIgnoredSlots() PaperDollFrameItemPopoutButton_HideAll() GearManagerDialogPopup:Hide() StaticPopup_Hide("CONFIRM_SAVE_EQUIPMENT_SET") StaticPopup_Hide("CONFIRM_OVERWRITE_EQUIPMENT_SET") end) equipmentManagerPane:SetScript("OnEvent", function(self, event, ...) if event == "EQUIPMENT_SWAP_FINISHED" then local completed, setName = ... if completed then if self:IsShown() then self.selectedSetName = setName module:PaperDollEquipmentManagerPane_Update() end end end if self:IsShown() then if event == "EQUIPMENT_SETS_CHANGED" then module:PaperDollEquipmentManagerPane_Update() elseif event == "PLAYER_EQUIPMENT_CHANGED" or event == "BAG_UPDATE" then self.queuedUpdate = true end end end) equipmentManagerPane:SetScript("OnUpdate", function(self) for i = 1, #self.buttons do local button = self.buttons[i] if button:IsMouseOver() then if button.name then button.DeleteButton:Show() button.EditButton:Show() else button.DeleteButton:Hide() button.EditButton:Hide() end button.HighlightBar:Show() else button.DeleteButton:Hide() button.EditButton:Hide() button.HighlightBar:Hide() end end if self.queuedUpdate then module:PaperDollEquipmentManagerPane_Update() self.queuedUpdate = false end end) GearManagerDialogPopup:SetParent(PaperDollFrame) GearManagerDialogPopup:ClearAllPoints() GearManagerDialogPopup:Point("BOTTOMLEFT", CharacterFrame.backdrop, "BOTTOMRIGHT", -6, -8) -- -- Mystic Enchants Pane -- local mysticEnchantPane = CreateFrame("ScrollFrame", "PaperDollMysticEnchantPane", PaperDollFrame, "HybridScrollFrameTemplate") mysticEnchantPane:Hide() mysticEnchantPane:Size(169, 350) mysticEnchantPane.scrollBar = CreateFrame("Slider", "$parentScrollBar", mysticEnchantPane, "HybridScrollBarTemplate") mysticEnchantPane.scrollBar:Point("TOPLEFT", mysticEnchantPane, "TOPRIGHT", 2, -16) mysticEnchantPane.scrollBar:Point("BOTTOMLEFT", mysticEnchantPane, "BOTTOMRIGHT", 2, 14) S:HandleScrollBar(mysticEnchantPane.scrollBar) FixHybridScrollBarSkin(mysticEnchantPane) CreateSmoothScrollAnimation(mysticEnchantPane.scrollBar, true) mysticEnchantPane:SetScript("OnShow", function(self) module:MysticEnchantPane_Update() end) mysticEnchantPane.scrollBar.Show = function(self) mysticEnchantPane:Width(169) mysticEnchantPane:Point("TOPRIGHT", CharacterFrame.backdrop, -29, -64) for _, button in next, mysticEnchantPane.buttons do button:Width(169) end getmetatable(self).__index.Show(self) end mysticEnchantPane.scrollBar.Hide = function(self) mysticEnchantPane:Width(190) mysticEnchantPane:Point("TOPRIGHT", CharacterFrame.backdrop, -8, -64) for _, button in next, mysticEnchantPane.buttons do button:Width(190) end getmetatable(self).__index.Hide(self) end mysticEnchantPane:SetFrameLevel(CharacterFrame:GetFrameLevel() + 1) HybridScrollFrame_OnLoad(mysticEnchantPane) mysticEnchantPane.update = self.MysticEnchantPane_Update HybridScrollFrame_CreateButtons(PaperDollMysticEnchantPane, "MysticEnchantButtonTemplate2", 2, -4) CharacterModelFrame:Size(237, 324) if not E.private.enhanced.character.player.orderName2 then E.private.enhanced.character.player.orderName2 = E.private.enhanced.character.player.orderName E.private.enhanced.character.player.collapsedName2 = table.copy(E.private.enhanced.character.player.collapsedName) end if C_Player:IsDefaultClass() then -- default class has no primary stat PAPERDOLL_STATCATEGORIES["PRIMARY_STAT"] = nil PAPERDOLL_STATINFO["PRIMARY_STAT"] = nil table.RemoveItem(PAPERDOLL_STATCATEGORY_DEFAULTORDER, "PRIMARY_STAT") end local activeSpec = GetActiveTalentGroup() if activeSpec == 1 then self:PaperDoll_InitStatCategories(PAPERDOLL_STATCATEGORY_DEFAULTORDER, E.private.enhanced.character.player.orderName, E.private.enhanced.character.player.collapsedName, "player") else self:PaperDoll_InitStatCategories(PAPERDOLL_STATCATEGORY_DEFAULTORDER, E.private.enhanced.character.player.orderName2, E.private.enhanced.character.player.collapsedName2, "player") end PaperDollFrame:RegisterEvent("PLAYER_TALENT_UPDATE") PaperDollFrame:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED") PaperDollFrame:SetScript("OnEvent", function(self, event, unit) if event == "PLAYER_ENTERING_WORLD" or (event == "UNIT_MODEL_CHANGED" and unit == "player") then CharacterModelFrame:SetUnit("player") return elseif event == "KNOWN_TITLES_UPDATE" or (event == "UNIT_NAME_UPDATE" and unit == "player") then if PaperDollTitlesPane:IsShown() then module:PaperDollTitlesPane_Update() end end if not self:IsVisible() then return end if unit == "player" then if event == "UNIT_LEVEL" then module:PaperDollFrame_SetLevel() elseif event == "UNIT_DAMAGE" or event == "PLAYER_DAMAGE_DONE_MODS" or event == "UNIT_ATTACK_SPEED" or event == "UNIT_RANGEDDAMAGE" or event == "UNIT_ATTACK" or event == "UNIT_STATS" or event == "UNIT_RANGED_ATTACK_POWER" or event == "UNIT_RESISTANCES" then self:SetScript("OnUpdate", PaperDollFrame_QueuedUpdate) end end if event == "COMBAT_RATING_UPDATE" then self:SetScript("OnUpdate", PaperDollFrame_QueuedUpdate) elseif event == "PLAYER_TALENT_UPDATE" then module:PaperDollFrame_SetLevel() elseif event == "ACTIVE_TALENT_GROUP_CHANGED" then if GetActiveTalentGroup() == 1 then module:PaperDoll_InitStatCategories(PAPERDOLL_STATCATEGORY_DEFAULTORDER, E.private.enhanced.character.player.orderName, E.private.enhanced.character.player.collapsedName, "player") else module:PaperDoll_InitStatCategories(PAPERDOLL_STATCATEGORY_DEFAULTORDER, E.private.enhanced.character.player.orderName2, E.private.enhanced.character.player.collapsedName2, "player") end end end) PaperDollFrame:SetScript("OnShow", function() module:PaperDollFrame_SetLevel() -- Include Hit Rating Adjustments C_Cache:QueryAllStats() if UnitHasRelicSlot("player") then CharacterAmmoSlot:Hide() else CharacterAmmoSlot:Show() end if PaperDollFrame.currentSideBarID == 2 then module:PaperDollTitlesPane_Update() end if GetActiveTalentGroup() == 1 then module:PaperDoll_InitStatCategories(PAPERDOLL_STATCATEGORY_DEFAULTORDER, E.private.enhanced.character.player.orderName, E.private.enhanced.character.player.collapsedName, "player") else module:PaperDoll_InitStatCategories(PAPERDOLL_STATCATEGORY_DEFAULTORDER, E.private.enhanced.character.player.orderName2, E.private.enhanced.character.player.collapsedName2, "player") end if E.private.enhanced.character.collapsed then module:CharacterFrame_Collapse() else module:CharacterFrame_Expand() end CharacterFrameExpandButton:Show() CharacterFrameExpandButton.collapseTooltip = L["Hide Character Information"] CharacterFrameExpandButton.expandTooltip = L["Show Character Information"] end) PaperDollFrame:SetScript("OnHide", function(self) module:CharacterFrame_Collapse() CharacterFrameExpandButton:Hide() if MOVING_STAT_CATEGORY then PaperDollStatCategory_OnDragStop(MOVING_STAT_CATEGORY) end end) hooksecurefunc("PaperDollFrame_UpdateStats", function() module:PaperDollFrame_UpdateStats() end) end do -- PetFrame PetNameText:ClearAllPoints() PetNameText:Point("CENTER", CharacterFrame.backdrop, 0, 200) PetLevelText:ClearAllPoints() PetLevelText:Point("TOP", CharacterFrame.backdrop, 0, -20) PetPaperDollCloseButton:Kill() PetAttributesFrame:Kill() PetResistanceFrame:Kill() PetModelFrame:Size(325, 324) PetModelFrame:Point("TOPLEFT", 19, -76) PetModelFrameRotateLeftButton:Point("TOPLEFT", PetPaperDollFrame, "TOPLEFT", 23, -80) PetPaperDollFrameExpBar:Width(297) PetPaperDollFrameExpBar:Point("BOTTOMLEFT", 20, 88) self:PaperDoll_InitStatCategories(PETPAPERDOLL_STATCATEGORY_DEFAULTORDER, E.private.enhanced.character.pet.orderName, E.private.enhanced.character.pet.collapsedName, "pet") PetPaperDollFrame:SetScript("OnEvent", function(self, event, unit) if event == "PET_UI_UPDATE" or event == "PET_UI_CLOSE" or event == "PET_BAR_UPDATE" or (event == "UNIT_PET" and unit == "player") or (event == "UNIT_NAME_UPDATE" and unit == "pet") then PetPaperDollFrame_UpdateTabs() if self:IsVisible() then self:SetScript("OnUpdate", PetPaperDollFrame_QueuedUpdate) end elseif event == "UNIT_PET_EXPERIENCE" then PetExpBar_Update() elseif event == "COMPANION_UPDATE" then if not PetPaperDollFrameCompanionFrame.idMount then PetPaperDollFrameCompanionFrame.idMount = GetCompanionInfo("MOUNT", 1) end if not PetPaperDollFrameCompanionFrame.idCritter then PetPaperDollFrameCompanionFrame.idCritter = GetCompanionInfo("CRITTER", 1) end if PetPaperDollFrameCompanionFrame:IsVisible() then module:PetPaperDollCompanionPane_Update() end elseif event == "COMPANION_LEARNED" then if not CharacterFrame:IsVisible() then SetButtonPulse(CharacterMicroButton, 60, 1) end if not PetPaperDollFrame:IsVisible() then SetButtonPulse(CharacterFrameTab2, 60, 1) end if self:IsVisible() then PetPaperDollFrame_UpdateTabs() module:PetPaperDollCompanionPane_Update() end elseif event == "COMPANION_UNLEARNED" then if self:IsVisible() then PetPaperDollFrame_UpdateTabs() module:PetPaperDollCompanionPane_Update() end elseif event == "SPELL_UPDATE_COOLDOWN" then if PetPaperDollFrameCompanionFrame:IsVisible() then PetPaperDollFrame_UpdateCompanionCooldowns() end elseif ((event == "UNIT_ENTERED_VEHICLE" or event == "UNIT_EXITED_VEHICLE") and unit == "player") then module:PetPaperDollCompanionPane_Update() elseif event == "PET_SPELL_POWER_UPDATE" then if self:IsVisible() then self:SetScript("OnUpdate", PetPaperDollFrame_QueuedUpdate) end elseif unit == "pet" then if self:IsVisible() then self:SetScript("OnUpdate", PetPaperDollFrame_QueuedUpdate) end end end) PetPaperDollFramePetFrame:HookScript("OnShow", function() if E.private.enhanced.character.collapsed then module:CharacterFrame_Collapse() else module:CharacterFrame_Expand() end CharacterFrameExpandButton:Show() CharacterFrameExpandButton.collapseTooltip = L["Hide Pet Information"] CharacterFrameExpandButton.expandTooltip = L["Show Pet Information"] module:PaperDoll_InitStatCategories(PETPAPERDOLL_STATCATEGORY_DEFAULTORDER, E.private.enhanced.character.pet.orderName, E.private.enhanced.character.pet.collapsedName, "pet") module:PaperDollFrame_UpdateStats() end) PetPaperDollFramePetFrame:HookScript("OnHide", function() if PaperDollFrame:IsShown() then return end module:CharacterFrame_Collapse() CharacterFrameExpandButton:Hide() end) end do -- CompanionFrame CompanionModelFrame:Size(325, 352) CompanionModelFrame:Point("TOPLEFT", 19, -76) CompanionModelFrameRotateLeftButton:Point("TOPLEFT", PetPaperDollFrame, "TOPLEFT", 23, -80) CompanionSelectedName:ClearAllPoints() CompanionSelectedName:Point("BOTTOM", CompanionModelFrame, "BOTTOM", 0, 10) CompanionSelectedName:SetParent(CompanionModelFrame) CompanionSelectedName:SetTextColor(1, 1, 1) CompanionPageNumber:Kill() CompanionSummonButton:Kill() for i = 1, 12 do _G["CompanionButton"..i]:Kill() _G["CompanionButton"..i].Disable = E.noop _G["CompanionButton"..i].Enable = E.noop end CompanionPrevPageButton:Kill() CompanionNextPageButton:Kill() local companionPane = CreateFrame("ScrollFrame", "PetPaperDollCompanionPane", PetPaperDollFrameCompanionFrame, "HybridScrollFrameTemplate") companionPane:Hide() companionPane:Size(169, 350) companionPane:Point("TOPRIGHT", CharacterFrame.backdrop, -29, -64) companionPane.text = companionPane:CreateFontString(nil, "OVERLAY") companionPane.text:Size(169, 20) companionPane.text:Point("BOTTOM", PetPaperDollCompanionPane, "TOP", 0, 7) companionPane.text:FontTemplate() companionPane.scrollBar = CreateFrame("Slider", "$parentScrollBar", companionPane, "HybridScrollBarTemplate") companionPane.scrollBar:Point("TOPLEFT", companionPane, "TOPRIGHT", 2, -16) companionPane.scrollBar:Point("BOTTOMLEFT", companionPane, "BOTTOMRIGHT", 2, 14) S:HandleScrollBar(companionPane.scrollBar) FixHybridScrollBarSkin(companionPane) CreateSmoothScrollAnimation(companionPane.scrollBar, true) companionPane.scrollBar.Show = function(self) companionPane:Width(169) companionPane:Point("TOPRIGHT", CharacterFrame.backdrop, -29, -64) for _, button in next, companionPane.buttons do button:Width(169) end getmetatable(self).__index.Show(self) end companionPane.scrollBar.Hide = function(self) companionPane:Width(190) companionPane:Point("TOPRIGHT", CharacterFrame.backdrop, -8, -64) for _, button in next, companionPane.buttons do button:Width(190) end getmetatable(self).__index.Hide(self) end companionPane.update = self.PetPaperDollCompanionPane_Update HybridScrollFrame_CreateButtons(companionPane, "CompanionButtonTemplate2", 2) PetPaperDollFrameCompanionFrame:HookScript("OnShow", function(self) if not CharacterFrame.Expanded then module:CharacterFrame_Expand(true) end module:PetPaperDollCompanionPane_Update() end) PetPaperDollFrameCompanionFrame:HookScript("OnHide", function(self) if PaperDollFrame:IsShown() or PetPaperDollFramePetFrame:IsShown() then return end module:CharacterFrame_Collapse(true) end) end hooksecurefunc("PetPaperDollFrame_SetTab", function(id) if id == 1 and HasPetUI() then PetPaperDollCompanionPane:Hide() elseif (id == 2 and GetNumCompanions("CRITTER") > 0) or (id == 3 and GetNumCompanions("MOUNT") > 0) then PetPaperDollCompanionPane:Show() module:PetPaperDollCompanionPane_Update() end end) self.Initialized = true self:UpdateCharacterModelFrame() self:UpdatePetModelFrame() self:UpdateCompanionModelFrame() self:RegisterEvent("ADDON_LOADED", function(event, addon) if addon == "Blizzard_InspectUI" then module:UnregisterEvent(event) module:SecureHook("InspectFrame_UpdateTalentTab", "UpdateInspectModelFrame") end end) end local function InitializeCallback() module:Initialize() end E:RegisterModule(module:GetName(), InitializeCallback)