diff --git a/ElvUI_SLE/modules/characterframe/characterframe.lua b/ElvUI_SLE/modules/characterframe/characterframe.lua new file mode 100644 index 0000000..3500f6c --- /dev/null +++ b/ElvUI_SLE/modules/characterframe/characterframe.lua @@ -0,0 +1,615 @@ +local E, L, V, P, G, _ = unpack(ElvUI); +-- local CFO = E:NewModule('CharacterFrameOptions', 'AceEvent-3.0'); +local CFO = E:GetModule('CharacterFrameOptions'); +local LSM = LibStub("LibSharedMedia-3.0") + +local f = CreateFrame('Frame', 'KnightArmory', PaperDollFrame) +local C = SLArmoryConstants +local backgrounds = { + ["SPACE"] = "Space", + ["ALLIANCE"] = "Alliance-text", + ["HORDE"] = "Horde-text", + ["EMPIRE"] = "TheEmpire", + ["CASTLE"] = "Castle", +} + +local function GemSocket_OnClick(self, button) + self = self:GetParent() + + if CursorHasItem() then + local CursorType, _, ItemLink = GetCursorInfo() + + -- Check cursor item is gem type + if CursorType == 'item' and select(6, GetItemInfo(ItemLink)) == select(8, GetAuctionItemClasses()) then + SocketInventoryItem(GetInventorySlotInfo(self.slotName)) + ClickSocketButton(self.socketNumber) + + return + end + end + + if self.GemItemID then + local itemName, itemLink = GetItemInfo(self.GemItemID) + + if not IsShiftKeyDown() then + SetItemRef(itemLink, itemLink, 'LeftButton') + else + if button == 'RightButton' then + SocketInventoryItem(GetInventorySlotInfo(self.slotName)) + elseif HandleModifiedItemClick(itemLink) then + elseif BrowseName and BrowseName:IsVisible() then + AuctionFrameBrowse_Reset(BrowseResetButton) + BrowseName:SetText(itemName) + BrowseName:SetFocus() + end + end + end +end + +local function GemSocket_OnRecieveDrag(self) + self = self:GetParent() + + if CursorHasItem() then + local CursorType, _, ItemLink = GetCursorInfo() + + if CursorType == 'item' and select(6, GetItemInfo(ItemLink)) == select(8, GetAuctionItemClasses()) then + SocketInventoryItem(GetInventorySlotInfo(self.slotName)) + ClickSocketButton(self.socketNumber) + end + end +end + +local function CreateArmoryFrame(self) + --<< Core >>-- + self:Point('TOPLEFT', CharacterFrameInset, 10, 20) + self:Point('BOTTOMRIGHT', CharacterFrameInsetRight, 'BOTTOMLEFT', -10, 5) + + --<< Background >>-- + self.BG = self:CreateTexture(nil, 'BACKGROUND') + --self.BG:SetInside() + self.BG:SetPoint("TOPLEFT", self, "TOPLEFT", -7, -20) + self.BG:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 7, 2) + + --<< Change Model Frame's frameLevel >>-- + CharacterModelFrame:SetFrameLevel(self:GetFrameLevel() + 2) + + --<< Average Item Level >>-- + C.Toolkit.TextSetting(self, nil, { ['Tag'] = 'AverageItemLevel', ['FontSize'] = 12, }, 'BOTTOM', CharacterModelFrame, 'TOP', 0, 14) + local function ValueColorUpdate() + self.AverageItemLevel:SetText(C.Toolkit.Color_Value(L['Average'])..': '..format('%.2f', select(2, GetAverageItemLevel()))) + end + E.valueColorUpdateFuncs[ValueColorUpdate] = true + + -- Create each equipment slots gradation, text, gem socket icon. + local Slot + for i, slotName in pairs(C.GearList) do + -- Equipment Tag + Slot = CreateFrame('Frame', nil, self) + Slot:Size(130, 41) + Slot:SetFrameLevel(CharacterModelFrame:GetFrameLevel() + 1) + Slot.Direction = i%2 == 1 and 'LEFT' or 'RIGHT' + Slot.ID, Slot.EmptyTexture = GetInventorySlotInfo(slotName) + Slot:Point(Slot.Direction, _G['Character'..slotName], Slot.Direction == 'LEFT' and -1 or 1, 0) + + -- Grow each equipment slot's frame level + _G['Character'..slotName]:SetFrameLevel(Slot:GetFrameLevel() + 1) + + -- Gradation + Slot.Gradation = Slot:CreateTexture(nil, 'OVERLAY') + Slot.Gradation:SetInside() + Slot.Gradation:SetTexture('Interface\\AddOns\\ElvUI_SLE\\media\\textures\\Gradation') + + if Slot.Direction == 'LEFT' then + Slot.Gradation:SetTexCoord(0, .5, 0, .5) + else + Slot.Gradation:SetTexCoord(.5, 1, 0, .5) + end + + if slotName ~= 'ShirtSlot' and slotName ~= 'TabardSlot' then + -- Item Level + C.Toolkit.TextSetting(Slot, nil, { ['Tag'] = 'ItemLevel', ['FontSize'] = 10, ['directionH'] = Slot.Direction, }, 'TOP'..Slot.Direction, _G['Character'..slotName], 'TOP'..(Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 2 or -2, -1) + + -- Enchantment Name + C.Toolkit.TextSetting(Slot, nil, { ['Tag'] = 'ItemEnchant', ['FontSize'] = 8, ['directionH'] = Slot.Direction, }, Slot.Direction, _G['Character'..slotName], Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT', Slot.Direction == 'LEFT' and 2 or -2, 1) + Slot.EnchantWarning = CreateFrame('Button', nil, Slot) + Slot.EnchantWarning:Size(E.db.sle.characterframeoptions.itemenchant.warningSize) + Slot.EnchantWarning.Texture = Slot.EnchantWarning:CreateTexture(nil, 'OVERLAY') + Slot.EnchantWarning.Texture:SetInside() + Slot.EnchantWarning.Texture:SetTexture('Interface\\AddOns\\ElvUI_SLE\\media\\textures\\Warning-Small') + Slot.EnchantWarning:Point(Slot.Direction, Slot.ItemEnchant, Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT', Slot.Direction == 'LEFT' and 3 or -3, 0) + Slot.EnchantWarning:SetScript('OnEnter', C.CommonScript.OnEnter) + Slot.EnchantWarning:SetScript('OnLeave', C.CommonScript.OnLeave) + + -- Durability + C.Toolkit.TextSetting(Slot, nil, { ['Tag'] = 'Durability', ['FontSize'] = 10, ['directionH'] = Slot.Direction, }, 'BOTTOM'..Slot.Direction, _G['Character'..slotName], 'BOTTOM'..(Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 2 or -2, 3) + + -- Gem Socket + for i = 1, MAX_NUM_SOCKETS do + Slot['Socket'..i] = CreateFrame('Frame', nil, Slot) + Slot['Socket'..i]:Size(E.db.sle.characterframeoptions.itemgem.socketSize) + Slot['Socket'..i]:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + Slot['Socket'..i]:SetBackdropColor(0, 0, 0, 1) + Slot['Socket'..i]:SetBackdropBorderColor(0, 0, 0) + Slot['Socket'..i]:SetFrameLevel(CharacterModelFrame:GetFrameLevel() + 1) + + Slot['Socket'..i].slotName = slotName + Slot['Socket'..i].socketNumber = i + + Slot['Socket'..i].Socket = CreateFrame('Button', nil, Slot['Socket'..i]) + Slot['Socket'..i].Socket:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + Slot['Socket'..i].Socket:SetInside() + Slot['Socket'..i].Socket:SetFrameLevel(Slot['Socket'..i]:GetFrameLevel() + 1) + Slot['Socket'..i].Socket:RegisterForClicks('AnyUp') + Slot['Socket'..i].Socket:SetScript('OnEnter', C.CommonScript.OnEnter) + Slot['Socket'..i].Socket:SetScript('OnLeave', C.CommonScript.OnLeave) + Slot['Socket'..i].Socket:SetScript('OnClick', GemSocket_OnClick) + Slot['Socket'..i].Socket:SetScript('OnReceiveDrag', GemSocket_OnRecieveDrag) + + Slot['Socket'..i].Texture = Slot['Socket'..i].Socket:CreateTexture(nil, 'OVERLAY') + Slot['Socket'..i].Texture:SetTexCoord(.1, .9, .1, .9) + Slot['Socket'..i].Texture:SetInside() + end + + Slot.Socket2:Point(Slot.Direction, Slot.Socket1, Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT', Slot.Direction == 'LEFT' and 1 or -1, 0) + Slot.Socket3:Point(Slot.Direction, Slot.Socket2, Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT', Slot.Direction == 'LEFT' and 1 or -1, 0) + + Slot.SocketWarning = CreateFrame('Button', nil, Slot) + Slot.SocketWarning:Size(E.db.sle.characterframeoptions.itemgem.warningSize) + Slot.SocketWarning:RegisterForClicks('AnyUp') + Slot.SocketWarning.Texture = Slot.SocketWarning:CreateTexture(nil, 'OVERLAY') + Slot.SocketWarning.Texture:SetInside() + Slot.SocketWarning.Texture:SetTexture('Interface\\AddOns\\ElvUI_SLE\\media\\textures\\Warning-Small') + Slot.SocketWarning:SetScript('OnEnter', C.CommonScript.OnEnter) + Slot.SocketWarning:SetScript('OnLeave', C.CommonScript.OnLeave) + end + + self[slotName] = Slot + end + + -- GameTooltip for counting gem sockets and getting enchant effects + self.ScanTTForEnchanting1 = CreateFrame('GameTooltip', 'KnightArmoryScanTT_E1', nil, 'GameTooltipTemplate') + self.ScanTTForEnchanting1:SetOwner(UIParent, 'ANCHOR_NONE') + + -- GameTooltip for checking that texture in tooltip is socket texture + self.ScanTTForEnchanting2 = CreateFrame('GameTooltip', 'KnightArmoryScanTT_E2', nil, 'GameTooltipTemplate') + self.ScanTTForEnchanting2:SetOwner(UIParent, 'ANCHOR_NONE') + + -- For resizing paper doll frame when it toggled. + self.ChangeCharacterFrameWidth = CreateFrame('Frame') + self.ChangeCharacterFrameWidth:SetScript('OnShow', function() if PaperDollFrame:IsVisible() then PANEL_DEFAULT_WIDTH = 448 CFO:ArmoryFrame_DataSetting() end end) + self.ChangeCharacterFrameWidth:SetScript('OnHide', function() PANEL_DEFAULT_WIDTH = 338 end) + + CreateArmoryFrame = nil +end + +function CFO:ChangeGradiantVisibility() + for _, slotName in pairs(C.GearList) do + if E.db.sle.characterframeoptions.shownormalgradient ~= false then + f[slotName].Gradation:Show() + else + f[slotName].Gradation:Hide() + end + end +end + +function CFO:ResizeErrorIcon() + for _, slotName in pairs(C.GearList) do + if slotName ~= 'ShirtSlot' and slotName ~= 'TabardSlot' then + f[slotName].SocketWarning:Size(E.db.sle.characterframeoptions.itemgem.warningSize) + f[slotName].EnchantWarning:Size(E.db.sle.characterframeoptions.itemenchant.warningSize) + for i = 1, MAX_NUM_SOCKETS do + f[slotName]['Socket'..i]:Size(E.db.sle.characterframeoptions.itemgem.socketSize) + end + end + end +end + +function CFO:ArmoryFrame_DataSetting() + if not f:IsVisible() then return end + local BGdrop = E.db.sle.characterframeoptions.image.dropdown + + -- Get Player Profession + local Prof1, Prof2 = GetProfessions() + local Prof1_Level, Prof2_Level = 0, 0 + CFO.PlayerProfession = {} + + if Prof1 then Prof1, _, Prof1_Level = GetProfessionInfo(Prof1) end + if Prof2 then Prof2, _, Prof2_Level = GetProfessionInfo(Prof2) end + if Prof1 and C.ProfessionList[Prof1] then CFO.PlayerProfession[(C.ProfessionList[Prof1].Key)] = Prof1_Level end + if Prof2 and C.ProfessionList[Prof2] then CFO.PlayerProfession[(C.ProfessionList[Prof2].Key)] = Prof2_Level end + + local ErrorDetected + local r, g, b + local Slot, ItemLink, ItemRarity, BasicItemLevel, TrueItemLevel, ItemUpgradeID, ItemTexture, IsEnchanted, UsableEffect, CurrentLineText, GemID, GemTotal_1, GemTotal_2, GemCount, CurrentDurability, MaxDurability + local arg1, itemID, enchantID, _, _, _, _, arg2, arg3, arg4, arg5, arg6 + + for _, slotName in pairs(C.GearList) do + if not (slotName == 'ShirtSlot' or slotName == 'TabardSlot') then + Slot = f[slotName] + Slot:EnableMouse(true) + + do --<< Clear Setting >>-- + ErrorDetected, TrueItemLevel, IsEnchanted, UsableEffect, ItemRarity, ItemUpgradeID, ItemTexture = nil, nil, nil, nil, nil, nil, nil + + Slot.ItemLevel:SetText(nil) + Slot.ItemEnchant:SetText(nil) + Slot.Durability:SetText('') + for i = 1, MAX_NUM_SOCKETS do + Slot['Socket'..i].Texture:SetTexture(nil) + Slot['Socket'..i].Socket.Link = nil + Slot['Socket'..i].GemItemID = nil + Slot['Socket'..i].GemType = nil + Slot['Socket'..i]:Hide() + end + + Slot.Socket1:Point('BOTTOM'..Slot.Direction, _G['Character'..slotName], 'BOTTOM'..(Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 3 or -3, 0) + Slot.EnchantWarning:Hide() + Slot.EnchantWarning.Message = nil + Slot.SocketWarning:Point(Slot.Direction, Slot.Socket1) + Slot.SocketWarning:Hide() + Slot.SocketWarning.Link = nil + Slot.SocketWarning.Message = nil + + f.ScanTTForEnchanting1:ClearLines() + f.ScanTTForEnchanting2:ClearLines() + for i = 1, 10 do + _G['KnightArmoryScanTT_E1Texture'..i]:SetTexture(nil) + _G['KnightArmoryScanTT_E2Texture'..i]:SetTexture(nil) + end + end + + ItemLink = GetInventoryItemLink('player', Slot.ID) + + if ItemLink then + do --<< Gem Parts >>-- + arg1, itemID, enchantID, _, _, _, _, arg2, arg3, arg4, arg5, arg6 = strsplit(':', ItemLink) + + f.ScanTTForEnchanting1:SetInventoryItem('player', Slot.ID) + f.ScanTTForEnchanting2:SetHyperlink(format('%s:%s:%d:0:0:0:0:%s:%s:%s:%s:%s', arg1, itemID, enchantID, arg2, arg3, arg4, arg5, arg6)) + + GemTotal_1, GemTotal_2, GemCount = 0, 0, 0 + + -- First, Counting default gem sockets + for i = 1, MAX_NUM_SOCKETS do + ItemTexture = _G['KnightArmoryScanTT_E2Texture'..i]:GetTexture() + + if ItemTexture and ItemTexture:find('Interface\\ItemSocketingFrame\\') then + GemTotal_1 = GemTotal_1 + 1 + Slot['Socket'..GemTotal_1].GemType = strupper(gsub(ItemTexture, 'Interface\\ItemSocketingFrame\\UI--EmptySocket--', '')) + end + end + + -- Second, Check if slot's item enable to adding a socket + if (slotName == 'WaistSlot' and UnitLevel('player') >= 70) or -- buckle + ((slotName == 'WristSlot' or slotName == 'HandsSlot') and CFO.PlayerProfession.BlackSmithing and CFO.PlayerProfession.BlackSmithing >= 550) then -- BlackSmith + + GemTotal_1 = GemTotal_1 + 1 + Slot['Socket'..GemTotal_1].GemType = 'PRISMATIC' + end + + -- Apply current item's gem setting + for i = 1, MAX_NUM_SOCKETS do + ItemTexture = _G['KnightArmoryScanTT_E1Texture'..i]:GetTexture() + GemID = select(i, GetInventoryItemGems(Slot.ID)) + + if Slot['Socket'..i].GemType and C.GemColor[Slot['Socket'..i].GemType] then + r, g, b = unpack(C.GemColor[Slot['Socket'..i].GemType]) + Slot['Socket'..i].Socket:SetBackdropColor(r, g, b, .5) + Slot['Socket'..i].Socket:SetBackdropBorderColor(r, g, b) + else + Slot['Socket'..i].Socket:SetBackdropColor(1, 1, 1, .5) + Slot['Socket'..i].Socket:SetBackdropBorderColor(1, 1, 1) + end + + if ItemTexture then + if E.db.sle.characterframeoptions.itemgem.show then + Slot['Socket'..i]:Show() + Slot.SocketWarning:Point(Slot.Direction, Slot['Socket'..i], (Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 3 or -3, 0) + else + Slot['Socket'..i]:Hide() + Slot.SocketWarning:Point(Slot.Direction, Slot['Socket1'], (Slot.Direction == 'LEFT' and 'LEFT' or 'RIGHT'), 0, 0) + end + GemTotal_2 = GemTotal_2 + 1 + + if GemID then + GemCount = GemCount + 1 + Slot['Socket'..i].Texture:SetTexture(ItemTexture) + Slot['Socket'..i].GemItemID = GemID + Slot['Socket'..i].Socket.Link = select(2, GetItemInfo(GemID)) + end + end + end + end + + _, _, ItemRarity, BasicItemLevel, _, _, _, _, _, ItemTexture = GetItemInfo(ItemLink) + r, g, b = GetItemQualityColor(ItemRarity) + + ItemUpgradeID = ItemLink:match(':(%d+)\124h%[') + + for i = 1, f.ScanTTForEnchanting1:NumLines() do + CurrentLineText = _G['KnightArmoryScanTT_E1TextLeft'..i]:GetText() + + if CurrentLineText:find(C.ItemLevelKey_Alt) then + TrueItemLevel = tonumber(CurrentLineText:match(C.ItemLevelKey_Alt)) + elseif CurrentLineText:find(C.ItemLevelKey) then + TrueItemLevel = tonumber(CurrentLineText:match(C.ItemLevelKey)) + elseif CurrentLineText:find(C.EnchantKey) then + CurrentLineText = CurrentLineText:match(C.EnchantKey) -- Get enchant string + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_AGILITY_SHORT, AGI) + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_SPIRIT_SHORT, SPI) + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_STAMINA_SHORT, STA) + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_STRENGTH_SHORT, STR) + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_INTELLECT_SHORT, INT) --Intellect is to long for darth + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_CRIT_RATING_SHORT, CRIT_ABBR) -- Critical is too long + --God damn russian localization team! + CurrentLineText = gsub(CurrentLineText, "к показателю уклонения", ITEM_MOD_DODGE_RATING_SHORT) + CurrentLineText = gsub(CurrentLineText, "к показателю скорости", ITEM_MOD_HASTE_RATING_SHORT) + CurrentLineText = gsub(CurrentLineText, "к показателю парирования", ITEM_MOD_PARRY_RATING_SHORT) + CurrentLineText = gsub(CurrentLineText, "к показателю искусности", ITEM_MOD_MASTERY_RATING_SHORT) + CurrentLineText = gsub(CurrentLineText, ' + ', '+') -- Remove space + CurrentLineText = gsub(CurrentLineText, "небольшое увеличение скорости бега", "+к скорости бега") + + if E.db.sle.characterframeoptions.itemenchant.show then + Slot.ItemEnchant:Show() + if E.db.sle.characterframeoptions.itemenchant.mouseover then + Slot.ItemEnchant:SetDrawLayer('HIGHLIGHT') + else + Slot.ItemEnchant:SetDrawLayer('OVERLAY') + end + Slot.ItemEnchant:FontTemplate(LSM:Fetch("font", E.db.sle.characterframeoptions.itemenchant.font), E.db.sle.characterframeoptions.itemenchant.fontSize, E.db.sle.characterframeoptions.itemenchant.fontOutline) + Slot.ItemEnchant:SetText('|cffceff00'..CurrentLineText) + else + Slot.ItemEnchant:Hide() + end + + IsEnchanted = true + elseif CurrentLineText:find(ITEM_SPELL_TRIGGER_ONUSE) then + UsableEffect = true + end + end + + --<< ItemLevel Parts >>-- + if BasicItemLevel then + if ItemUpgradeID then + if ItemUpgradeID == '0' then + ItemUpgradeID = nil + else + if not C.ItemUpgrade[ItemUpgradeID] then + print('New Upgrade ID |cffceff00['..ItemUpgradeID..']|r : |cffceff00'..(TrueItemLevel - BasicItemLevel)) + end + + ItemUpgradeID = TrueItemLevel - BasicItemLevel + end + end + if E.db.sle.characterframeoptions.itemlevel.show ~= false then + Slot.ItemLevel:FontTemplate(LSM:Fetch("font", E.db.sle.characterframeoptions.itemlevel.font), E.db.sle.characterframeoptions.itemlevel.fontSize, E.db.sle.characterframeoptions.itemlevel.fontOutline) + Slot.ItemLevel:SetText((Slot.Direction == 'LEFT' and TrueItemLevel or '')..(ItemUpgradeID and (Slot.Direction == 'LEFT' and ' ' or '')..(C.UpgradeColor[ItemUpgradeID] or '|cffaaaaaa')..'(+'..ItemUpgradeID..')|r'..(Slot.Direction == 'RIGHT' and ' ' or '') or '')..(Slot.Direction == 'RIGHT' and TrueItemLevel or '')) + end + end + + --<< Durability Parts >>-- + CurrentDurability, MaxDurability = GetInventoryItemDurability(Slot.ID) + if CurrentDurability and MaxDurability then + if E.db.sle.characterframeoptions.itemdurability.show ~= false then + --Slot.Durability:Show() + r, g, b = E:ColorGradient((CurrentDurability / MaxDurability), 1, 0, 0, 1, 1, 0, 0, 1, 0) + Slot.Durability:FontTemplate(LSM:Fetch("font", E.db.sle.characterframeoptions.itemdurability.font), E.db.sle.characterframeoptions.itemdurability.fontSize, E.db.sle.characterframeoptions.itemdurability.fontOutline) + Slot.Durability:SetFormattedText("%s%.0f%%|r", E:RGBToHex(r, g, b), (CurrentDurability / MaxDurability) * 100) + Slot.Socket1:Point('BOTTOM'..Slot.Direction, Slot.Durability, 'BOTTOM'..(Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 3 or -3, -3) + end + end + + -- Check Error + if (not IsEnchanted and C.EnchantableSlots[slotName]) or ((slotName == 'Finger0Slot' or slotName == 'Finger1Slot') and CFO.PlayerProfession.Enchanting and CFO.PlayerProfession.Enchanting >= 550 and not IsEnchanted) then + ErrorDetected = true + if E.db.sle.characterframeoptions.itemenchant.showwarning ~= false then + Slot.EnchantWarning:Show() + Slot.ItemEnchant:FontTemplate(LSM:Fetch("font", E.db.sle.characterframeoptions.itemenchant.font), E.db.sle.characterframeoptions.itemenchant.fontSize, E.db.sle.characterframeoptions.itemenchant.fontOutline) + Slot.ItemEnchant:SetText('|cffff0000'..L['Not Enchanted']) + end + elseif CFO.PlayerProfession.Engineering and ((slotName == 'BackSlot' and CFO.PlayerProfession.Engineering >= 380) or (slotName == 'HandsSlot' and CFO.PlayerProfession.Engineering >= 400) or (slotName == 'WaistSlot' and CFO.PlayerProfession.Engineering >= 380)) and not UsableEffect then + ErrorDetected = true + if E.db.sle.characterframeoptions.itemenchant.showwarning ~= false then + Slot.EnchantWarning:Show() + Slot.EnchantWarning.Message = '|cff71d5ff'..GetSpellInfo(110403)..'|r : '..L['Missing Tinkers'] + end + elseif slotName == 'ShoulderSlot' and CFO.PlayerProfession.Inscription and C.ItemEnchant_Profession_Inscription and CFO.PlayerProfession.Inscription >= C.ItemEnchant_Profession_Inscription.NeedLevel and not C.ItemEnchant_Profession_Inscription[enchantID] then + ErrorDetected = true + if E.db.sle.characterframeoptions.itemenchant.showwarning ~= false then + Slot.ItemEnchant:SetDrawLayer('OVERLAY') + Slot.EnchantWarning:Show() + Slot.EnchantWarning.Message = '|cff71d5ff'..GetSpellInfo(110400)..'|r : '..L['This is not profession only.'] + end + elseif slotName == 'WristSlot' and CFO.PlayerProfession.LeatherWorking and C.ItemEnchant_Profession_LeatherWorking and CFO.PlayerProfession.LeatherWorking >= C.ItemEnchant_Profession_LeatherWorking.NeedLevel and not C.ItemEnchant_Profession_LeatherWorking[enchantID] then + ErrorDetected = true + if E.db.sle.characterframeoptions.itemenchant.showwarning ~= false then + Slot.ItemEnchant:SetDrawLayer('OVERLAY') + Slot.EnchantWarning:Show() + Slot.EnchantWarning.Message = '|cff71d5ff'..GetSpellInfo(110423)..'|r : '..L['This is not profession only.'] + end + elseif slotName == 'BackSlot' and CFO.PlayerProfession.Tailoring and C.ItemEnchant_Profession_Tailoring and CFO.PlayerProfession.Tailoring >= C.ItemEnchant_Profession_Tailoring.NeedLevel and not C.ItemEnchant_Profession_Tailoring[enchantID] then + ErrorDetected = true + if E.db.sle.characterframeoptions.itemenchant.showwarning ~= false then + Slot.ItemEnchant:SetDrawLayer('OVERLAY') + Slot.EnchantWarning:Show() + Slot.EnchantWarning.Message = '|cff71d5ff'..GetSpellInfo(110426)..'|r : '..L['This is not profession only.'] + end + end + + if GemTotal_1 > GemTotal_2 or GemTotal_1 > GemCount then + ErrorDetected = true + + if E.db.sle.characterframeoptions.itemgem.showwarning ~= false then + Slot.SocketWarning:Show() + end + + if GemTotal_1 > GemTotal_2 then + if slotName == 'WaistSlot' then + if TrueItemLevel < 300 then + _, Slot.SocketWarning.Link = GetItemInfo(41611) + elseif TrueItemLevel < 417 then + _, Slot.SocketWarning.Link = GetItemInfo(55054) + else + _, Slot.SocketWarning.Link = GetItemInfo(90046) + end + elseif slotName == 'HandsSlot' then + Slot.SocketWarning.Link = GetSpellLink(114112) + elseif slotName == 'WristSlot' then + Slot.SocketWarning.Link = GetSpellLink(113263) + end + + if slotName == 'WaistSlot' then + Slot.SocketWarning.Message = L['Missing Buckle'] + elseif slotName == 'WristSlot' or slotName == 'HandsSlot' then + Slot.SocketWarning.Message = '|cff71d5ff'..GetSpellInfo(110396)..'|r : '..L['Missing Socket'] + end + else + Slot.SocketWarning.Message = '|cffff5678'..(GemTotal_1 - GemCount)..'|r '..L['Empty Socket'] + end + + if GemTotal_1 ~= GemTotal_2 and slotName == 'WaistSlot' then + Slot.SocketWarning:SetScript('OnClick', function(self, button) + local itemName, itemLink + + if TrueItemLevel < 300 then + itemName, itemLink = GetItemInfo(41611) + elseif TrueItemLevel < 417 then + itemName, itemLink = GetItemInfo(55054) + else + itemName, itemLink = GetItemInfo(90046) + end + + if HandleModifiedItemClick(itemLink) then + elseif IsShiftKeyDown() then + if button == 'RightButton' then + SocketInventoryItem(Slot.ID) + elseif BrowseName and BrowseName:IsVisible() then + AuctionFrameBrowse_Reset(BrowseResetButton) + BrowseName:SetText(itemName) + BrowseName:SetFocus() + end + end + end) + end + end + end + + -- Change Gradation + if ErrorDetected and E.db.sle.characterframeoptions.showerrorgradient ~= false then + if Slot.Direction == 'LEFT' then + Slot.Gradation:SetTexCoord(0, .5, .5, 1) + else + Slot.Gradation:SetTexCoord(.5, 1, .5, 1) + end + else + if Slot.Direction == 'LEFT' then + Slot.Gradation:SetTexCoord(0, .5, 0, .5) + else + Slot.Gradation:SetTexCoord(.5, 1, 0, .5) + end + end + end + end + + if E.db.sle.characterframeoptions.showimage ~= false then + if BGdrop ~= "CUSTOM" then + f.BG:SetTexture('Interface\\AddOns\\ElvUI_SLE\\media\\textures\\'..backgrounds[BGdrop]) + else + f.BG:SetTexture(E.db.sle.characterframeoptions.image.custom) + end + else + f.BG:SetTexture(nil); + end + + f.AverageItemLevel:SetText(C.Toolkit.Color_Value(L['Average'])..': '..format('%.2f', select(2, GetAverageItemLevel()))) +end + +function CFO:StartArmoryFrame() + -- Setting frame + CHARACTERFRAME_EXPANDED_WIDTH = 650 + CharacterFrame:SetHeight(444) + CharacterFrameInsetRight:SetPoint('TOPLEFT', CharacterFrameInset, 'TOPRIGHT', 110, 0) + CharacterFrameExpandButton:SetPoint('BOTTOMRIGHT', CharacterFrameInsetRight, 'BOTTOMLEFT', -3, 7) + + -- Move right equipment slots + CharacterHandsSlot:SetPoint('TOPRIGHT', CharacterFrameInsetRight, 'TOPLEFT', -4, -2) + + -- Move bottom equipment slots + CharacterMainHandSlot:SetPoint('BOTTOMLEFT', PaperDollItemsFrame, 'BOTTOMLEFT', 181, 14) + + -- Model Frame + CharacterModelFrame:Size(341, 302) + CharacterModelFrame:SetPoint('TOPLEFT', PaperDollFrame, 'TOPLEFT', 52, -90) + CharacterModelFrame.BackgroundTopLeft:Hide() + CharacterModelFrame.BackgroundTopRight:Hide() + CharacterModelFrame.BackgroundBotLeft:Hide() + CharacterModelFrame.BackgroundBotRight:Hide() + + -- Character Control Frame + CharacterModelFrameControlFrame:ClearAllPoints() + CharacterModelFrameControlFrame:SetPoint('BOTTOM', CharacterModelFrame, 'BOTTOM', -1.5, 1) + + if CreateArmoryFrame then + CreateArmoryFrame(KnightArmory) + end + CFO:ArmoryFrame_DataSetting() + + -- Run ArmoryMode + CFO:RegisterEvent('SOCKET_INFO_SUCCESS', 'ArmoryFrame_DataSetting') + CFO:RegisterEvent('PLAYER_EQUIPMENT_CHANGED', 'ArmoryFrame_DataSetting') + CFO:RegisterEvent('PLAYER_ENTERING_WORLD', 'ArmoryFrame_DataSetting') + CFO:RegisterEvent('UNIT_INVENTORY_CHANGED', 'ArmoryFrame_DataSetting') + CFO:RegisterEvent('EQUIPMENT_SWAP_FINISHED', 'ArmoryFrame_DataSetting') + CFO:RegisterEvent('UPDATE_INVENTORY_DURABILITY', 'ArmoryFrame_DataSetting') + CFO:RegisterEvent('ITEM_UPGRADE_MASTER_UPDATE', 'ArmoryFrame_DataSetting') + + -- For frame resizing + f.ChangeCharacterFrameWidth:SetParent(PaperDollFrame) + if PaperDollFrame:IsVisible() then + f.ChangeCharacterFrameWidth:Show() + CharacterFrame:SetWidth(CharacterFrameInsetRight:IsShown() and 650 or 448) + end +end + +function CFO:Initialize() + if not E.private.sle.characterframeoptions.enable then return end + + hooksecurefunc(_G, 'PaperDollFrame_SetLevel', function() + local primaryTalentTree = GetSpecialization() + local classDisplayName, class = UnitClass("player") + local classColorString = RAID_CLASS_COLORS[class].colorStr + local specName, _; + local PLAYER_LEVEL = "|c%s%s %s %s %s|r" + local PLAYER_LEVEL_NO_SPEC = "|c%s%s %s %s|r" + if (primaryTalentTree) then + _, specName = GetSpecializationInfo(primaryTalentTree); + end + + if (specName and specName ~= "") then + CharacterLevelText:SetFormattedText(PLAYER_LEVEL, classColorString, LEVEL, UnitLevel("player"), specName, classDisplayName); + else + CharacterLevelText:SetFormattedText(PLAYER_LEVEL_NO_SPEC, classColorString, LEVEL, UnitLevel("player"), classDisplayName); + end + + CharacterFrameTitleText:ClearAllPoints() + CharacterFrameTitleText:Point('TOP', f, 'TOP', 0, 0) + CharacterFrameTitleText:SetParent(f) + CharacterLevelText:ClearAllPoints() + CharacterLevelText:SetPoint('TOP', CharacterFrameTitleText, 'BOTTOM', 0, 0) + CharacterLevelText:SetParent(f) + end) + + CFO:StartArmoryFrame() +end + +-- E:RegisterModule(CFO:GetName()) \ No newline at end of file diff --git a/ElvUI_SLE/modules/characterframe/communication.lua b/ElvUI_SLE/modules/characterframe/communication.lua new file mode 100644 index 0000000..2660e78 --- /dev/null +++ b/ElvUI_SLE/modules/characterframe/communication.lua @@ -0,0 +1,948 @@ +-------------------------------------------------------------------------------- +--<< AISM : Surpport Module for Armory Inspecting >>-- +-------------------------------------------------------------------------------- +local AISM = _G['Armory_InspectSupportModule'] + +if not AISM then + local ItemSetBonusKey = ITEM_SET_BONUS:gsub('%%s', '(.+)') + local ProfessionLearnKey = ERR_LEARN_ABILITY_S:gsub('%%s', '(.+)') + local ProfessionLearnKey2 = ERR_LEARN_RECIPE_S:gsub('%%s', '(.+)') + local ProfessionUnlearnKey = ERR_SPELL_UNLEARNED_S:gsub('%%s', '(.+)') + local GuildLeaveKey = ERR_GUILD_LEAVE_S:gsub('%%s', '(.+)') + local PlayerOfflineKey = ERR_CHAT_PLAYER_NOT_FOUND_S:gsub('%%s', '(.+)') + + local playerName = UnitName('player') + local playerRealm = gsub(GetRealmName(),'[%s%-]','') + local _, playerClass, playerClassID = UnitClass('player') + local playerRace, playerRaceID = UnitRace('player') + local playerSex = UnitSex('player') + local isHelmDisplayed, isCloakDisplayed + + + --<< Create Core >>-- + AISM = CreateFrame('Frame', 'Armory_InspectSupportModule', UIParent) + AISM.Version = 1.0 + AISM.Tooltip = CreateFrame('GameTooltip', 'AISM_Tooltip', nil, 'GameTooltipTemplate') + AISM.Tooltip:SetOwner(UIParent, 'ANCHOR_NONE') + AISM.Updater = CreateFrame('Frame', 'AISM_Updater', UIParent) + + AISM.SendMessageDelay_Group = 2 + + AISM.PlayerData = { ['SetItem'] = {}, } + AISM.PlayerData_ShortString = { ['SetItem'] = {}, } + AISM.AISMUserList = {} + AISM.GroupMemberData = {} + AISM.GuildMemberData = {} + AISM.CurrentInspectData = {} + AISM.InspectRegistered = {} + AISM.RemainMessage = {} + AISM.RegisteredFunction = {} + + + --<< Define Key Table >>-- + local SlotIDList = {} + AISM.ProfessionList = { + [GetSpellInfo(105206)] = 'AC', -- Alchemy + [GetSpellInfo(110396)] = 'BS', -- BlackSmithing + [GetSpellInfo(110400)] = 'EC', -- Enchanting + [GetSpellInfo(110403)] = 'EG', -- Engineering + [GetSpellInfo(110417)] = 'IS', -- Inscription + [GetSpellInfo(110420)] = 'JC', -- JewelCrafting + [GetSpellInfo(110423)] = 'LW', -- LeatherWorking + [GetSpellInfo(110426)] = 'TL', -- Tailoring + + [GetSpellInfo(110413)] = 'HB', -- Herbalism + [GetSpellInfo(102161)] = 'MN', -- Mining + [GetSpellInfo(102216)] = 'SK', -- Skinning + } + AISM.GearList = { + ['HeadSlot'] = 'HE', + ['NeckSlot'] = 'NK', + ['ShoulderSlot'] = 'SD', + ['BackSlot'] = 'BK', + ['ChestSlot'] = 'CH', + ['ShirtSlot'] = 'ST', + ['TabardSlot'] = 'TB', + ['WristSlot'] = 'WR', + ['HandsSlot'] = 'HD', + ['WaistSlot'] = 'WA', + ['LegsSlot'] = 'LE', + ['FeetSlot'] = 'FE', + ['Finger0Slot'] = 'FG0', + ['Finger1Slot'] = 'FG1', + ['Trinket0Slot'] = 'TR0', + ['Trinket1Slot'] = 'TR1', + ['MainHandSlot'] = 'MH', + ['SecondaryHandSlot'] = 'SH', + } + AISM.CanTransmogrifySlot = { + ['HeadSlot'] = true, + ['ShoulderSlot'] = true, + ['BackSlot'] = true, + ['ChestSlot'] = true, + ['WristSlot'] = true, + ['HandsSlot'] = true, + ['WaistSlot'] = true, + ['LegsSlot'] = true, + ['FeetSlot'] = true, + ['MainHandSlot'] = true, + ['SecondaryHandSlot'] = true, + } + AISM.DataTypeTable = { + ['PLI'] = 'PlayerInfo', + ['GLD'] = 'GuildInfo', + ['PvP'] = 'PvPInfo', + ['PF1'] = 'Profession', + ['PF2'] = 'Profession', + ['ASP'] = 'ActiveSpec', + ['SID'] = 'SetItemData', + } + for groupNum = 1, MAX_TALENT_GROUPS do + AISM.DataTypeTable['SP'..groupNum] = 'Specialization' + AISM.DataTypeTable['GL'..groupNum] = 'Glyph' + end + for slotName, keyName in pairs(AISM.GearList) do + AISM.DataTypeTable[keyName] = 'Gear' + SlotIDList[GetInventorySlotInfo(slotName)] = slotName + end + + + --<< Player Data Updater Core >>-- + local needUpdate, args + AISM.Updater:SetScript('OnUpdate', function(self) + AISM.UpdatedData = needUpdate and AISM.UpdatedData or {} + needUpdate = nil + + if not self.ProfessionUpdated then + needUpdate = AISM:GetPlayerProfessionSetting() or needUpdate + end + + if not self.SpecUpdated then + needUpdate = AISM:GetPlayerSpecSetting() or needUpdate + end + + if not self.GlyphUpdated then + needUpdate = AISM:GetPlayerGlyphString() or needUpdate + end + + if self.GearUpdated ~= true then + needUpdate = AISM:GetPlayerGearString() or needUpdate + end + + if not needUpdate then + self:Hide() + + for _ in pairs(AISM.UpdatedData) do + if AISM.CurrentGroupMode and AISM.CurrentGroupMode ~= 'NoGroup' and AISM.CurrentGroupType then + AISM:SendData(AISM.UpdatedData) + end + break + end + end + end) + AISM.Updater:SetScript('OnEvent', function(self, Event, ...) + if Event == 'SOCKET_INFO_SUCCESS' or Event == 'ITEM_UPGRADE_MASTER_UPDATE' or Event == 'TRANSMOGRIFY_UPDATE' then + self.GearUpdated = nil + self:Show() + elseif Event == 'UNIT_INVENTORY_CHANGED' then + args = ... + + if args == 'player' then + self.GearUpdated = nil + self:Show() + end + elseif Event == 'PLAYER_EQUIPMENT_CHANGED' then + args = ... + self.GearUpdated = type(self.GearUpdated) == 'table' and self.GearUpdated or {} + self.GearUpdated[(SlotIDList[args])] = true + self:Show() + elseif Event == 'COMBAT_LOG_EVENT_UNFILTERED' then + _, Event, _, _, _, _, _, _, args = ... + + if Event == 'ENCHANT_APPLIED' and args == playerName then + self.GearUpdated = nil + self:Show() + end + elseif Event == 'CHAT_MSG_SYSTEM' then + args = ... + + if args:find(ProfessionLearnKey) or args:find(ProfessionLearnKey2) or args:find(ProfessionUnlearnKey) then + self.ProfessionUpdated = nil + self:Show() + end + elseif Event == 'ACTIVE_TALENT_GROUP_CHANGED' or Event == 'CHARACTER_POINTS_CHANGED' then + self.SpecUpdated = nil + self:Show() + elseif Event == 'GLYPH_ADDED' or Event == 'GLYPH_REMOVED' or Event == 'GLYPH_UPDATED' then + self.GlyphUpdated = nil + self:Show() + else + end + end) + AISM.UpdateHelmDisplaying = function(value) + isHelmDisplayed = value == '1' + AISM.Updater.GearUpdated = nil + AISM.Updater:Show() + end + hooksecurefunc('ShowHelm', AISM.UpdateHelmDisplaying) + AISM.UpdateCloakDisplaying = function(value) + isCloakDisplayed = value == '1' + AISM.Updater.GearUpdated = nil + AISM.Updater:Show() + end + hooksecurefunc('ShowCloak', AISM.UpdateCloakDisplaying) + + + --<< Profession String >>-- + function AISM:GetPlayerProfessionSetting() + local Profession1, Profession2 = GetProfessions() + local Profession1_Level, Profession2_Level = 0, 0 + + if Profession1 then + Profession1, _, Profession1_Level = GetProfessionInfo(Profession1) + + if self.ProfessionList[Profession1] then + Profession1 = self.ProfessionList[Profession1]..'/'..Profession1_Level + else + Profession1 = 'F' + end + end + + if Profession2 then + Profession2, _, Profession2_Level = GetProfessionInfo(Profession2) + + if self.ProfessionList[Profession2] then + Profession2 = self.ProfessionList[Profession2]..'/'..Profession2_Level + else + Profession2 = 'F' + end + end + + if self.PlayerData.Profession1 ~= Profession1 then + self.PlayerData.Profession1 = Profession1 + end + + if self.PlayerData.Profession2 ~= Profession2 then + self.PlayerData.Profession2 = Profession2 + end + + self.Updater.ProfessionUpdated = true + end + AISM.Updater:RegisterEvent('CHAT_MSG_SYSTEM') + + + --<< Specialization String >>-- + function AISM:GetPlayerSpecSetting() + local DataString, isSelected, selectedSlot + local ActiveSpec = GetActiveSpecGroup() + + for groupNum = 1, MAX_TALENT_GROUPS do + DataString = GetSpecialization(nil, nil, groupNum) + + if DataString then + DataString = GetSpecializationInfo(DataString) + else + DataString = '0' + end + + for i = 1, MAX_NUM_TALENT_TIERS do + selectedSlot = '0' + + for k = 1, NUM_TALENT_COLUMNS do + _, _, _, _, isSelected = GetTalentInfo((i - 1) * NUM_TALENT_COLUMNS + k, nil, groupNum) + + if isSelected then + selectedSlot = k + break + end + end + + DataString = DataString..'/'..selectedSlot + end + + if self.PlayerData['Spec'..groupNum] ~= DataString then + self.PlayerData['Spec'..groupNum] = DataString + end + + if groupNum == ActiveSpec and self.PlayerData_ShortString.Spec1 ~= DataString then + self.PlayerData_ShortString.Spec1 = DataString + self.UpdatedData.Spec1 = DataString + end + end + + isSelected = GetActiveSpecGroup() + + if self.PlayerData.ActiveSpec ~= ActiveSpec then + self.PlayerData.ActiveSpec = ActiveSpec + end + + self.Updater.SpecUpdated = true + end + AISM.Updater:RegisterEvent('ACTIVE_TALENT_GROUP_CHANGED') + AISM.Updater:RegisterEvent('CHARACTER_POINTS_CHANGED') + + + --<< Glyph String >>-- + function AISM:GetPlayerGlyphString() + local ShortString, FullString + local ActiveSpec = GetActiveSpecGroup() + + local SpellID, GlyphID + for groupNum = 1, MAX_TALENT_GROUPS do + ShortString, FullString = '', '' + + for slotNum = 1, NUM_GLYPH_SLOTS do + _, _, _, SpellID, _, GlyphID = GetGlyphSocketInfo(slotNum, groupNum) + + ShortString = ShortString..(SpellID or '0')..(slotNum ~= NUM_GLYPH_SLOTS and '/' or '') + FullString = FullString..(SpellID or '0')..'_'..(GlyphID or '0')..(slotNum ~= NUM_GLYPH_SLOTS and '/' or '') + end + + if self.PlayerData['Glyph'..groupNum] ~= FullString then + self.PlayerData['Glyph'..groupNum] = FullString + end + + if groupNum == ActiveSpec and self.PlayerData_ShortString.Glyph1 ~= ShortString then + self.PlayerData_ShortString.Glyph1 = ShortString + self.UpdatedData.Glyph1 = ShortString + end + end + + self.Updater.GlyphUpdated = true + end + AISM.Updater:RegisterEvent('GLYPH_ADDED') + AISM.Updater:RegisterEvent('GLYPH_REMOVED') + AISM.Updater:RegisterEvent('GLYPH_UPDATED') + + + --<< Gear String >>-- + function AISM:GetPlayerGearString() + local ShortString, FullString, needUpdate, needUpdateList + local CurrentSetItem = {} + + local slotID, slotLink, isTransmogrified, transmogrifiedItemID, SetName, GeatSetCount, SetItemMax, SetOptionCount, colorR, colorG, colorB, checkSpace, tooltipText + for slotName in pairs(self.Updater.GearUpdated or self.GearList) do + needUpdate = nil + + slotID = GetInventorySlotInfo(slotName) + slotLink = GetInventoryItemLink('player', slotID) + + if slotLink and slotLink:find('%[%]') then -- sometimes itemLink is malformed so we need to update when crashed + needUpdate = true + else + if slotLink and self.CanTransmogrifySlot[slotName] then + isTransmogrified, _, _, _, _, transmogrifiedItemID = GetTransmogrifySlotInfo(slotID) + else + isTransmogrified = nil + end + + ShortString = slotLink and select(2, strsplit(':', slotLink)) or 'F' + FullString = (slotLink or 'F')..'/'..(slotName == 'HeadSlot' and not isHelmDisplayed and 'ND' or slotName == 'BackSlot' and not isCloakDisplayed and 'ND' or isTransmogrified and transmogrifiedItemID or '0') + + for i = 1, MAX_NUM_SOCKETS do + FullString = FullString..'/'..(select(i, GetInventoryItemGems(slotID)) or 0) + end + + if self.PlayerData[slotName] ~= FullString then + self.PlayerData[slotName] = FullString + end + + if self.PlayerData_ShortString[slotName] ~= ShortString then + self.PlayerData_ShortString[slotName] = ShortString + self.UpdatedData[slotName] = ShortString + end + + if slotLink then + self.Tooltip:ClearLines() + self.Tooltip:SetHyperlink(slotLink) + + checkSpace = 2 + SetOptionCount = 1 + + for i = 1, self.Tooltip:NumLines() do + SetName, SetItemCount, SetItemMax = _G['AISM_TooltipTextLeft'..i]:GetText():match('^(.+) %((%d)/(%d)%)$') -- find string likes 'SetName (0/5)' + + if SetName then + SetItemCount = tonumber(SetItemCount) + SetItemMax = tonumber(SetItemMax) + + if SetItemCount > SetItemMax or SetItemMax == 1 then + needUpdate = true + break + else + if not (CurrentSetItem[SetName] or self.PlayerData.SetItem or self.PlayerData.SetItem[SetName]) then + needUpdate = true + end + + CurrentSetItem[SetName] = CurrentSetItem[SetName] or {} + + ShortString = 0 + FullString = '' + + for k = 1, self.Tooltip:NumLines() do + tooltipText = _G['AISM_TooltipTextLeft'..(i+k)]:GetText() + + if tooltipText == ' ' then + checkSpace = checkSpace - 1 + + if checkSpace == 0 then break end + elseif checkSpace == 2 then + colorR, colorG, colorB = _G['AISM_TooltipTextLeft'..(i+k)]:GetTextColor() + + if colorR > LIGHTYELLOW_FONT_COLOR.r - .01 and colorR < LIGHTYELLOW_FONT_COLOR.r + .01 and colorG > LIGHTYELLOW_FONT_COLOR.g - .01 and colorG < LIGHTYELLOW_FONT_COLOR.g + .01 and colorB > LIGHTYELLOW_FONT_COLOR.b - .01 and colorB < LIGHTYELLOW_FONT_COLOR.b + .01 then + ShortString = ShortString + 1 + tooltipText = LIGHTYELLOW_FONT_COLOR_CODE..tooltipText + else + tooltipText = GRAY_FONT_COLOR_CODE..tooltipText + end + + if CurrentSetItem[SetName][k] and CurrentSetItem[SetName][k] ~= tooltipText then + needUpdate = true + end + + CurrentSetItem[SetName][k] = tooltipText + FullString = FullString..'/'..tooltipText + elseif tooltipText:find(ItemSetBonusKey) then + tooltipText = tooltipText:match("^%((%d)%)%s.+:%s.+$") or 'T' + + if CurrentSetItem[SetName]['SetOption'..SetOptionCount] and CurrentSetItem[SetName]['SetOption'..SetOptionCount] ~= tooltipText then + needUpdate = true + end + + CurrentSetItem[SetName]['SetOption'..SetOptionCount] = tooltipText + FullString = FullString..'/'..tooltipText + + SetOptionCount = SetOptionCount + 1 + end + end + + if self.PlayerData.SetItem[SetName] ~= FullString then + self.PlayerData.SetItem[SetName] = FullString + end + + if self.PlayerData_ShortString.SetItem[SetName] ~= ShortString then + self.PlayerData_ShortString.SetItem[SetName] = ShortString + + self.UpdatedData.SetItem = self.UpdatedData.SetItem or {} + self.UpdatedData.SetItem[SetName] = ShortString + end + end + end + + if checkSpace == 0 then break end + end + end + end + + if needUpdate then + needUpdateList = needUpdateList or {} + needUpdateList[slotName] = true + end + end + + -- Clear cache when there's no gear set + if self.PlayerData.SetItem then + for SetName in pairs(self.PlayerData.SetItem) do + if not CurrentSetItem[SetName] then + self.PlayerData.SetItem[SetName] = nil + + self.PlayerData_ShortString.SetItem[SetName] = nil + self.UpdatedData.SetItem = self.UpdatedData.SetItem or {} + self.UpdatedData.SetItem[SetName] = 'F' + end + end + end + + if needUpdateList then + self.Updater.GearUpdated = needUpdateList + return true + else + self.Updater.GearUpdated = true + end + end + AISM.Updater:RegisterEvent('SOCKET_INFO_SUCCESS') + AISM.Updater:RegisterEvent('PLAYER_EQUIPMENT_CHANGED') + AISM.Updater:RegisterEvent('UNIT_INVENTORY_CHANGED') + AISM.Updater:RegisterEvent('ITEM_UPGRADE_MASTER_UPDATE') + AISM.Updater:RegisterEvent('TRANSMOGRIFY_UPDATE') + AISM.Updater:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED') + + + --<< Player Info >>-- + function AISM:SettingInspectData(TableToSave) + local guildName, guildRankName = GetGuildInfo('player') + + TableToSave.PlayerInfo = playerName..'_'..UnitPVPName('player')..'/'..playerRealm..'/'..UnitLevel('player')..'/'..playerClass..'/'..playerClassID..'/'..playerRace..'/'..playerRaceID..'/'..playerSex..(guildName and '/'..guildName..'/'..guildRankName or '') + + if IsInGuild() then + TableToSave.GuildInfo = GetGuildLevel()..'/'..GetNumGuildMembers() + + for _, DataString in ipairs({ GetGuildLogoInfo('player') }) do + TableToSave.GuildInfo = TableToSave.GuildInfo..'/'..DataString + end + end + + TableToSave.PvP = GetPVPLifetimeStats() + + local Rating, Played, Won + for i, Type in pairs({ '2vs2', '3vs3', '5vs5', 'RB' }) do + Rating, _, _, Played, Won = GetPersonalRatedInfo(i) + + if Played > 0 then + TableToSave.PvP = TableToSave.PvP..'/'..Type..'_'..Rating..'_'..Played..'_'..Won + end + end + end + + + function AISM:SendData(InputData, Prefix, Channel, WhisperTarget) + Channel = Channel or IsInGroup(LE_PARTY_CATEGORY_INSTANCE) and 'INSTANCE_CHAT' or string.upper(self.CurrentGroupMode) + Prefix = Prefix or 'AISM' + + if not InputData or type(InputData) ~= 'table' or Channel == 'NOGROUP' then return end + + local Data = {} + + if InputData.Profession1 then + Data[#Data + 1] = 'PF1:'..InputData.Profession1 + end + + if InputData.Profession2 then + Data[#Data + 1] = 'PF2:'..InputData.Profession2 + end + + for groupNum = 1, MAX_TALENT_GROUPS do + if InputData['Spec'..groupNum] then + Data[#Data + 1] = 'SP'..groupNum..':'..InputData['Spec'..groupNum] + end + end + + if InputData.ActiveSpec then + Data[#Data + 1] = 'ASP:'..InputData.ActiveSpec + end + + for groupNum = 1, MAX_TALENT_GROUPS do + if InputData['Glyph'..groupNum] then + Data[#Data + 1] = 'GL'..groupNum..':'..InputData['Glyph'..groupNum] + end + end + + for slotName, keyName in pairs(self.GearList) do + if InputData[slotName] then + Data[#Data + 1] = keyName..':'..InputData[slotName] + end + end + + if InputData.SetItem then + for SetName, DataString in pairs(InputData.SetItem) do + Data[#Data + 1] = 'SID:'..SetName..(type(DataString) == 'number' and '/' or '')..DataString + end + end + + if InputData.PlayerInfo then + Data[#Data + 1] = 'PLI:'..InputData.PlayerInfo + end + + if InputData.GuildInfo then + Data[#Data + 1] = 'GLD:'..InputData.GuildInfo + end + + if InputData.PvP then + Data[#Data + 1] = 'PvP:'..InputData.PvP + end + + local DataString = '' + local stringLength = 0 + local dataLength + + for dataTag, dataText in pairs(Data) do + DataString = DataString..'{'..dataText..'}' + dataLength = strlen(dataText) + 2 + + if stringLength + dataLength <= 255 then + stringLength = stringLength + dataLength + else + while strlen(DataString) > 255 do + SendAddonMessage(Prefix, strsub(DataString, 1, 255), Channel, WhisperTarget) + + DataString = strsub(DataString, 256) + stringLength = strlen(DataString) + end + end + end + + if DataString ~= '' then + SendAddonMessage(Prefix, DataString, Channel, WhisperTarget) + end + end + + + function AISM:GetPlayerCurrentGroupMode() + if not (IsInGroup() or IsInRaid()) or GetNumGroupMembers() == 1 then + self.CurrentGroupMode = 'NoGroup' + self.GroupMemberData = {} + else + if IsInRaid() then + self.CurrentGroupMode = 'raid' + else + self.CurrentGroupMode = 'party' + end + + for userName in pairs(self.GroupMemberData) do + if not UnitExists(userName) or not UnitIsConnected(userName) then + self.GroupMemberData[userName] = nil + end + end + end + + return self.CurrentGroupMode + end + + + function AISM:GetCurrentInstanceType() + local _, instanceType, difficultyID = GetInstanceInfo() + + if difficultyID == 8 then + self.InstanceType = 'challenge' + else + self.InstanceType = instanceType == 'none' and 'field' or instanceType + end + end + + + local needSendData, Name, TableIndex + AISM:SetScript('OnUpdate', function(self, elapsed) + if elapsed < .1 then + --needSendData = nil + + if self.CurrentGroupMode ~= 'NoGroup' then + for i = 1, MAX_RAID_MEMBERS do + Name = UnitName(self.CurrentGroupMode..i) + TableIndex = GetUnitName(self.CurrentGroupMode..i, true) + + if Name and not UnitIsUnit('player', self.CurrentGroupMode..i) then + if Name == UNKNOWNOBJECT or Name == COMBATLOG_UNKNOWN_UNIT or not UnitIsConnected(self.CurrentGroupMode..i) then + self.AISMUserList[TableIndex] = nil + self.GroupMemberData[TableIndex] = nil + elseif not self.GroupMemberData[TableIndex] then + needSendData = true + self.GroupMemberData[TableIndex] = true + end + end + end + else + needSendData = nil + self.SendDataGroupUpdated = nil + end + + if needSendData and self.Updater.SpecUpdated and self.Updater.GlyphUpdated and self.Updater.GearUpdated then + self.SendDataGroupUpdated = (self.SendDataGroupUpdated or self.SendMessageDelay_Group) - elapsed + + if self.SendDataGroupUpdated < 0 then + needSendData = nil + self.SendDataGroupUpdated = nil + + self:SendData(self.PlayerData_ShortString) + end + end + + if needSendData == nil then + self:Hide() -- close function + end + end + end) + + + function AISM:PrepareTableSetting(Prefix, Sender) + self.AISMUserList[Sender] = self.AISMUserList[Sender] or true + + if Prefix == 'AISM' then + local NeedResponse + + if type(self.GroupMemberData[Sender]) ~= 'table' then + self.GroupMemberData[Sender] = {} + + NeedResponse = true + end + + return self.GroupMemberData[Sender], NeedResponse + else + return self.CurrentInspectData[Sender] + end + end + + + local SenderRealm + function AISM:Receiver(Prefix, Message, Channel, Sender) + Sender, SenderRealm = strsplit('-', Sender) + SenderRealm = gsub(SenderRealm,'[%s%-]','') + Sender = Sender..(SenderRealm and SenderRealm ~= '' and SenderRealm ~= playerRealm and '-'..SenderRealm or '') + + --print('|cffceff00['..Channel..']|r|cff2eb7e4['..Prefix..']|r '..Sender..' : ') + --print(Message) + + if Message:find('AISM_') then + if Message == 'AISM_Check' then + self.AISMUserList[Sender] = true + SendAddonMessage('AISM', 'AISM_CheckResponse', 'WHISPER', Sender) + elseif Message == 'AISM_CheckResponse' then + self.AISMUserList[Sender] = true + elseif Message == 'AISM_UnregistME' then + self.AISMUserList[Sender] = nil + self.GroupMemberData[Sender] = nil + elseif Message == 'AISM_GUILD_Check' then + self.AISMUserList[Sender] = 'GUILD' + SendAddonMessage('AISM', 'AISM_GUILD_CheckResponse', SenderRealm == playerRealm and 'WHISPER' or 'GUILD', Sender) + elseif Message == 'AISM_GUILD_CheckResponse' then + self.AISMUserList[Sender] = 'GUILD' + elseif Message == 'AISM_GUILD_UnregistME' then + self.AISMUserList[Sender] = nil + self.CurrentInspectData[Sender] = nil + elseif Message:find('AISM_DataRequestForInspecting:') then + local needplayerName, needplayerRealm = Message:match('^.+:(.+)-(.+)$') + + if needplayerName == playerName and needplayerRealm == playerRealm then + local TableToSend = {} + + for Index, Data in pairs(self.PlayerData) do + TableToSend[Index] = Data + end + + self:SettingInspectData(TableToSend) + + self:SendData(TableToSend, Prefix, Channel, Sender) + end + end + else + local TableToSave, NeedResponse, Group, stringTable + + TableToSave, NeedResponse = self:PrepareTableSetting(Prefix, Sender) + + if not TableToSave then + self.RemainMessage[Sender] = nil + + return + else + Message = (self.RemainMessage[Sender] or '')..Message + + for DataType, DataString in Message:gmatch('%{(.-):(.-)%}') do + if self.DataTypeTable[DataType] then + Message = Message:gsub('%{'..DataType..':.-%}', '') + Group = DataType:match('^.+(%d)$') + stringTable = { strsplit('/', DataString) } + + for Index, Data in pairs(stringTable) do + if tonumber(Data) then + stringTable[Index] = tonumber(Data) + end + end + + if Group and self.DataTypeTable[DataType] ~= 'Gear' then -- Prepare group setting + Group = tonumber(Group) + TableToSave[(self.DataTypeTable[DataType])] = TableToSave[(self.DataTypeTable[DataType])] or {} + TableToSave[(self.DataTypeTable[DataType])][Group] = TableToSave[(self.DataTypeTable[DataType])][Group] or {} + end + + if self.DataTypeTable[DataType] == 'Profession' then + if stringTable[1] == 'F' then + TableToSave.Profession[Group].Name = EMPTY + TableToSave.Profession[Group].Level = 0 + else + for localeName, Key in pairs(self.ProfessionList) do + if Key == stringTable[1] then + TableToSave.Profession[Group].Name = localeName + break + end + end + TableToSave.Profession[Group].Level = stringTable[2] + end + elseif self.DataTypeTable[DataType] == 'Specialization' then + TableToSave.Specialization[Group].SpecializationID = stringTable[1] + + for i = 1, MAX_NUM_TALENT_TIERS do + for k = 1, NUM_TALENT_COLUMNS do + TableToSave.Specialization[Group]['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)] = k == stringTable[i + 1] and true or false + end + end + elseif self.DataTypeTable[DataType] == 'ActiveSpec' then + TableToSave.Specialization = TableToSave.Specialization or {} + TableToSave.Specialization.ActiveSpec = tonumber(DataString) + elseif self.DataTypeTable[DataType] == 'Glyph' then + local SpellID, GlyphID + for i = 1, #stringTable do + SpellID, GlyphID = strsplit('_', stringTable[i]) + + TableToSave.Glyph[Group]['Glyph'..i..'SpellID'] = tonumber(SpellID) + TableToSave.Glyph[Group]['Glyph'..i..'ID'] = tonumber(GlyphID) + end + elseif self.DataTypeTable[DataType] == 'Gear' then + TableToSave.Gear = TableToSave.Gear or {} + + for slotName, keyName in pairs(self.GearList) do + if keyName == DataType then + DataType = slotName + break + end + end + + TableToSave.Gear[DataType] = { + ['ItemLink'] = stringTable[1] ~= 'F' and stringTable[1] or nil, + ['Transmogrify'] = stringTable[2] == 'ND' and 'NotDisplayed' or stringTable[2] ~= 0 and stringTable[2] or nil + } + + for i = 1, MAX_NUM_SOCKETS do + TableToSave.Gear[DataType]['Gem'..i] = stringTable[i + 2] ~= 0 and stringTable[i + 2] or nil + end + elseif self.DataTypeTable[DataType] == 'SetItemData' then + TableToSave.SetItem = TableToSave.SetItem or {} + + if stringTable[2] ~= 'F' then + if type(stringTable[2]) == 'number' then + TableToSave.SetItem[(stringTable[1])] = stringTable[2] + else + TableToSave.SetItem[(stringTable[1])] = {} + + for i = 2, #stringTable do + if strlen(stringTable[i]) > 2 then + TableToSave.SetItem[(stringTable[1])][i - 1] = stringTable[i] + else + for k = 1, #stringTable - i + 1 do + TableToSave.SetItem[(stringTable[1])]['SetOption'..k] = stringTable[i + k - 1] == 'T' or stringTable[i + k - 1] + end + break + end + end + end + else + TableToSave.SetItem[(stringTable[1])] = nil + end + elseif self.DataTypeTable[DataType] == 'PlayerInfo' then + TableToSave.Name, TableToSave.Title = strsplit('_', stringTable[1]) + TableToSave.Realm = stringTable[2] ~= '' and stringTable[2] ~= playerRealm and stringTable[2] or nil + TableToSave.Level = stringTable[3] + TableToSave.Class = stringTable[4] + TableToSave.ClassID = stringTable[5] + TableToSave.Race = stringTable[6] + TableToSave.RaceID = stringTable[7] + TableToSave.GenderID = stringTable[8] + TableToSave.guildName = stringTable[9] + TableToSave.guildRankName = stringTable[10] + elseif self.DataTypeTable[DataType] == 'GuildInfo' then + TableToSave.guildLevel = stringTable[1] + TableToSave.guildNumMembers = stringTable[2] + + for i = 3, #stringTable do + TableToSave.guildEmblem = TableToSave.guildEmblem or {} + TableToSave.guildEmblem[i - 2] = stringTable[i] + end + elseif self.DataTypeTable[DataType] == 'PvPInfo' then + TableToSave.PvP = TableToSave.PvP or {} + + TableToSave.PvP.Honor = stringTable[1] + + local PvPType, Rating, Played, Won + for i = 2, #stringTable do + PvPType, Rating, Played, Won = strsplit('_', stringTable[i]) + TableToSave.PvP[PvPType] = { tonumber(Rating), tonumber(Played), tonumber(Won) } + end + end + end + end + + if Message == '' then + for funcName, func in pairs(self.RegisteredFunction) do + func(Sender, TableToSave) + end + + Message = nil + end + + self.RemainMessage[Sender] = Message + + if NeedResponse then + self:SendData(self.PlayerData_ShortString, 'AISM', SenderRealm == playerRealm and 'WHISPER' or nil, Sender) + end + end + end + end + + + local Prefix, Message, Channel, Sender, Type + AISM:SetScript('OnEvent', function(self, Event, ...) + if Event == 'VARIABLES_LOADED' then + isHelmDisplayed = ShowingHelm() == 1 + isCloakDisplayed = ShowingCloak() == 1 + + self:UnregisterEvent('VARIABLES_LOADED') + elseif Event == 'PLAYER_LOGIN' then + self:GetPlayerCurrentGroupMode() + self:GetCurrentInstanceType() + elseif Event == 'PLAYER_LOGOUT' then + if IsInGuild() then + SendAddonMessage('AISM', 'AISM_GUILD_UnregistME', 'GUILD') + end + if self.CurrentGroupMode ~= 'NoGroup' then + SendAddonMessage('AISM', 'AISM_UnregistME', IsInGroup(LE_PARTY_CATEGORY_INSTANCE) and 'INSTANCE_CHAT' or string.upper(self.CurrentGroupMode)) + end + elseif Event == 'CHAT_MSG_SYSTEM' then + Message = ... + Type = Message:find(GuildLeaveKey) and 'GUILD' or Message:find(PlayerOfflineKey) and 'OFFLINE' or nil + + if Type then + local SenderRealm + + Sender = Message:match(GuildLeaveKey) or Message:match(PlayerOfflineKey) + Sender = Sender:gsub('@', '-') + Sender, SenderRealm = strsplit('-', Sender) + SenderRealm = gsub(SenderRealm,'[%s%-]','') + Sender = Sender..(SenderRealm and SenderRealm ~= '' and SenderRealm ~= playerRealm and '-'..SenderRealm or '') + + for userName in pairs(self.AISMUserList) do + if userName == Sender then + self.AISMUserList[userName] = Type == 'GUILD' and true or nil + + return + end + end + end + elseif Event == 'CHAT_MSG_ADDON' then + Prefix, Message, Channel, Sender = ... + + if (Prefix == 'AISM' or Prefix == 'AISM_Inspect') and Sender ~= playerName..'-'..playerRealm then + self:Receiver(Prefix, Message, Channel, Sender) + end + elseif Event == 'GROUP_ROSTER_UPDATE' then + self:GetPlayerCurrentGroupMode() + self:Show() + elseif Event == 'PLAYER_ENTERING_WORLD' or Event == 'ZONE_CHANGED_NEW_AREA' then + self:GetCurrentInstanceType() + self:Show() + end + end) + AISM:RegisterEvent('VARIABLES_LOADED') + AISM:RegisterEvent('PLAYER_LOGIN') + AISM:RegisterEvent('PLAYER_LOGOUT') + AISM:RegisterEvent('CHAT_MSG_SYSTEM') + AISM:RegisterEvent('CHAT_MSG_ADDON') + AISM:RegisterEvent('GROUP_ROSTER_UPDATE') + AISM:RegisterEvent('PLAYER_ENTERING_WORLD') + AISM:RegisterEvent('ZONE_CHANGED_NEW_AREA') + + + function AISM:RegisterInspectDataRequest(Func, funcName, PreserveFunction) + if type(Func) == 'function' then + funcName = funcName or #self.RegisteredFunction + 1 + + self.RegisteredFunction[funcName] = function(User, UserData) + if Func(User, UserData) then + if not PreserveFunction then + self.RegisteredFunction[funcName] = nil + end + end + end + end + end + + RegisterAddonMessagePrefix('AISM') + RegisterAddonMessagePrefix('AISM_Inspect') +end \ No newline at end of file diff --git a/ElvUI_SLE/modules/characterframe/core.lua b/ElvUI_SLE/modules/characterframe/core.lua new file mode 100644 index 0000000..8f22db0 --- /dev/null +++ b/ElvUI_SLE/modules/characterframe/core.lua @@ -0,0 +1,494 @@ +local E, L, V, P, G, _ = unpack(ElvUI) + +-- Constants +SLArmoryConstants = { + ['ItemLevelKey'] = ITEM_LEVEL:gsub('%%d', '(.+)'), + ['ItemLevelKey_Alt'] = ITEM_LEVEL_ALT:gsub('%%d', '.+'):gsub('%(.+%)', '%%((.+)%%)'), + ['EnchantKey'] = ENCHANTED_TOOLTIP_LINE:gsub('%%s', '(.+)'), + ['ItemSetBonusKey'] = ITEM_SET_BONUS:gsub('%%s', '(.+)'), + ['TransmogrifiedKey'] = TRANSMOGRIFIED:gsub('%%s', '(.+)'), + + ['GearList'] = { + 'HeadSlot', 'HandsSlot', 'NeckSlot', 'WaistSlot', 'ShoulderSlot', 'LegsSlot', 'BackSlot', 'FeetSlot', 'ChestSlot', 'Finger0Slot', + 'ShirtSlot', 'Finger1Slot', 'TabardSlot', 'Trinket0Slot', 'WristSlot', 'Trinket1Slot', 'SecondaryHandSlot', 'MainHandSlot' + }, + + ['EnchantableSlots'] = { + ['ShoulderSlot'] = true, ['BackSlot'] = true, ['ChestSlot'] = true, ['WristSlot'] = true, ['HandsSlot'] = true, + ['LegsSlot'] = true, ['FeetSlot'] = true, ['MainHandSlot'] = true, ['SecondaryHandSlot'] = true + }, + + ['UpgradeColor'] = { + [16] = '|cffff9614', [12] = '|cfff88ef4', [8] = '|cff2eb7e4', [4] = '|cffceff00' + }, + + ['GemColor'] = { + ['RED'] = { 1, .2, .2, }, ['YELLOW'] = { .97, .82, .29, }, ['BLUE'] = { .47, .67, 1, } + }, + + ['EmptySocketString'] = { + [EMPTY_SOCKET_BLUE] = true, [EMPTY_SOCKET_COGWHEEL] = true, [EMPTY_SOCKET_HYDRAULIC] = true, [EMPTY_SOCKET_META] = true, + [EMPTY_SOCKET_NO_COLOR] = true, [EMPTY_SOCKET_PRISMATIC] = true, [EMPTY_SOCKET_RED] = true, [EMPTY_SOCKET_YELLOW] = true + }, + + ['ItemUpgrade'] = { + ['0'] = 0, ['1'] = 8, + ['373'] = 4, ['374'] = 8, ['375'] = 4, ['376'] = 4, ['377'] = 4, ['379'] = 4, ['380'] = 4, + ['445'] = 0, ['446'] = 4, ['447'] = 8, ['451'] = 0, ['452'] = 8, ['453'] = 0, ['454'] = 4, + ['455'] = 8, ['456'] = 0, ['457'] = 8, ['458'] = 0, ['459'] = 4, ['460'] = 8, ['461'] = 12, + ['462'] = 16, ['465'] = 0, ['466'] = 4, ['467'] = 8, ['468'] = 0, ['469'] = 4, ['470'] = 8, + ['471'] = 12, ['472'] = 16, ['476'] = 0, ['477'] = 4, ['478'] = 8, ['479'] = 0, ['480'] = 8, + ['491'] = 0, ['492'] = 4, ['493'] = 8, ['494'] = 0, ['495'] = 4, ['496'] = 8, ['497'] = 12, ['498'] = 16, + ['504'] = 12, ['505'] = 16, ['506'] = 20, ['507'] = 24, + }, + + ['ItemBindString'] = { -- Usually transmogrify string is located upper than bind string so we need to check this string for adding a transmogrify string in tooltip. + [ITEM_BIND_ON_EQUIP] = true, + [ITEM_BIND_ON_PICKUP] = true, + [ITEM_BIND_TO_ACCOUNT] = true, + [ITEM_BIND_TO_BNETACCOUNT] = true + }, + + ['CanTransmogrifySlot'] = { + ['HeadSlot'] = true, + ['ShoulderSlot'] = true, + ['BackSlot'] = true, + ['ChestSlot'] = true, + ['WristSlot'] = true, + ['HandsSlot'] = true, + ['WaistSlot'] = true, + ['LegsSlot'] = true, + ['FeetSlot'] = true, + ['MainHandSlot'] = true, + ['SecondaryHandSlot'] = true + }, + + ['ItemEnchant_Profession_Inscription'] = { + ['NeedLevel'] = 600, + ['4912'] = true, -- ?? ?? ???? Secret Ox Horn Inscription + ['4913'] = true, -- ?? ??? ???? Secret Crane Wing Inscription + ['4914'] = true, -- ?? ??? ?? ???? Secret Tiger Claw Inscription + ['4915'] = true, -- ?? ??? ??? ???? Secret Tiger Fang Inscription + }, + + ['ItemEnchant_Profession_LeatherWorking'] = { + ['NeedLevel'] = 575, + ['4875'] = true, -- ?? ?? - ? Fur Lining - Strength + ['4877'] = true, -- ?? ?? - ?? Fur Lining - Intellect + ['4878'] = true, -- ?? ?? - ?? Fur Lining - Stamina + ['4879'] = true, -- ?? ?? - ??? Fur Lining - Agility + }, + + ['ItemEnchant_Profession_Tailoring'] = { + ['NeedLevel'] = 550, + ['4892'] = true, -- ??? ?? Lightweave Embroidery + ['4893'] = true, -- ??? ?? Darkglow Embroidery + ['4894'] = true, -- ?? ?? Swordguard Embroidery + }, + + ['ProfessionList'] = {}, + + ['CommonScript'] = { + ['OnEnter'] = function(self) + if self.Link or self.Message then + GameTooltip:SetOwner(self, 'ANCHOR_RIGHT') + + self:SetScript('OnUpdate', function() + GameTooltip:ClearLines() + + if self.Link then + GameTooltip:SetHyperlink(self.Link) + end + + if self.Link and self.Message then GameTooltip:AddLine(' ') end -- Line space + + if self.Message then + GameTooltip:AddLine(self.Message, 1, 1, 1) + end + + GameTooltip:Show() + end) + end + end, + ['OnLeave'] = function(self) + self:SetScript('OnUpdate', nil) + GameTooltip:Hide() + end, + ['GemSocket_OnEnter'] = function(self) + GameTooltip:SetOwner(self, 'ANCHOR_RIGHT') + + self = self:GetParent() + + if self.GemItemID then + if type(self.GemItemID) == 'number' then + GameTooltip:SetHyperlink(select(2, GetItemInfo(self.GemItemID))) + else + GameTooltip:ClearLines() + GameTooltip:AddLine(self.GemItemID) + end + elseif self.GemType then + GameTooltip:ClearLines() + GameTooltip:AddLine(_G['EMPTY_SOCKET_'..self.GemType]) + end + + GameTooltip:Show() + end, + ['Transmogrify_OnEnter'] = function(self) + self.Texture:SetVertexColor(1, .8, 1) + + if self.Link then + if GetItemInfo(self.Link) then + GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT') + GameTooltip:SetHyperlink(select(2, GetItemInfo(self.Link))) + GameTooltip:Show() + else + self:SetScript('OnUpdate', function() + if GetItemInfo(self.Link) then + SLArmoryConstants.CommonScript.Transmogrify_OnEnter(self) + self:SetScript('OnUpdate', nil) + end + end) + end + end + end, + ['Transmogrify_OnLeave'] = function(self) + self:SetScript('OnUpdate', nil) + self.Texture:SetVertexColor(1, .5, 1) + + GameTooltip:Hide() + end, + ['ClearTooltip'] = function(tooltip) + local tooltipName = tooltip:GetName() + + tooltip:ClearLines() + for i = 1, 10 do + _G[tooltipName..'Texture'..i]:SetTexture(nil) + _G[tooltipName..'Texture'..i]:ClearAllPoints() + _G[tooltipName..'Texture'..i]:Point('TOPLEFT', tooltip) + end + end, + }, + + ['Toolkit'] = { + ['Color_Value'] = function(InputText) + return E:RGBToHex(E.media.rgbvaluecolor[1], E.media.rgbvaluecolor[2], E.media.rgbvaluecolor[3])..(InputText and InputText..'|r' or '') + end, + + ['Color_Class'] = function(Class, InputText) + return (Class and '|c'..RAID_CLASS_COLORS[Class].colorStr or '')..(InputText and InputText..'|r' or '') + end, + + ['TextSetting'] = function(self, Text, Style, ...) + if Style and Style.Tag then + if not self[Style.Tag] then + self[Style.Tag] = self:CreateFontString(nil, 'OVERLAY') + end + + self = self[Style.Tag] + else + if not Style then + Style = {} + end + + if not self.text then + self.text = self:CreateFontString(nil, 'OVERLAY') + end + + self = self.text + end + + self:FontTemplate(Style.Font and LibStub('LibSharedMedia-3.0'):Fetch('font', Style.Font), Style.FontSize, Style.FontOutline) + self:SetJustifyH(Style.directionH or 'CENTER') + self:SetJustifyV(Style.directionV or 'MIDDLE') + self:SetText(Text) + + if ... then + self:Point(...) + else + self:SetInside() + end + end, + + ['CreateWidget_CheckButton'] = function(buttonName, buttonText, heightSize, fontInfo) + if not _G[buttonName] then + heightSize = heightSize or 24 + fontInfo = fontInfo or { ['FontStyle'] = 'OUTLINE', ['directionH'] = 'LEFT', } + + CreateFrame('Button', buttonName, E.UIParent) + _G[buttonName]:SetHeight(heightSize) + _G[buttonName]:EnableMouse(true) + + _G[buttonName].CheckButtonBG = CreateFrame('Frame', nil, _G[buttonName]) + _G[buttonName].CheckButtonBG:SetTemplate('Default', true) + _G[buttonName].CheckButtonBG:Size(heightSize - 8) + _G[buttonName].CheckButtonBG:SetPoint('LEFT') + + _G[buttonName].CheckButton = _G[buttonName].CheckButtonBG:CreateTexture(nil, 'OVERLAY') + _G[buttonName].CheckButton:Size(heightSize) + _G[buttonName].CheckButton:Point('CENTER', _G[buttonName].CheckButtonBG) + _G[buttonName].CheckButton:SetTexture('Interface\\Buttons\\UI-CheckBox-Check') + + SLArmoryConstants.Toolkit.TextSetting(_G[buttonName], buttonText, fontInfo, 'LEFT', _G[buttonName].CheckButtonBG, 'RIGHT', 6, 0) + + _G[buttonName].hover = _G[buttonName]:CreateTexture(nil, 'HIGHLIGHT') + _G[buttonName].hover:SetTexture('Interface\\Buttons\\UI-CheckBox-Highlight') + _G[buttonName].hover:SetBlendMode('ADD') + _G[buttonName].hover:SetAllPoints(_G[buttonName].CheckButtonBG) + + _G[buttonName]:SetHighlightTexture(_G[buttonName].hover) + _G[buttonName]:SetWidth(_G[buttonName].text:GetWidth() + heightSize + 2) + _G[buttonName]:SetScript('OnMouseDown', function(self) self.text:Point('LEFT', self.CheckButtonBG, 'RIGHT', 6, -2) end) + _G[buttonName]:SetScript('OnMouseUp', function(self) self.text:Point('LEFT', self.CheckButtonBG, 'RIGHT', 6, 0) end) + + return _G[buttonName] + end + end, + }, +} + +--Get Profession Information +local ProfessionName, ProfessionTexture +for ProfessionSkillID, Key in pairs({ + [105206] = 'Alchemy', + [110396] = 'BlackSmithing', + [110400] = 'Enchanting', + [110403] = 'Engineering', + [110417] = 'Inscription', + [110420] = 'JewelCrafting', + [110423] = 'LeatherWorking', + [110426] = 'Tailoring', + + [110413] = 'Herbalism', + [102161] = 'Mining', + [102216] = 'Skinning' +}) +do + ProfessionName, _, ProfessionTexture = GetSpellInfo(ProfessionSkillID) + + SLArmoryConstants.ProfessionList[ProfessionName] = { + ['Key'] = Key, + ['Texture'] = ProfessionTexture + } +end + +--Colorize Class Name and localize specialization name +local ClassName = {} +FillLocalizedClassList(ClassName) + +L['Warrior'] = SLArmoryConstants.Toolkit.Color_Class('WARRIOR', ClassName['WARRIOR']) +_, L['Spec_Warrior_Arms'] = GetSpecializationInfoByID(71) +_, L['Spec_Warrior_Fury'] = GetSpecializationInfoByID(72) +_, L['Spec_Warrior_Protection'] = GetSpecializationInfoByID(73) + +L['Hunter'] = SLArmoryConstants.Toolkit.Color_Class('HUNTER', ClassName['HUNTER']) +_, L['Spec_Hunter_Beast'] = GetSpecializationInfoByID(253) +_, L['Spec_Hunter_Marksmanship'] = GetSpecializationInfoByID(254) +_, L['Spec_Hunter_Survival'] = GetSpecializationInfoByID(255) + +L['Shaman'] = SLArmoryConstants.Toolkit.Color_Class('SHAMAN', ClassName['SHAMAN']) +_, L['Spec_Shaman_Elemental'] = GetSpecializationInfoByID(262) +_, L['Spec_Shaman_Enhancement'] = GetSpecializationInfoByID(263) +_, L['Spec_Shaman_Restoration'] = GetSpecializationInfoByID(264) + +L['Monk'] = SLArmoryConstants.Toolkit.Color_Class('MONK', ClassName['MONK']) +_, L['Spec_Monk_Brewmaster'] = GetSpecializationInfoByID(268) +_, L['Spec_Monk_Mistweaver'] = GetSpecializationInfoByID(270) +_, L['Spec_Monk_Windwalker'] = GetSpecializationInfoByID(269) + +L['Rogue'] = SLArmoryConstants.Toolkit.Color_Class('ROGUE', ClassName['ROGUE']) +_, L['Spec_Rogue_Assassination'] = GetSpecializationInfoByID(259) +_, L['Spec_Rogue_Combat'] = GetSpecializationInfoByID(260) +_, L['Spec_Rogue_Subtlety'] = GetSpecializationInfoByID(261) + +L['DeathKnight'] = SLArmoryConstants.Toolkit.Color_Class('DEATHKNIGHT', ClassName['DEATHKNIGHT']) +_, L['Spec_DeathKnight_Blood'] = GetSpecializationInfoByID(250) +_, L['Spec_DeathKnight_Frost'] = GetSpecializationInfoByID(251) +_, L['Spec_DeathKnight_Unholy'] = GetSpecializationInfoByID(252) + +L['Mage'] = SLArmoryConstants.Toolkit.Color_Class('MAGE', ClassName['MAGE']) +_, L['Spec_Mage_Arcane'] = GetSpecializationInfoByID(62) +_, L['Spec_Mage_Fire'] = GetSpecializationInfoByID(63) +_, L['Spec_Mage_Frost'] = GetSpecializationInfoByID(64) + +L['Druid'] = SLArmoryConstants.Toolkit.Color_Class('DRUID', ClassName['DRUID']) +_, L['Spec_Druid_Balance'] = GetSpecializationInfoByID(102) +_, L['Spec_Druid_Feral'] = GetSpecializationInfoByID(103) +_, L['Spec_Druid_Guardian'] = GetSpecializationInfoByID(104) +_, L['Spec_Druid_Restoration'] = GetSpecializationInfoByID(105) + +L['Paladin'] = SLArmoryConstants.Toolkit.Color_Class('PALADIN', ClassName['PALADIN']) +_, L['Spec_Paladin_Holy'] = GetSpecializationInfoByID(65) +_, L['Spec_Paladin_Protection'] = GetSpecializationInfoByID(66) +_, L['Spec_Paladin_Retribution'] = GetSpecializationInfoByID(70) + +L['Priest'] = SLArmoryConstants.Toolkit.Color_Class('PRIEST', ClassName['PRIEST']) +_, L['Spec_Priest_Discipline'] = GetSpecializationInfoByID(256) +_, L['Spec_Priest_Holy'] = GetSpecializationInfoByID(257) +_, L['Spec_Priest_Shadow'] = GetSpecializationInfoByID(258) + +L['Warlock'] = SLArmoryConstants.Toolkit.Color_Class('WARLOCK', ClassName['WARLOCK']) +_, L['Spec_Warlock_Affliction'] = GetSpecializationInfoByID(265) +_, L['Spec_Warlock_Demonology'] = GetSpecializationInfoByID(266) +_, L['Spec_Warlock_Destruction'] = GetSpecializationInfoByID(267) + + +SLArmoryConstants['ClassRole'] = { + ['WARRIOR'] = { + [L['Spec_Warrior_Arms']] = { --무기 + ['Color'] = '|cff9a9a9a', + ['Role'] = 'Melee', + }, + [L['Spec_Warrior_Fury']] = { --분노 + ['Color'] = '|cffb50000', + ['Role'] = 'Melee', + }, + [L['Spec_Warrior_Protection']] = { --방어 + ['Color'] = '|cff088fdc', + ['Role'] = 'Tank', + }, + }, + ['HUNTER'] = { + [L['Spec_Hunter_Beast']] = { --야수 + ['Color'] = '|cffffdb00', + ['Role'] = 'Melee', + }, + [L['Spec_Hunter_Marksmanship']] = { --사격 + ['Color'] = '|cffea5455', + ['Role'] = 'Melee', + }, + [L['Spec_Hunter_Survival']] = { --생존 + ['Color'] = '|cffbaf71d', + ['Role'] = 'Melee', + }, + }, + ['SHAMAN'] = { + [L['Spec_Shaman_Elemental']] = { --정기 + ['Color'] = '|cff2be5fa', + ['Role'] = 'Caster', + }, + [L['Spec_Shaman_Enhancement']] = { --고양 + ['Color'] = '|cffe60000', + ['Role'] = 'Melee', + }, + [L['Spec_Shaman_Restoration']] = { --복원 + ['Color'] = '|cff00ff0c', + ['Role'] = 'Healer', + }, + }, + ['MONK'] = { + [L['Spec_Monk_Brewmaster']] = { --양조 + ['Color'] = '|cffbcae6d', + ['Role'] = 'Tank', + }, + [L['Spec_Monk_Mistweaver']] = { --운무 + ['Color'] = '|cffb6f1b7', + ['Role'] = 'Healer', + }, + [L['Spec_Monk_Windwalker']] = { --풍운 + ['Color'] = '|cffb2c6de', + ['Role'] = 'Melee', + }, + }, + ['ROGUE'] = { + [L['Spec_Rogue_Assassination']] = { --암살 + ['Color'] = '|cff129800', + ['Role'] = 'Melee', + }, + [L['Spec_Rogue_Combat']] = { --전투 + ['Color'] = '|cffbc0001', + ['Role'] = 'Melee', + }, + [L['Spec_Rogue_Subtlety']] = { --잠행 + ['Color'] = '|cfff48cba', + ['Role'] = 'Melee', + }, + }, + ['DEATHKNIGHT'] = { + [L['Spec_DeathKnight_Blood']] = { --혈기 + ['Color'] = '|cffbc0001', + ['Role'] = 'Tank', + }, + [L['Spec_DeathKnight_Frost']] = { --냉기 + ['Color'] = '|cff1784d1', + ['Role'] = 'Melee', + }, + [L['Spec_DeathKnight_Unholy']] = { --부정 + ['Color'] = '|cff00ff10', + ['Role'] = 'Melee', + }, + }, + ['MAGE'] = { + [L['Spec_Mage_Arcane']] = { --비전 + ['Color'] = '|cffdcb0fb', + ['Role'] = 'Caster', + }, + [L['Spec_Mage_Fire']] = { --화염 + ['Color'] = '|cffff3615', + ['Role'] = 'Caster', + }, + [L['Spec_Mage_Frost']] = { --냉기 + ['Color'] = '|cff1784d1', + ['Role'] = 'Caster', + }, + }, + ['DRUID'] = { + [L['Spec_Druid_Balance']] = { --조화 + ['Color'] = '|cffff7d0a', + ['Role'] = 'Caster', + }, + [L['Spec_Druid_Feral']] = { --야성 + ['Color'] = '|cffffdb00', + ['Role'] = 'Melee', + }, + [L['Spec_Druid_Guardian']] = { --수호 + ['Color'] = '|cff088fdc', + ['Role'] = 'Tank', + }, + [L['Spec_Druid_Restoration']] = { --회복 + ['Color'] = '|cff64df62', + ['Role'] = 'Healer', + }, + }, + ['PALADIN'] = { + [L['Spec_Paladin_Holy']] = { --신성 + ['Color'] = '|cfff48cba', + ['Role'] = 'Healer', + }, + [L['Spec_Paladin_Protection']] = { --보호 + ['Color'] = '|cff84e1ff', + ['Role'] = 'Tank', + }, + [L['Spec_Paladin_Retribution']] = { --징벌 + ['Color'] = '|cffe60000', + ['Role'] = 'Melee', + }, + }, + ['PRIEST'] = { + [L['Spec_Priest_Discipline']] = { --수양 + ['Color'] = '|cffffffff', + ['Role'] = 'Healer', + }, + [L['Spec_Priest_Holy']] = { --신성 + ['Color'] = '|cff6bdaff', + ['Role'] = 'Healer', + }, + [L['Spec_Priest_Shadow']] = { --암흑 + ['Color'] = '|cff7e52c1', + ['Role'] = 'Caster', + }, + }, + ['WARLOCK'] = { + [L['Spec_Warlock_Affliction']] = { --고통 + ['Color'] = '|cff00ff10', + ['Role'] = 'Caster', + }, + [L['Spec_Warlock_Demonology']] = { --악마 + ['Color'] = '|cff9482c9', + ['Role'] = 'Caster', + }, + [L['Spec_Warlock_Destruction']] = { --파괴 + ['Color'] = '|cffba1706', + ['Role'] = 'Caster', + }, + }, +} \ No newline at end of file diff --git a/ElvUI_SLE/modules/characterframe/inspectframe.lua b/ElvUI_SLE/modules/characterframe/inspectframe.lua new file mode 100644 index 0000000..d0fcd34 --- /dev/null +++ b/ElvUI_SLE/modules/characterframe/inspectframe.lua @@ -0,0 +1,2241 @@ +local E, L, V, P, G, _ = unpack(ElvUI) +local AISM = _G['Armory_InspectSupportModule'] +local IFO = E:GetModule('InspectFrameOptions') +-- local IFO = E:NewModule('InspectFrameOptions', 'AceEvent-3.0') +local SLE = E:GetModule('SLE'); +local S = E:GetModule('Skins') + +-------------------------------------------------------------------------------- +--<< KnightFrame : Upgrade Inspect Frame like Wow-Armory >>-- +-------------------------------------------------------------------------------- +local SLI = CreateFrame('Frame', 'KnightInspect', E.UIParent) +local ENI = _G['EnhancedNotifyInspectFrame'] or { ['CancelInspect'] = function() end, } +local ButtonName = INSPECT +local C = SLArmoryConstants + +local CORE_FRAME_LEVEL = 10 +local SLOT_SIZE = 37 +local TAB_HEIGHT = 22 +local SIDE_BUTTON_WIDTH = 16 +local SPACING = 3 +local INFO_TAB_SIZE = 22 +local TALENT_SLOT_SIZE = 26 +local GLYPH_SLOT_HEIGHT = 22 + +local HeadSlotItem = 1020 +local BackSlotItem = 102246 +local Default_NotifyInspect +local Default_InspectUnit + +--<< Key Table >>-- +SLI.PageList = { ['Character'] = 'CHARACTER', ['Info'] = 'INFO', ['Spec'] = 'TALENTS' } +SLI.InfoPageCategoryList = { 'Profession', 'PvP', 'Guild' } +SLI.UnitPopupList = { ['FRIEND'] = true, ['GUILD'] = true, ['RAID'] = true, ['FOCUS'] = true, ['PLAYER'] = true, ['PARTY'] = true, ['RAID_PLAYER'] = true } +SLI.ModelList = { + ['Human'] = { ['RaceID'] = 1, [2] = { ['x'] = 0.02, ['y'] = -0.025, ['z'] = -0.6 }, [3] = { ['x'] = -0.01, ['y'] = -0.08, ['z'] = -0.6 } }, + ['Dwarf'] = { ['RaceID'] = 3, [2] = { ['x'] = -0.01, ['y'] = -0.23, ['z'] = -0.9 }, [3] = { ['x'] = -0.03, ['y'] = -0.15, ['z'] = -0.8 } }, + ['NightElf'] = { ['RaceID'] = 4, [2] = { ['z'] = -0.7 }, [3] = { ['x'] = -0.02, ['y'] = -0.04, ['z'] = -0.7 }}, + ['Gnome'] = { ['RaceID'] = 7, [2] = { ['y'] = -0.2, ['z'] = -1 }, [3] = { ['x'] = -0.01, ['y'] = -0.19, ['z'] = -0.9 } }, + ['Draenei'] = { ['RaceID'] = 11, [2] = { ['x'] = -0.04, ['y'] = -0.08, ['z'] = -0.7 }, [3] = { ['x'] = -0.02, ['y'] = -0.01, ['z'] = -0.6 }}, + ['Worgen'] = { ['RaceID'] = 22, [2] = { ['x'] = -0.09, ['y'] = -0.1, ['z'] = -0.4 }, [3] = { ['x'] = -0.01, ['y'] = 0.01, ['z'] = 0.06 }}, + ['Orc'] = { ['RaceID'] = 2, [2] = { ['y'] = -0.06, ['z'] = -1 }, [3] = { ['x'] = -0.01, ['y'] = -0.05, ['z'] = -0.7 }}, + ['Scourge'] = { ['RaceID'] = 5, [2] = { ['y'] = -0.08, ['z'] = -0.7 }, [3] = { ['y'] = -0.05, ['z'] = -0.6 }}, + ['Tauren'] = { ['RaceID'] = 6, [2] = { ['y'] = -0.09, ['z'] = -0.7 }, [3] = { ['y'] = -0.16, ['z'] = -0.6 } }, + ['Troll'] = { ['RaceID'] = 8, [2] = { ['y'] = -0.14, ['z'] = -1.1 }, [3] = { ['y'] = -0.11, ['z'] = -0.8 }}, + ['BloodElf'] = { ['RaceID'] = 10, [2] = { ['x'] = 0.02, ['y'] = -0.01, ['z'] = -0.5 }, [3] = { ['x'] = 0.04, ['y'] = -0.01, ['z'] = -0.6 }}, + ['Goblin'] = { ['RaceID'] = 9, [2] = { ['y'] = -0.23, ['z'] = -1.3 }, [3] = { ['x'] = -0.01, ['y'] = -0.25, ['z'] = -1.3 } }, + ['Pandaren'] = { ['RaceID'] = 24, [2] = { ['x'] = 0.02, ['y'] = 0.02, ['z'] = -0.6 }, [3] = { ['x'] = 0, ['y'] = -0.05, ['z'] = -1 } }, +} +SLI.CurrentInspectData = {} +SLI.Default_CurrentInspectData = { + ['Gear'] = { + ['HeadSlot'] = {}, ['NeckSlot'] = {}, ['ShoulderSlot'] = {}, ['BackSlot'] = {}, ['ChestSlot'] = {}, + ['ShirtSlot'] = {}, ['TabardSlot'] = {}, ['WristSlot'] = {}, ['MainHandSlot'] = {}, + + ['HandsSlot'] = {}, ['WaistSlot'] = {}, ['LegsSlot'] = {}, ['FeetSlot'] = {}, ['Finger0Slot'] = {}, + ['Finger1Slot'] = {}, ['Trinket0Slot'] = {}, ['Trinket1Slot'] = {}, ['SecondaryHandSlot'] = {} + }, + ['SetItem'] = {}, + ['Specialization'] = { [1] = {}, [2] = {} }, + ['Glyph'] = { [1] = {}, [2] = {} }, + ['Profession'] = { [1] = {}, [2] = {} }, + ['PvP'] = {} +} + +SLI.CurrentGroupMode = 'NoGroup' +local function CheckGroupMode() + local Check + + if not (IsInGroup() or IsInRaid()) or GetNumGroupMembers() == 1 then + Check = 'NoGroup' + else + if IsInRaid() then + Check = 'raid' + else + Check = 'party' + end + end + + if SLI.CurrentGroupMode ~= Check then + SLI.CurrentGroupMode = Check + + end +end +IFO:RegisterEvent('GROUP_ROSTER_UPDATE', CheckGroupMode) +IFO:RegisterEvent('PLAYER_ENTERING_WORLD', CheckGroupMode) + +local function Button_OnEnter(self) + self:SetBackdropBorderColor(unpack(E.media.rgbvaluecolor)) + self.text:SetText(C.Toolkit.Color_Value(self.buttonString)) +end + +local function Button_OnLeave(self) + self:SetBackdropBorderColor(unpack(E.media.bordercolor)) + self.text:SetText(self.buttonString) +end + +function SLI:ChangePage(Type) + for pageType in pairs(self.PageList) do + if self[pageType] then + if Type == pageType..'Button' then + Type = pageType + self[pageType]:Show() + else + self[pageType]:Hide() + end + end + end + + self.MainHandSlot:ClearAllPoints() + self.SecondaryHandSlot:ClearAllPoints() + if Type == 'Character' then + for _, slotName in pairs(C.GearList) do + self[slotName].ItemLevel:Hide() + end + self.Model:Point('TOPRIGHT', self.HandsSlot) + self.MainHandSlot:Point('BOTTOMRIGHT', self.BP, 'TOP', -2, SPACING) + self.SecondaryHandSlot:Point('BOTTOMLEFT', self.BP, 'TOP', 2, SPACING) + else + for _, slotName in pairs(C.GearList) do + self[slotName].ItemLevel:Show() + end + self.Model:Point('TOPRIGHT', UIParent, 'BOTTOMLEFT') + self.MainHandSlot:Point('BOTTOMLEFT', self.BP, 'TOPLEFT', 1, SPACING) + self.SecondaryHandSlot:Point('BOTTOMRIGHT', self.BP, 'TOPRIGHT', -1, SPACING) + end + + if self[Type].Message then + self.Message:SetText(self[Type].Message) + self.MessageFrame.Page:Width(self.Message:GetWidth()) + self.MessageFrame.UpdatedTime = nil + self.MessageFrame.Offset = 0 + self.MessageFrame.Page:ClearAllPoints() + self.MessageFrame.Page:Point('TOPLEFT', self.MessageFrame) + self.MessageFrame.Page:Point('BOTTOMLEFT', self.MessageFrame) + self.MessageFrame:Show() + else + self.MessageFrame:Hide() + end +end + + +SLI.EquipmentSlot_OnEnter = function(self) + if C.CanTransmogrifySlot[self.SlotName] and type(self.TransmogrifyLink) == 'number' and not GetItemInfo(self.TransmogrifyLink) then + self:SetScript('OnUpdate', function() + if GetItemInfo(self.TransmogrifyLink) then + SLI.EquipmentSlot_OnEnter(self) + self:SetScript('OnUpdate', nil) + end + end) + return + end + + if self.Link then + GameTooltip:SetOwner(self, 'ANCHOR_RIGHT') + GameTooltip:SetHyperlink(self.Link) + + local CurrentLineText, SetName + for i = 1, GameTooltip:NumLines() do + CurrentLineText = _G['GameTooltipTextLeft'..i]:GetText() + + SetName = CurrentLineText:match('^(.+) %((%d)/(%d)%)$') + + if SetName then + local SetCount = 0 + + if type(SLI.SetItem[SetName]) == 'table' then + for dataType, Data in pairs(SLI.SetItem[SetName]) do + if type(dataType) == 'string' then -- Means SetOption Data + local CurrentLineNum = i + #SLI.SetItem[SetName] + 1 + dataType:match('^.+(%d)$') + local CurrentText = _G['GameTooltipTextLeft'..CurrentLineNum]:GetText() + local CurrentTextType = CurrentText:match("^%((%d)%)%s.+:%s.+$") or true + + if Data ~= CurrentTextType then + if Data == true and CurrentTextType ~= true then + _G['GameTooltipTextLeft'..CurrentLineNum]:SetText(GREEN_FONT_COLOR_CODE..(strsub(CurrentText, (strlen(CurrentTextType) + 4)))) + else + _G['GameTooltipTextLeft'..CurrentLineNum]:SetText(GRAY_FONT_COLOR_CODE..'('..Data..') '..CurrentText) + end + end + else + if Data:find(LIGHTYELLOW_FONT_COLOR_CODE) then + SetCount = SetCount + 1 + end + + _G['GameTooltipTextLeft'..(i + dataType)]:SetText(Data) + end + end + + _G['GameTooltipTextLeft'..i]:SetText(string.gsub(CurrentLineText, ' %(%d/', ' %('..SetCount..'/', 1)) + end + + break + elseif C.CanTransmogrifySlot[self.SlotName] and C.ItemBindString[CurrentLineText] and self.TransmogrifyAnchor.Link then + _G['GameTooltipTextLeft'..i]:SetText(E:RGBToHex(1, .5, 1)..format(TRANSMOGRIFIED, GetItemInfo(self.TransmogrifyAnchor.Link) or self.TransmogrifyAnchor.Link)..'|r|n'..CurrentLineText) + end + end + + GameTooltip:Show() + end +end +SLI.ScrollFrame_OnMouseWheel = function(self, spinning) + local Page = self:GetScrollChild() + local PageHeight = Page:GetHeight() + local WindowHeight = self:GetHeight() + + if PageHeight > WindowHeight then + self.Offset = (self.Offset or 0) - spinning * 5 + + Page:ClearAllPoints() + if self.Offset > PageHeight - WindowHeight then + self.Offset = PageHeight - WindowHeight + + Page:Point('BOTTOMLEFT', self) + Page:Point('BOTTOMRIGHT', self) + return + elseif self.Offset < 0 then + self.Offset = 0 + end + else + self.Offset = 0 + end + + Page:Point('TOPLEFT', self, 0, self.Offset) + Page:Point('TOPRIGHT', self, 0, self.Offset) +end +SLI.Category_OnClick = function(self) + self = self:GetParent() + + self.Closed = not self.Closed + + SLI:ReArrangeCategory() +end +SLI.GemSocket_OnClick = function(self, button) + self = self:GetParent() + + if self.GemItemID and type(self.GemItemID) == 'number' then + local itemName, itemLink = GetItemInfo(self.GemItemID) + + if not IsShiftKeyDown() then + SetItemRef(itemLink, itemLink, 'LeftButton') + else + if HandleModifiedItemClick(itemLink) then + elseif BrowseName and BrowseName:IsVisible() then + AuctionFrameBrowse_Reset(BrowseResetButton) + BrowseName:SetText(itemName) + BrowseName:SetFocus() + end + end + end +end + +SLI.OnClick = function(self) + if self.Link then + if HandleModifiedItemClick(self.Link) then + elseif self.EnableAuctionSearch and BrowseName and BrowseName:IsVisible() then + AuctionFrameBrowse_Reset(BrowseResetButton) + BrowseName:SetText(self:GetParent().text:GetText()) + BrowseName:SetFocus() + end + end +end + + +function SLI:CreateInspectFrame() + do --<< Core >>-- + self:Size(450, 480) + self:CreateBackdrop('Transparent') + self:SetFrameStrata('DIALOG') + self:SetFrameLevel(CORE_FRAME_LEVEL) + self:SetMovable(true) + self:SetClampedToScreen(true) + self:SetScript('OnHide', function() + PlaySound('igCharacterInfoClose') + + if self.CurrentInspectData.Name then + local TableIndex = self.CurrentInspectData.Name..(SLI.CurrentInspectData.Realm and '-'..SLI.CurrentInspectData.Realm or '') + + if AISM then + if self.LastDataSetting then + AISM.RegisteredFunction[TableIndex] = nil + end + end + + ENI.CancelInspect(TableIndex) + SLI:UnregisterEvent('INSPECT_READY') + SLI:UnregisterEvent('INSPECT_HONOR_UPDATE') + end + + self.LastDataSetting = nil + self.Model:Point('TOPRIGHT', UIParent, 'BOTTOMLEFT') + end) + self:SetScript('OnShow', function() self.Model:Point('TOPRIGHT', self.HandsSlot) end) + self:SetScript('OnEvent', function(self, Event, ...) if self[Event] then self[Event](Event, ...) end end) + UIPanelWindows['KnightInspect'] = { area = 'left', pushable = 1, whileDead = 1 } + end + + do --<< Tab >>-- + self.Tab = CreateFrame('Frame', nil, self) + self.Tab:Point('TOPLEFT', self, SPACING, -SPACING) + self.Tab:Point('BOTTOMRIGHT', self, 'TOPRIGHT', -SPACING, -(SPACING + TAB_HEIGHT)) + self.Tab:SetBackdrop({ + bgFile = E.media.normTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Tab:SetBackdropBorderColor(0, 0, 0) + C.Toolkit.TextSetting(self.Tab, ' |cff2eb7e4S&L Inspect', { ['FontSize'] = 10, ['FontOutline'] = 'OUTLINE', }, 'LEFT', 6, 1) + self.Tab:SetScript('OnMouseDown', function() self:StartMoving() end) + self.Tab:SetScript('OnMouseUp', function() self:StopMovingOrSizing() end) + end + + do --<< Close Button >>-- + self.Close = CreateFrame('Button', nil, self.Tab) + self.Close:Size(TAB_HEIGHT - 8) + self.Close:SetTemplate() + self.Close.backdropTexture:SetVertexColor(0.1, 0.1, 0.1) + self.Close:Point('RIGHT', -4, 0) + C.Toolkit.TextSetting(self.Close, 'X', { ['FontSize'] = 13, }, 'CENTER', 1, 0) + self.Close:SetScript('OnEnter', Button_OnEnter) + self.Close:SetScript('OnLeave', Button_OnLeave) + self.Close:SetScript('OnClick', function() HideUIPanel(self) end) + self.Close.buttonString = 'X' + end + + do --<< Bottom Panel >>-- + self.BP = CreateFrame('Frame', nil, self) + self.BP:Point('TOPLEFT', self, 'BOTTOMLEFT', SPACING, SPACING + TAB_HEIGHT) + self.BP:Point('BOTTOMRIGHT', self, -SPACING, SPACING) + self.BP:SetBackdrop({ + bgFile = E.media.normTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.BP:SetBackdropColor(0.09, 0.3, 0.45) + self.BP:SetBackdropBorderColor(0, 0, 0) + self.BP:SetFrameLevel(CORE_FRAME_LEVEL + 2) + + self.MessageFrame = CreateFrame('ScrollFrame', nil, self.BP) + self.MessageFrame:Point('TOPLEFT', self.BP, SPACING * 2 + TAB_HEIGHT, 0) + self.MessageFrame:Point('BOTTOMRIGHT', self.BP, -10, 1) + self.MessageFrame.UpdateInterval = 3 + self.MessageFrame.ScrollSpeed = 1 + + local PageWidth + local VisibleWidth + self.MessageFrame:SetScript('OnUpdate', function(self, elapsed) + PageWidth = self.Page:GetWidth() + VisibleWidth = self:GetWidth() + + if PageWidth > VisibleWidth then + self.UpdatedTime = (self.UpdatedTime or -self.UpdateInterval) + elapsed + + if self.UpdatedTime > 0 then + if self.Offset then + self.Offset = self.Offset - self.ScrollSpeed + else + self.UpdatedTime = nil + self.Offset = 0 + end + + self.Page:ClearAllPoints() + if self.Offset < VisibleWidth - PageWidth then + self.UpdatedTime = -self.UpdateInterval - 2 + self.Offset = nil + self.Page:Point('TOPRIGHT', self) + self.Page:Point('BOTTOMRIGHT', self) + else + self.Page:Point('TOPLEFT', self, self.Offset, 0) + self.Page:Point('BOTTOMLEFT', self, self.Offset, 0) + end + end + end + end) + + self.MessageFrame.Icon = self.MessageFrame:CreateTexture(nil, 'OVERLAY') + self.MessageFrame.Icon:Size(TAB_HEIGHT) + self.MessageFrame.Icon:Point('TOPLEFT', self.BP, 'TOPLEFT', SPACING * 2, -1) + self.MessageFrame.Icon:SetTexture('Interface\\HELPFRAME\\HelpIcon-ReportAbuse') + + self.MessageFrame.Page = CreateFrame('Frame', nil, self.MessageFrame) + self.MessageFrame:SetScrollChild(self.MessageFrame.Page) + self.MessageFrame.Page:Point('TOPLEFT', self.MessageFrame) + self.MessageFrame.Page:Point('BOTTOMLEFT', self.MessageFrame) + C.Toolkit.TextSetting(self.MessageFrame.Page, '', { ['FontSize'] = 10, ['FontOutline'] = 'OUTLINE', ['directionH'] = 'LEFT' }, 'LEFT', self.MessageFrame.Page) + + self.Message = self.MessageFrame.Page.text + end + + do --<< Background >>-- + self.BG = self:CreateTexture(nil, 'OVERLAY') + self.BG:Point('TOPLEFT', self.Tab, 'BOTTOMLEFT', 0, -38) + self.BG:Point('BOTTOMRIGHT', self.BP, 'TOPRIGHT') + self.BG:SetTexture('Interface\\AddOns\\ElvUI_SLE\\Media\\textures\\Space') + end + + do --<< Buttons >>-- + for buttonName, buttonString in pairs(self.PageList) do + buttonName = buttonName..'Button' + + self[buttonName] = CreateFrame('Button', nil, self.BP) + self[buttonName]:Size(70, 20) + self[buttonName]:SetBackdrop({ + bgFile = E.media.normTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self[buttonName]:SetBackdropBorderColor(0, 0, 0) + self[buttonName]:SetFrameLevel(CORE_FRAME_LEVEL + 1) + C.Toolkit.TextSetting(self[buttonName], _G[buttonString], { ['FontSize'] = 9, ['FontOutline'] = 'OUTLINE' }) + self[buttonName]:SetScript('OnEnter', Button_OnEnter) + self[buttonName]:SetScript('OnLeave', Button_OnLeave) + self[buttonName]:SetScript('OnClick', function() SLI:ChangePage(buttonName) end) + self[buttonName]['buttonString'] = _G[buttonString] + end + self.CharacterButton:Point('TOPLEFT', self.BP, 'BOTTOMLEFT', SPACING + 1, 2) + self.InfoButton:Point('TOPLEFT', self.CharacterButton, 'TOPRIGHT', SPACING, 0) + self.SpecButton:Point('TOPLEFT', self.InfoButton, 'TOPRIGHT', SPACING, 0) + end + + do --<< Bookmark Star >>-- + self.Bookmark = CreateFrame('CheckButton', nil, self) + self.Bookmark:Size(24) + self.Bookmark:EnableMouse(true) + self.Bookmark.NormalTexture = self.Bookmark:CreateTexture(nil, 'OVERLAY') + self.Bookmark.NormalTexture:SetTexCoord(0.5, 1, 0, 0.5) + self.Bookmark.NormalTexture:SetTexture('Interface\\Common\\ReputationStar.tga') + self.Bookmark.NormalTexture:SetInside() + self.Bookmark:SetNormalTexture(self.Bookmark.NormalTexture) + self.Bookmark.HighlightTexture = self.Bookmark:CreateTexture(nil, 'OVERLAY') + self.Bookmark.HighlightTexture:SetTexCoord(0, 0.5, 0.5, 1) + self.Bookmark.HighlightTexture:SetTexture('Interface\\Common\\ReputationStar.tga') + self.Bookmark.HighlightTexture:SetInside() + self.Bookmark:SetHighlightTexture(self.Bookmark.HighlightTexture) + self.Bookmark.CheckedTexture = self.Bookmark:CreateTexture(nil, 'OVERLAY') + self.Bookmark.CheckedTexture:SetTexCoord(0, 0.5, 0, 0.5) + self.Bookmark.CheckedTexture:SetTexture('Interface\\Common\\ReputationStar.tga') + self.Bookmark.CheckedTexture:SetInside() + self.Bookmark:SetCheckedTexture(self.Bookmark.CheckedTexture) + self.Bookmark:Point('LEFT', self.Tab, 'BOTTOMLEFT', 7, -34) + self.Bookmark:Hide() + end + + do --<< Texts >>-- + C.Toolkit.TextSetting(self, nil, { ['Tag'] = 'Name', ['FontSize'] = 22, ['FontOutline'] = 'OUTLINE', }, 'LEFT', self.Bookmark, 'RIGHT', 9, 0) + C.Toolkit.TextSetting(self, nil, { ['Tag'] = 'Title', ['FontSize'] = 12, ['FontOutline'] = 'OUTLINE', }, 'BOTTOMLEFT', self.Name, 'TOPLEFT', 0, 3) + C.Toolkit.TextSetting(self, nil, { ['Tag'] = 'TitleR', ['FontSize'] = 12, ['FontOutline'] = 'OUTLINE', }, 'LEFT', self.Name, 'RIGHT', -2, 7) + C.Toolkit.TextSetting(self, nil, { ['Tag'] = 'LevelRace', ['FontSize'] = 10, ['directionH'] = 'LEFT', }, 'BOTTOMLEFT', self.Name, 'BOTTOMRIGHT', -2, 2) + C.Toolkit.TextSetting(self, nil, { ['Tag'] = 'Guild', ['FontSize'] = 10, ['directionH'] = 'LEFT', }, 'TOPLEFT', self.Name, 'BOTTOMLEFT', 4, -5) + --C.Toolkit.TextSetting(self, nil, { ['Tag'] = 'Realm', ['FontSize'] = 10, ['directionH'] = 'LEFT', }, 'BOTTOMLEFT', self.Name, 'TOPLEFT', 2, 14) + self.Guild:Point('RIGHT', self, -44, 0) + end + + do --<< Class, Specialization Icon >>-- + for _, frameName in pairs({ 'SpecIcon', 'ClassIcon', }) do + self[frameName..'Slot'] = CreateFrame('Frame', nil, self) + self[frameName..'Slot']:Size(24) + self[frameName..'Slot']:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self[frameName] = self[frameName..'Slot']:CreateTexture(nil, 'OVERLAY') + self[frameName]:SetTexCoord(unpack(E.TexCoords)) + self[frameName]:SetInside() + end + self.ClassIconSlot:Point('RIGHT', self.Tab, 'BOTTOMRIGHT', -44, -35) + self.SpecIconSlot:Point('RIGHT', self.ClassIconSlot, 'LEFT', -SPACING, 0) + end + + do --<< Player Model >>-- + self.Model = CreateFrame('DressUpModel', nil, UIParent) + self.Model:SetFrameStrata('DIALOG') + self.Model:SetFrameLevel(CORE_FRAME_LEVEL + 1) + self.Model:EnableMouse(1) + self.Model:EnableMouseWheel(1) + self.Model:SetUnit('player') + self.Model:TryOn(HeadSlotItem) + self.Model:TryOn(BackSlotItem) + self.Model:Undress() + self.Model:SetScript('OnMouseDown', function(self, button) + self.startx, self.starty = GetCursorPosition() + + local endx, endy, z, x, y + if button == 'LeftButton' then + SLI.Model:SetScript('OnUpdate', function(self) + endx, endy = GetCursorPosition() + + self.rotation = (endx - self.startx) / 34 + self:GetFacing() + self:SetFacing(self.rotation) + self.startx, self.starty = GetCursorPosition() + end) + elseif button == 'RightButton' then + SLI.Model:SetScript('OnUpdate', function(self) + endx, endy = GetCursorPosition() + + z, x, y = self:GetPosition(z, x, y) + x = (endx - self.startx) / 45 + x + y = (endy - self.starty) / 45 + y + + self:SetPosition(z, x, y) + self.startx, self.starty = GetCursorPosition() + end) + end + end) + self.Model:SetScript('OnMouseUp', function(self) + self:SetScript('OnUpdate', nil) + end) + self.Model:SetScript('OnMouseWheel', function(self, spining) + local z, x, y = self:GetPosition() + + z = (spining > 0 and z + 0.1 or z - 0.1) + + self:SetPosition(z, x, y) + end) + end + + do --<< Equipment Slots >>-- + self.Character = CreateFrame('Frame', nil, self) + + local Slot + for i, slotName in pairs(C.GearList) do + -- Slot + Slot = CreateFrame('Button', nil, self) + Slot:Size(SLOT_SIZE) + Slot:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + Slot:SetFrameLevel(CORE_FRAME_LEVEL + 3) + Slot:SetScript('OnEnter', self.EquipmentSlot_OnEnter) + Slot:SetScript('OnLeave', C.CommonScript.OnLeave) + Slot:SetScript('OnClick', self.OnClick) + C.Toolkit.TextSetting(Slot, '', { ['FontSize'] = 12, ['FontOutline'] = 'OUTLINE' }) + + Slot.SlotName = slotName + Slot.Direction = i%2 == 1 and 'LEFT' or 'RIGHT' + Slot.ID, Slot.EmptyTexture = GetInventorySlotInfo(slotName) + + Slot.Texture = Slot:CreateTexture(nil, 'OVERLAY') + Slot.Texture:SetTexCoord(unpack(E.TexCoords)) + Slot.Texture:SetInside() + Slot.Texture:SetTexture(Slot.EmptyTexture) + + Slot.Highlight = Slot:CreateTexture('Frame', nil, self) + Slot.Highlight:SetInside() + Slot.Highlight:SetTexture(1, 1, 1, 0.3) + Slot:SetHighlightTexture(Slot.Highlight) + + C.Toolkit.TextSetting(Slot, nil, { ['Tag'] = 'ItemLevel', ['FontSize'] = 10, ['FontOutline'] = 'OUTLINE', }, 'TOP', Slot, 0, -3) + + -- Gradation + Slot.Gradation = CreateFrame('Frame', nil, self.Character) + Slot.Gradation:Size(130, SLOT_SIZE + 4) + Slot.Gradation:SetFrameLevel(CORE_FRAME_LEVEL + 2) + Slot.Gradation:Point(Slot.Direction, Slot, Slot.Direction == 'LEFT' and -1 or 1, 0) + Slot.Gradation.Texture = Slot.Gradation:CreateTexture(nil, 'OVERLAY') + Slot.Gradation.Texture:SetInside() + Slot.Gradation.Texture:SetTexture('Interface\\AddOns\\ElvUI_SLE\\media\\textures\\Gradation') + if Slot.Direction == 'LEFT' then + Slot.Gradation.Texture:SetTexCoord(0, .5, 0, .5) + else + Slot.Gradation.Texture:SetTexCoord(.5, 1, 0, .5) + end + + if not (slotName == 'ShirtSlot' or slotName == 'TabardSlot') then + -- Item Level + C.Toolkit.TextSetting(Slot.Gradation, nil, { ['Tag'] = 'ItemLevel', ['FontSize'] = 10, ['directionH'] = Slot.Direction, }, 'TOP'..Slot.Direction, Slot, 'TOP'..(Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 2 or -2, -1) + + -- Enchantment + C.Toolkit.TextSetting(Slot.Gradation, nil, { ['Tag'] = 'ItemEnchant', ['FontSize'] = 8, ['directionH'] = Slot.Direction, }, Slot.Direction, Slot, Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT', Slot.Direction == 'LEFT' and 2 or -2, 2) + Slot.EnchantWarning = CreateFrame('Button', nil, Slot.Gradation) + Slot.EnchantWarning:Size(12) + Slot.EnchantWarning.Texture = Slot.EnchantWarning:CreateTexture(nil, 'OVERLAY') + Slot.EnchantWarning.Texture:SetInside() + Slot.EnchantWarning.Texture:SetTexture('Interface\\AddOns\\ElvUI_SLE\\media\\textures\\Warning-Small') + Slot.EnchantWarning:Point(Slot.Direction, Slot.Gradation.ItemEnchant, Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT', Slot.Direction == 'LEFT' and 3 or -3, 0) + Slot.EnchantWarning:SetScript('OnEnter', C.CommonScript.OnEnter) + Slot.EnchantWarning:SetScript('OnLeave', C.CommonScript.OnLeave) + + -- Gem Socket + for i = 1, MAX_NUM_SOCKETS do + Slot['Socket'..i] = CreateFrame('Frame', nil, Slot.Gradation) + Slot['Socket'..i]:Size(12) + Slot['Socket'..i]:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + Slot['Socket'..i]:SetBackdropColor(0, 0, 0, 1) + Slot['Socket'..i]:SetBackdropBorderColor(0, 0, 0) + Slot['Socket'..i]:SetFrameLevel(CORE_FRAME_LEVEL + 3) + + Slot['Socket'..i].Socket = CreateFrame('Button', nil, Slot['Socket'..i]) + Slot['Socket'..i].Socket:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + Slot['Socket'..i].Socket:SetInside() + Slot['Socket'..i].Socket:SetFrameLevel(CORE_FRAME_LEVEL + 4) + Slot['Socket'..i].Socket:SetScript('OnEnter', C.CommonScript.GemSocket_OnEnter) + Slot['Socket'..i].Socket:SetScript('OnLeave', C.CommonScript.OnLeave) + Slot['Socket'..i].Socket:SetScript('OnClick', self.GemSocket_OnClick) + + Slot['Socket'..i].Texture = Slot['Socket'..i].Socket:CreateTexture(nil, 'OVERLAY') + Slot['Socket'..i].Texture:SetTexCoord(.1, .9, .1, .9) + Slot['Socket'..i].Texture:SetInside() + end + Slot.Socket1:Point('BOTTOM'..Slot.Direction, Slot, 'BOTTOM'..(Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 3 or -3, 2) + Slot.Socket2:Point(Slot.Direction, Slot.Socket1, Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT', Slot.Direction == 'LEFT' and 1 or -1, 0) + Slot.Socket3:Point(Slot.Direction, Slot.Socket2, Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT', Slot.Direction == 'LEFT' and 1 or -1, 0) + + Slot.SocketWarning = CreateFrame('Button', nil, Slot.Gradation) + Slot.SocketWarning:Size(12) + Slot.SocketWarning.Texture = Slot.SocketWarning:CreateTexture(nil, 'OVERLAY') + Slot.SocketWarning.Texture:SetInside() + Slot.SocketWarning.Texture:SetTexture('Interface\\AddOns\\ElvUI_SLE\\media\\textures\\Warning-Small') + Slot.SocketWarning:SetScript('OnEnter', C.CommonScript.OnEnter) + Slot.SocketWarning:SetScript('OnLeave', C.CommonScript.OnLeave) + + if C.CanTransmogrifySlot[slotName] then + Slot.TransmogrifyAnchor = CreateFrame('Button', nil, Slot.Gradation) + Slot.TransmogrifyAnchor:Size(12) + Slot.TransmogrifyAnchor:SetFrameLevel(CORE_FRAME_LEVEL + 4) + Slot.TransmogrifyAnchor:Point('BOTTOM'..Slot.Direction, Slot) + Slot.TransmogrifyAnchor:SetScript('OnEnter', C.CommonScript.Transmogrify_OnEnter) + Slot.TransmogrifyAnchor:SetScript('OnLeave', C.CommonScript.Transmogrify_OnLeave) + + Slot.TransmogrifyAnchor.Texture = Slot.TransmogrifyAnchor:CreateTexture(nil, 'OVERLAY') + Slot.TransmogrifyAnchor.Texture:SetInside() + Slot.TransmogrifyAnchor.Texture:SetTexture('Interface\\AddOns\\ElvUI_SLE\\media\\textures\\anchor') + Slot.TransmogrifyAnchor.Texture:SetVertexColor(1, .5, 1) + + if Slot.Direction == 'LEFT' then + Slot.TransmogrifyAnchor.Texture:SetTexCoord(0, 1, 0, 1) + else + Slot.TransmogrifyAnchor.Texture:SetTexCoord(1, 0, 0, 1) + end + end + end + + self[slotName] = Slot + end + + -- Slot Location : Left + self.HeadSlot:Point('BOTTOMLEFT', self.NeckSlot, 'TOPLEFT', 0, SPACING) + self.NeckSlot:Point('BOTTOMLEFT', self.ShoulderSlot, 'TOPLEFT', 0, SPACING) + self.ShoulderSlot:Point('BOTTOMLEFT', self.BackSlot, 'TOPLEFT', 0, SPACING) + self.BackSlot:Point('BOTTOMLEFT', self.ChestSlot, 'TOPLEFT', 0, SPACING) + self.ChestSlot:Point('BOTTOMLEFT', self.ShirtSlot, 'TOPLEFT', 0, SPACING) + self.ShirtSlot:Point('BOTTOMLEFT', self.TabardSlot, 'TOPLEFT', 0, SPACING) + self.TabardSlot:Point('BOTTOMLEFT', self.WristSlot, 'TOPLEFT', 0, SPACING) + self.WristSlot:Point('LEFT', self.BP, 1, 0) + self.WristSlot:Point('BOTTOM', self.MainHandSlot, 'TOP', 0, SPACING) + + -- Slot Location : Right + self.HandsSlot:Point('BOTTOMRIGHT', self.WaistSlot, 'TOPRIGHT', 0, SPACING) + self.WaistSlot:Point('BOTTOMRIGHT', self.LegsSlot, 'TOPRIGHT', 0, SPACING) + self.LegsSlot:Point('BOTTOMRIGHT', self.FeetSlot, 'TOPRIGHT', 0, SPACING) + self.FeetSlot:Point('BOTTOMRIGHT', self.Finger0Slot, 'TOPRIGHT', 0, SPACING) + self.Finger0Slot:Point('BOTTOMRIGHT', self.Finger1Slot, 'TOPRIGHT', 0, SPACING) + self.Finger1Slot:Point('BOTTOMRIGHT', self.Trinket0Slot, 'TOPRIGHT', 0, SPACING) + self.Trinket0Slot:Point('BOTTOMRIGHT', self.Trinket1Slot, 'TOPRIGHT', 0, SPACING) + self.Trinket1Slot:Point('RIGHT', self.BP, -1, 0) + self.Trinket1Slot:Point('BOTTOM', self.SecondaryHandSlot, 'TOP', 0, SPACING) + + -- ItemLevel + C.Toolkit.TextSetting(self.Character, nil, { ['Tag'] = 'AverageItemLevel', ['FontSize'] = 12, }, 'TOP', self.Model) + end + + self.Model:Point('TOPLEFT', self.HeadSlot) + self.Model:Point('BOTTOM', self.BP, 'TOP', 0, SPACING) + + do --<< Information Page >>-- + self.Info = CreateFrame('ScrollFrame', nil, self) + self.Info:SetFrameLevel(CORE_FRAME_LEVEL + 5) + self.Info:EnableMouseWheel(1) + self.Info:SetScript('OnMouseWheel', self.ScrollFrame_OnMouseWheel) + + self.Info.BG = CreateFrame('Frame', nil, self.Info) + self.Info.BG:SetFrameLevel(CORE_FRAME_LEVEL + 1) + self.Info.BG:Point('TOPLEFT', self.HeadSlot, 'TOPRIGHT', SPACING, 0) + self.Info.BG:Point('RIGHT', self.Trinket1Slot, 'BOTTOMLEFT', -SPACING, 0) + self.Info.BG:Point('BOTTOM', self.BP, 'TOP', 0, SPACING) + self.Info.BG:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Info.BG:SetBackdropColor(0, 0, 0, .7) + + self.Info:Point('TOPLEFT', self.Info.BG, 4, -7) + self.Info:Point('BOTTOMRIGHT', self.Info.BG, -4, 7) + + self.Info.Page = CreateFrame('Frame', nil, self.Info) + self.Info:SetScrollChild(self.Info.Page) + self.Info.Page:SetFrameLevel(CORE_FRAME_LEVEL + 2) + self.Info.Page:Point('TOPLEFT', self.Info) + self.Info.Page:Point('TOPRIGHT', self.Info, -1, 0) + + for _, CategoryType in pairs(SLI.InfoPageCategoryList) do + self.Info[CategoryType] = CreateFrame('ScrollFrame', nil, self.Info.Page) + self.Info[CategoryType]:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Info[CategoryType]:SetBackdropColor(.08, .08, .08, .8) + self.Info[CategoryType]:SetBackdropBorderColor(0, 0, 0) + self.Info[CategoryType]:Point('LEFT', self.Info.Page) + self.Info[CategoryType]:Point('RIGHT', self.Info.Page) + self.Info[CategoryType]:Height(INFO_TAB_SIZE + SPACING * 2) + + self.Info[CategoryType].IconSlot = CreateFrame('Frame', nil, self.Info[CategoryType]) + self.Info[CategoryType].IconSlot:Size(INFO_TAB_SIZE) + self.Info[CategoryType].IconSlot:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Info[CategoryType].IconSlot:Point('TOPLEFT', self.Info[CategoryType], SPACING, -SPACING) + self.Info[CategoryType].Icon = self.Info[CategoryType].IconSlot:CreateTexture(nil, 'OVERLAY') + self.Info[CategoryType].Icon:SetTexCoord(unpack(E.TexCoords)) + self.Info[CategoryType].Icon:SetInside() + + self.Info[CategoryType].Tab = CreateFrame('Frame', nil, self.Info[CategoryType]) + self.Info[CategoryType].Tab:Point('TOPLEFT', self.Info[CategoryType].IconSlot, 'TOPRIGHT', 1, 0) + self.Info[CategoryType].Tab:Point('BOTTOMRIGHT', self.Info[CategoryType], 'TOPRIGHT', -SPACING, -(SPACING + INFO_TAB_SIZE)) + self.Info[CategoryType].Tab:SetBackdrop({ + bgFile = E.media.normTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + + self.Info[CategoryType].Tooltip = CreateFrame('Button', nil, self.Info[CategoryType]) + self.Info[CategoryType].Tooltip:Point('TOPLEFT', self.Info[CategoryType].Icon) + self.Info[CategoryType].Tooltip:Point('BOTTOMRIGHT', self.Info[CategoryType].Tab) + self.Info[CategoryType].Tooltip:SetFrameLevel(CORE_FRAME_LEVEL + 4) + self.Info[CategoryType].Tooltip:SetScript('OnClick', SLI.Category_OnClick) + + C.Toolkit.TextSetting(self.Info[CategoryType].Tab, CategoryType, { ['FontSize'] = 10 }, 'LEFT', 6, 1) + + self.Info[CategoryType].Page = CreateFrame('Frame', nil, self.Info[CategoryType]) + self.Info[CategoryType]:SetScrollChild(self.Info[CategoryType].Page) + self.Info[CategoryType].Page:SetFrameLevel(CORE_FRAME_LEVEL + 2) + self.Info[CategoryType].Page:Point('TOPLEFT', self.Info[CategoryType].IconSlot, 'BOTTOMLEFT', 0, -SPACING) + self.Info[CategoryType].Page:Point('BOTTOMRIGHT', self.Info[CategoryType], -SPACING, SPACING) + end + + do -- Profession Part + self.Info.Profession.CategoryHeight = INFO_TAB_SIZE + 34 + SPACING * 3 + self.Info.Profession.Icon:SetTexture(GetSpellTexture(110396)) + + for i = 1, 2 do + self.Info.Profession['Prof'..i] = CreateFrame('Frame', nil, self.Info.Profession.Page) + self.Info.Profession['Prof'..i]:Size(20) + self.Info.Profession['Prof'..i]:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Info.Profession['Prof'..i]:SetBackdropBorderColor(0, 0, 0) + + self.Info.Profession['Prof'..i].Icon = self.Info.Profession['Prof'..i]:CreateTexture(nil, 'OVERLAY') + self.Info.Profession['Prof'..i].Icon:SetTexCoord(unpack(E.TexCoords)) + self.Info.Profession['Prof'..i].Icon:SetInside() + + self.Info.Profession['Prof'..i].BarFrame = CreateFrame('Frame', nil, self.Info.Profession['Prof'..i]) + self.Info.Profession['Prof'..i].BarFrame:Size(136, 5) + self.Info.Profession['Prof'..i].BarFrame:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Info.Profession['Prof'..i].BarFrame:SetBackdropColor(0, 0, 0) + self.Info.Profession['Prof'..i].BarFrame:SetBackdropBorderColor(0, 0, 0) + self.Info.Profession['Prof'..i].BarFrame:Point('BOTTOMLEFT', self.Info.Profession['Prof'..i], 'BOTTOMRIGHT', SPACING, 0) + + self.Info.Profession['Prof'..i].Bar = CreateFrame('StatusBar', nil, self.Info.Profession['Prof'..i].BarFrame) + self.Info.Profession['Prof'..i].Bar:SetInside() + self.Info.Profession['Prof'..i].Bar:SetStatusBarTexture(E.media.normTex) + self.Info.Profession['Prof'..i].Bar:SetMinMaxValues(0, 600) + + C.Toolkit.TextSetting(self.Info.Profession['Prof'..i], nil, { ['Tag'] = 'Level', ['FontSize'] = 10 }, 'TOP', self.Info.Profession['Prof'..i].Icon) + self.Info.Profession['Prof'..i].Level:Point('RIGHT', self.Info.Profession['Prof'..i].Bar) + + C.Toolkit.TextSetting(self.Info.Profession['Prof'..i], nil, { ['Tag'] = 'Name', ['FontSize'] = 10, ['directionH'] = 'LEFT' }, 'TOP', self.Info.Profession['Prof'..i].Icon) + self.Info.Profession['Prof'..i].Name:Point('LEFT', self.Info.Profession['Prof'..i].Bar) + self.Info.Profession['Prof'..i].Name:Point('RIGHT', self.Info.Profession['Prof'..i].Level, 'LEFT', -SPACING, 0) + end + + self.Info.Profession.Prof1:Point('TOPLEFT', self.Info.Profession.Page, 6, -7) + self.Info.Profession.Prof2:Point('TOPLEFT', self.Info.Profession.Page, 'TOP', 6, -7) + end + + do -- PvP Category + self.Info.PvP.CategoryHeight = 90 + self.Info.PvP.Icon:SetTexture('Interface\\Icons\\achievement_bg_killxenemies_generalsroom') + + self.Info.PvP.PageLeft = CreateFrame('Frame', nil, self.Info.PvP.Page) + self.Info.PvP.PageLeft:Point('TOP', self.Info.PvP.Page) + self.Info.PvP.PageLeft:Point('LEFT', self.Info.PvP.Page) + self.Info.PvP.PageLeft:Point('BOTTOMRIGHT', self.Info.PvP.Page, 'BOTTOM') + self.Info.PvP.PageLeft:SetFrameLevel(CORE_FRAME_LEVEL + 3) + self.Info.PvP.PageRight = CreateFrame('Frame', nil, self.Info.PvP.Page) + self.Info.PvP.PageRight:Point('TOP', self.Info.PvP.Page) + self.Info.PvP.PageRight:Point('RIGHT', self.Info.PvP.Page) + self.Info.PvP.PageRight:Point('BOTTOMLEFT', self.Info.PvP.Page, 'BOTTOM') + self.Info.PvP.PageRight:SetFrameLevel(CORE_FRAME_LEVEL + 3) + + for i = 1, 3 do + self.Info.PvP['Bar'..i] = self.Info.PvP.Page:CreateTexture(nil, 'OVERLAY') + self.Info.PvP['Bar'..i]:SetTexture(0, 0, 0) + self.Info.PvP['Bar'..i]:Width(2) + end + self.Info.PvP.Bar1:Point('TOP', self.Info.PvP.PageLeft, 0, -SPACING * 2) + self.Info.PvP.Bar1:Point('BOTTOM', self.Info.PvP.PageLeft, 0, SPACING * 2) + self.Info.PvP.Bar2:Point('TOP', self.Info.PvP.Page, 0, -SPACING * 2) + self.Info.PvP.Bar2:Point('BOTTOM', self.Info.PvP.Page, 0, SPACING * 2) + self.Info.PvP.Bar3:Point('TOP', self.Info.PvP.PageRight, 0, -SPACING * 2) + self.Info.PvP.Bar3:Point('BOTTOM', self.Info.PvP.PageRight, 0, SPACING * 2) + + for _, Type in pairs({ '2vs2', '3vs3', '5vs5', 'RB' }) do + self.Info.PvP[Type] = CreateFrame('Frame', nil, self.Info.PvP.Page) + self.Info.PvP[Type]:SetFrameLevel(CORE_FRAME_LEVEL + 4) + + self.Info.PvP[Type].Rank = self.Info.PvP.Page:CreateTexture(nil, 'OVERLAY') + self.Info.PvP[Type].Rank:SetTexture('Interface\\ACHIEVEMENTFRAME\\UI-ACHIEVEMENT-SHIELDS') + self.Info.PvP[Type].Rank:SetTexCoord(0, .5, 0, .5) + self.Info.PvP[Type].Rank:Size(83, 57) + self.Info.PvP[Type].Rank:Point('TOP', self.Info.PvP[Type], 0, -10) + self.Info.PvP[Type].Rank:Hide() + self.Info.PvP[Type].RankGlow = self.Info.PvP.Page:CreateTexture(nil, 'OVERLAY') + self.Info.PvP[Type].RankGlow:SetTexture('Interface\\ACHIEVEMENTFRAME\\UI-ACHIEVEMENT-SHIELDS') + self.Info.PvP[Type].RankGlow:SetBlendMode('ADD') + self.Info.PvP[Type].RankGlow:SetTexCoord(0, .5, 0, .5) + self.Info.PvP[Type].RankGlow:Point('TOPLEFT', self.Info.PvP[Type].Rank) + self.Info.PvP[Type].RankGlow:Point('BOTTOMRIGHT', self.Info.PvP[Type].Rank) + self.Info.PvP[Type].RankGlow:Hide() + self.Info.PvP[Type].RankNoLeaf = self.Info.PvP.Page:CreateTexture(nil, 'OVERLAY') + self.Info.PvP[Type].RankNoLeaf:SetTexture('Interface\\ACHIEVEMENTFRAME\\UI-Achievement-Progressive-Shield') + self.Info.PvP[Type].RankNoLeaf:SetTexCoord(0, .66, 0, .77) + self.Info.PvP[Type].RankNoLeaf:Point('CENTER', self.Info.PvP[Type].Rank, 0, 2) + self.Info.PvP[Type].RankNoLeaf:SetVertexColor(.2, .4, 1) + self.Info.PvP[Type].RankNoLeaf:Size(80, 65) + + C.Toolkit.TextSetting(self.Info.PvP[Type], nil, { ['Tag'] = 'Type', ['FontSize'] = 10, ['FontOutline'] = 'OUTLINE' }, 'TOPLEFT', self.Info.PvP[Type]) + self.Info.PvP[Type].Type:Point('TOPRIGHT', self.Info.PvP[Type]) + self.Info.PvP[Type].Type:SetHeight(22) + C.Toolkit.TextSetting(self.Info.PvP[Type], nil, { ['Tag'] = 'Rating', ['FontSize'] = 22, ['FontOutline'] = 'OUTLINE' }, 'CENTER', self.Info.PvP[Type].Rank, 0, 3) + C.Toolkit.TextSetting(self.Info.PvP[Type], nil, { ['Tag'] = 'Record', ['FontSize'] = 10, ['FontOutline'] = 'OUTLINE' }, 'TOP', self.Info.PvP[Type].Rank, 'BOTTOM', 0, 12) + end + self.Info.PvP['2vs2']:Point('TOP', self.Info.PvP.Bar1) + self.Info.PvP['2vs2']:Point('LEFT', self.Info.PvP.Page) + self.Info.PvP['2vs2']:Point('BOTTOMRIGHT', self.Info.PvP.Bar1, 'BOTTOMLEFT', -SPACING, 0) + self.Info.PvP['2vs2'].Type:SetText(ARENA_2V2) + + self.Info.PvP['3vs3']:Point('TOPLEFT', self.Info.PvP.Bar1, 'TOPRIGHT', SPACING, 0) + self.Info.PvP['3vs3']:Point('BOTTOMRIGHT', self.Info.PvP.Bar2, 'BOTTOMLEFT', -SPACING, 0) + self.Info.PvP['3vs3'].Type:SetText(ARENA_3V3) + + self.Info.PvP['5vs5']:Point('TOPLEFT', self.Info.PvP.Bar2, 'TOPRIGHT', SPACING, 0) + self.Info.PvP['5vs5']:Point('BOTTOMRIGHT', self.Info.PvP.Bar3, 'BOTTOMLEFT', -SPACING, 0) + self.Info.PvP['5vs5'].Type:SetText(ARENA_5V5) + + self.Info.PvP.RB:Point('TOP', self.Info.PvP.Bar3) + self.Info.PvP.RB:Point('RIGHT', self.Info.PvP.Page) + self.Info.PvP.RB:Point('BOTTOMLEFT', self.Info.PvP.Bar3, 'BOTTOMRIGHT', SPACING, 0) + self.Info.PvP.RB.Type:SetText(PVP_RATED_BATTLEGROUNDS) + end + + do -- Guild Category + self.Info.Guild.CategoryHeight = INFO_TAB_SIZE + 66 + SPACING * 3 + self.Info.Guild.Icon:SetTexture(GetSpellTexture(83968)) + + self.Info.Guild.Banner = CreateFrame('Frame', nil, self.Info.Guild.Page) + self.Info.Guild.Banner:SetInside() + self.Info.Guild.Banner:SetFrameLevel(CORE_FRAME_LEVEL + 3) + + self.Info.Guild.BG = self.Info.Guild.Banner:CreateTexture(nil, 'BACKGROUND') + self.Info.Guild.BG:Size(33, 44) + self.Info.Guild.BG:SetTexCoord(.00781250, .32812500, .01562500, .84375000) + self.Info.Guild.BG:SetTexture('Interface\\GuildFrame\\GuildDifficulty') + self.Info.Guild.BG:Point('TOP', self.Info.Guild.Page) + + self.Info.Guild.Border = self.Info.Guild.Banner:CreateTexture(nil, 'ARTWORK') + self.Info.Guild.Border:Size(33, 44) + self.Info.Guild.Border:SetTexCoord(.34375000, .66406250, .01562500, .84375000) + self.Info.Guild.Border:SetTexture('Interface\\GuildFrame\\GuildDifficulty') + self.Info.Guild.Border:Point('CENTER', self.Info.Guild.BG) + + self.Info.Guild.Emblem = self.Info.Guild.Banner:CreateTexture(nil, 'OVERLAY') + self.Info.Guild.Emblem:Size(16) + self.Info.Guild.Emblem:SetTexture('Interface\\GuildFrame\\GuildEmblems_01') + self.Info.Guild.Emblem:Point('CENTER', self.Info.Guild.BG, 0, 2) + + C.Toolkit.TextSetting(self.Info.Guild.Banner, nil, { ['Tag'] = 'Name', ['FontSize'] = 14 }, 'TOP', self.Info.Guild.BG, 'BOTTOM', 0, 7) + C.Toolkit.TextSetting(self.Info.Guild.Banner, nil, { ['Tag'] = 'LevelMembers', ['FontSize'] = 9 }, 'TOP', self.Info.Guild.Banner.Name, 'BOTTOM', 0, -2) + end + end + + do --<< Specialization Page >>-- + self.Spec = CreateFrame('ScrollFrame', nil, self) + self.Spec:SetFrameLevel(CORE_FRAME_LEVEL + 5) + self.Spec:EnableMouseWheel(1) + self.Spec:SetScript('OnMouseWheel', self.ScrollFrame_OnMouseWheel) + + self.Spec.BGFrame = CreateFrame('Frame', nil, self.Spec) + self.Spec.BGFrame:SetFrameLevel(CORE_FRAME_LEVEL + 1) + self.Spec.BG = self.Spec.BGFrame:CreateTexture(nil, 'BACKGROUND') + self.Spec.BG:Point('TOP', self.HeadSlot, 'TOPRIGHT', 0, -30) + self.Spec.BG:Point('LEFT', self.WristSlot, 'TOPRIGHT', SPACING, 0) + self.Spec.BG:Point('RIGHT', self.Trinket1Slot, 'BOTTOMLEFT', -SPACING, 0) + self.Spec.BG:Point('BOTTOM', self.BP, 'TOP', 0, SPACING) + self.Spec.BG:SetTexture(0, 0, 0, .7) + + self.Spec:Point('TOPLEFT', self.Spec.BG, 4, -7) + self.Spec:Point('BOTTOMRIGHT', self.Spec.BG, -4, 7) + + self.Spec.Page = CreateFrame('Frame', nil, self.Spec) + self.Spec:SetScrollChild(self.Spec.Page) + self.Spec.Page:SetFrameLevel(CORE_FRAME_LEVEL + 2) + self.Spec.Page:Point('TOPLEFT', self.Spec) + self.Spec.Page:Point('TOPRIGHT', self.Spec) + self.Spec.Page:Height((TALENT_SLOT_SIZE + SPACING * 3) * MAX_NUM_TALENT_TIERS + (SPACING + GLYPH_SLOT_HEIGHT) * 3 + 22) + + self.Spec.BottomBorder = self.Spec:CreateTexture(nil, 'OVERLAY') + self.Spec.BottomBorder:Point('TOPLEFT', self.Spec.BG, 'BOTTOMLEFT', 0, E.mult) + self.Spec.BottomBorder:Point('BOTTOMRIGHT', self.Spec.BG) + self.Spec.LeftBorder = self.Spec:CreateTexture(nil, 'OVERLAY') + self.Spec.LeftBorder:Point('TOPLEFT', self.Spec.BG) + self.Spec.LeftBorder:Point('BOTTOMLEFT', self.Spec.BottomBorder, 'TOPLEFT') + self.Spec.LeftBorder:Width(E.mult) + self.Spec.RightBorder = self.Spec:CreateTexture(nil, 'OVERLAY') + self.Spec.RightBorder:Point('TOPRIGHT', self.Spec.BG) + self.Spec.RightBorder:Point('BOTTOMRIGHT', self.Spec.BottomBorder, 'TOPRIGHT') + self.Spec.RightBorder:Width(E.mult) + + do -- Specialization Tab + for i = 1, MAX_TALENT_GROUPS do + self.Spec['Spec'..i] = CreateFrame('Button', nil, self.Spec) + self.Spec['Spec'..i]:Size(150, 30) + self.Spec['Spec'..i]:SetScript('OnClick', function() self:ToggleSpecializationTab(i, self.CurrentInspectData) end) + + self.Spec['Spec'..i].Tab = CreateFrame('Frame', nil, self.Spec['Spec'..i]) + self.Spec['Spec'..i].Tab:Size(120, 30) + self.Spec['Spec'..i].Tab:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = 0, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Spec['Spec'..i].Tab:SetBackdropColor(0, 0, 0, .7) + self.Spec['Spec'..i].Tab:SetBackdropBorderColor(0, 0, 0, 0) + self.Spec['Spec'..i].Tab:Point('TOPRIGHT', self.Spec['Spec'..i]) + C.Toolkit.TextSetting(self.Spec['Spec'..i].Tab, nil, { ['FontSize'] = 10, ['FontOutline'] = 'OUTLINE' }, 'TOPLEFT', 0, 0) + self.Spec['Spec'..i].Tab.text:Point('BOTTOMRIGHT', 0, -4) + + self.Spec['Spec'..i].Icon = CreateFrame('Frame', nil, self.Spec['Spec'..i].Tab) + self.Spec['Spec'..i].Icon:Size(27, 26) + self.Spec['Spec'..i].Icon:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Spec['Spec'..i].Icon:SetBackdropColor(0, 0, 0, .7) + self.Spec['Spec'..i].Icon:Point('TOPLEFT', self.Spec['Spec'..i]) + + self.Spec['Spec'..i].Texture = self.Spec['Spec'..i].Icon:CreateTexture(nil, 'OVERLAY') + self.Spec['Spec'..i].Texture:SetTexCoord(unpack(E.TexCoords)) + self.Spec['Spec'..i].Texture:SetInside() + + self.Spec['Spec'..i].TopBorder = self.Spec['Spec'..i].Tab:CreateTexture(nil, 'OVERLAY') + self.Spec['Spec'..i].TopBorder:Point('TOPLEFT', self.Spec['Spec'..i].Tab) + self.Spec['Spec'..i].TopBorder:Point('BOTTOMRIGHT', self.Spec['Spec'..i].Tab, 'TOPRIGHT', 0, -E.mult) + + self.Spec['Spec'..i].LeftBorder = self.Spec['Spec'..i].Tab:CreateTexture(nil, 'OVERLAY') + self.Spec['Spec'..i].LeftBorder:Point('TOPLEFT', self.Spec['Spec'..i].TopBorder, 'BOTTOMLEFT') + self.Spec['Spec'..i].LeftBorder:Point('BOTTOMRIGHT', self.Spec['Spec'..i].Tab, 'BOTTOMLEFT', E.mult, 0) + + self.Spec['Spec'..i].RightBorder = self.Spec['Spec'..i].Tab:CreateTexture(nil, 'OVERLAY') + self.Spec['Spec'..i].RightBorder:Point('TOPLEFT', self.Spec['Spec'..i].TopBorder, 'BOTTOMRIGHT', -E.mult, 0) + self.Spec['Spec'..i].RightBorder:Point('BOTTOMRIGHT', self.Spec['Spec'..i].Tab) + + self.Spec['Spec'..i].BottomLeftBorder = self.Spec['Spec'..i].Tab:CreateTexture(nil, 'OVERLAY') + self.Spec['Spec'..i].BottomLeftBorder:Point('TOPLEFT', self.Spec.BG, 0, E.mult) + self.Spec['Spec'..i].BottomLeftBorder:Point('BOTTOMRIGHT', self.Spec['Spec'..i].LeftBorder, 'BOTTOMLEFT') + + self.Spec['Spec'..i].BottomRightBorder = self.Spec['Spec'..i].Tab:CreateTexture(nil, 'OVERLAY') + self.Spec['Spec'..i].BottomRightBorder:Point('TOPRIGHT', self.Spec.BG, 0, E.mult) + self.Spec['Spec'..i].BottomRightBorder:Point('BOTTOMLEFT', self.Spec['Spec'..i].RightBorder, 'BOTTOMRIGHT') + end + self.Spec.Spec1:Point('BOTTOMLEFT', self.Spec.BG, 'TOPLEFT', 20, 0) + self.Spec.Spec2:Point('BOTTOMRIGHT', self.Spec.BG, 'TOPRIGHT', -20, 0) + end + + for i = 1, MAX_NUM_TALENT_TIERS do + self.Spec['TalentTier'..i] = CreateFrame('Frame', nil, self.Spec.Page) + self.Spec['TalentTier'..i]:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Spec['TalentTier'..i]:SetBackdropColor(.08, .08, .08) + self.Spec['TalentTier'..i]:SetBackdropBorderColor(0, 0, 0) + self.Spec['TalentTier'..i]:SetFrameLevel(CORE_FRAME_LEVEL + 2) + self.Spec['TalentTier'..i]:Size(352, TALENT_SLOT_SIZE + SPACING * 2) + + for k = 1, NUM_TALENT_COLUMNS do + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)] = CreateFrame('Frame', nil, self.Spec['TalentTier'..i]) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)]:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)]:SetFrameLevel(CORE_FRAME_LEVEL + 3) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)]:Size(114, TALENT_SLOT_SIZE) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon = CreateFrame('Frame', nil, self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)]) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon:Size(20) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon.Texture = self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon:CreateTexture(nil, 'OVERLAY') + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon.Texture:SetTexCoord(unpack(E.TexCoords)) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon.Texture:SetInside() + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon:Point('LEFT', self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)], SPACING, 0) + C.Toolkit.TextSetting(self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)], nil, { ['FontSize'] = 9, ['directionH'] = 'LEFT' }, 'TOPLEFT', self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon, 'TOPRIGHT', SPACING, SPACING) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].text:Point('BOTTOMLEFT', self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon, 'BOTTOMRIGHT', SPACING, -SPACING) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].text:Point('RIGHT', -SPACING, 0) + + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Tooltip = CreateFrame('Button', nil, self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)]) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Tooltip:SetFrameLevel(CORE_FRAME_LEVEL + 4) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Tooltip:SetInside() + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Tooltip:SetScript('OnClick', self.OnClick) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Tooltip:SetScript('OnEnter', C.CommonScript.OnEnter) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Tooltip:SetScript('OnLeave', C.CommonScript.OnLeave) + end + + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + 1)]:Point('RIGHT', self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + 2)], 'LEFT', -2, 0) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + 2)]:Point('CENTER', self.Spec['TalentTier'..i]) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + 3)]:Point('LEFT', self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + 2)], 'RIGHT', 2, 0) + end + + self.Spec.TalentTier1:Point('TOP', self.Spec.Page, 0, -2) + self.Spec.TalentTier2:Point('TOP', self.Spec.TalentTier1, 'BOTTOM', 0, -SPACING) + self.Spec.TalentTier3:Point('TOP', self.Spec.TalentTier2, 'BOTTOM', 0, -SPACING) + self.Spec.TalentTier4:Point('TOP', self.Spec.TalentTier3, 'BOTTOM', 0, -SPACING) + self.Spec.TalentTier5:Point('TOP', self.Spec.TalentTier4, 'BOTTOM', 0, -SPACING) + self.Spec.TalentTier6:Point('TOP', self.Spec.TalentTier5, 'BOTTOM', 0, -SPACING) + + for _, groupName in pairs({ 'MAJOR_GLYPH', 'MINOR_GLYPH' }) do + self.Spec['GLYPH_'..groupName] = CreateFrame('Frame', nil, self.Spec.Page) + self.Spec['GLYPH_'..groupName]:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Spec['GLYPH_'..groupName]:SetBackdropColor(.08, .08, .08) + self.Spec['GLYPH_'..groupName]:SetBackdropBorderColor(0, 0, 0) + self.Spec['GLYPH_'..groupName]:Height(GLYPH_SLOT_HEIGHT * 3 + SPACING * 3 + 22) + C.Toolkit.TextSetting(self.Spec['GLYPH_'..groupName], '|cffceff00<|r '.._G[groupName]..' |cffceff00>|r', { ['FontSize'] = 10 }, 'TOP', self.Spec['GLYPH_'..groupName], 0, -5) + end + + for i = 1, NUM_GLYPH_SLOTS do + self.Spec['Glyph'..i] = CreateFrame('Button', nil, self.Spec.Page) + self.Spec['Glyph'..i]:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Spec['Glyph'..i]:SetFrameLevel(CORE_FRAME_LEVEL + 2) + self.Spec['Glyph'..i]:Height(GLYPH_SLOT_HEIGHT) + + self.Spec['Glyph'..i].NeedLevel = (i == 1 or i == 2) and 25 or (i == 3 or i == 4) and 50 or 75 + + self.Spec['Glyph'..i].Icon = CreateFrame('Frame', nil, self.Spec['Glyph'..i]) + self.Spec['Glyph'..i].Icon:Size(16) + self.Spec['Glyph'..i].Icon:SetBackdrop({ + bgFile = E.media.blankTex, + edgeFile = E.media.blankTex, + tile = false, tileSize = 0, edgeSize = E.mult, + insets = { left = 0, right = 0, top = 0, bottom = 0} + }) + self.Spec['Glyph'..i].Icon:SetBackdropColor(.15, .15, .15) + self.Spec['Glyph'..i].Icon:SetFrameLevel(CORE_FRAME_LEVEL + 3) + self.Spec['Glyph'..i].Icon.Texture = self.Spec['Glyph'..i].Icon:CreateTexture(nil, 'OVERLAY') + self.Spec['Glyph'..i].Icon.Texture:SetTexCoord(unpack(E.TexCoords)) + self.Spec['Glyph'..i].Icon.Texture:SetInside() + self.Spec['Glyph'..i].Icon:Point('LEFT', self.Spec['Glyph'..i], SPACING, 0) + + self.Spec['Glyph'..i].Tooltip = CreateFrame('Button', nil, self.Spec['Glyph'..i]) + self.Spec['Glyph'..i].Tooltip:SetFrameLevel(CORE_FRAME_LEVEL + 4) + self.Spec['Glyph'..i].Tooltip:SetInside() + self.Spec['Glyph'..i].Tooltip:SetScript('OnClick', self.OnClick) + self.Spec['Glyph'..i].Tooltip:SetScript('OnEnter', C.CommonScript.OnEnter) + self.Spec['Glyph'..i].Tooltip:SetScript('OnLeave', C.CommonScript.OnLeave) + self.Spec['Glyph'..i].Tooltip.EnableAuctionSearch = true + + C.Toolkit.TextSetting(self.Spec['Glyph'..i], nil, { ['FontSize'] = 9, ['directionH'] = 'LEFT' }, 'LEFT', self.Spec['Glyph'..i].Icon, 'RIGHT', SPACING, 0) + self.Spec['Glyph'..i].text:Point('RIGHT', self.Spec['Glyph'..i], -SPACING, 0) + end + + self.Spec.Glyph2:Point('TOP', self.Spec.GLYPH_MAJOR_GLYPH.text, 'BOTTOM', 0, -7) + self.Spec.Glyph2:Point('LEFT', self.Spec.GLYPH_MAJOR_GLYPH, SPACING, 0) + self.Spec.Glyph2:Point('RIGHT', self.Spec.GLYPH_MAJOR_GLYPH, -SPACING, 0) + self.Spec.Glyph4:Point('TOPLEFT', self.Spec.Glyph2, 'BOTTOMLEFT', 0, -SPACING) + self.Spec.Glyph4:Point('TOPRIGHT', self.Spec.Glyph2, 'BOTTOMRIGHT', 0, -SPACING) + self.Spec.Glyph6:Point('TOPLEFT', self.Spec.Glyph4, 'BOTTOMLEFT', 0, -SPACING) + self.Spec.Glyph6:Point('TOPRIGHT', self.Spec.Glyph4, 'BOTTOMRIGHT', 0, -SPACING) + + self.Spec.Glyph1:Point('TOP', self.Spec.GLYPH_MINOR_GLYPH.text, 'BOTTOM', 0, -7) + self.Spec.Glyph1:Point('LEFT', self.Spec.GLYPH_MINOR_GLYPH, SPACING, 0) + self.Spec.Glyph1:Point('RIGHT', self.Spec.GLYPH_MINOR_GLYPH, -SPACING, 0) + self.Spec.Glyph3:Point('TOPLEFT', self.Spec.Glyph1, 'BOTTOMLEFT', 0, -SPACING) + self.Spec.Glyph3:Point('TOPRIGHT', self.Spec.Glyph1, 'BOTTOMRIGHT', 0, -SPACING) + self.Spec.Glyph5:Point('TOPLEFT', self.Spec.Glyph3, 'BOTTOMLEFT', 0, -SPACING) + self.Spec.Glyph5:Point('TOPRIGHT', self.Spec.Glyph3, 'BOTTOMRIGHT', 0, -SPACING) + + self.Spec.GLYPH_MAJOR_GLYPH:Point('TOPLEFT', self.Spec['TalentTier'..MAX_NUM_TALENT_TIERS], 'BOTTOMLEFT', 0, -SPACING) + self.Spec.GLYPH_MAJOR_GLYPH:Point('TOPRIGHT', self.Spec['TalentTier'..MAX_NUM_TALENT_TIERS], 'BOTTOM', -2, -SPACING) + self.Spec.GLYPH_MINOR_GLYPH:Point('TOPLEFT', self.Spec['TalentTier'..MAX_NUM_TALENT_TIERS], 'BOTTOM', 2, -SPACING) + self.Spec.GLYPH_MINOR_GLYPH:Point('TOPRIGHT', self.Spec['TalentTier'..MAX_NUM_TALENT_TIERS], 'BOTTOMRIGHT', 0, -SPACING) + end + + do --<< Scanning Tooltip >>-- + self.ScanTTForInspecting = CreateFrame('GameTooltip', 'KnightInspectScanTT_I', nil, 'GameTooltipTemplate') + self.ScanTTForInspecting:SetOwner(UIParent, 'ANCHOR_NONE') + self.ScanTT = CreateFrame('GameTooltip', 'KnightInspectScanTT', nil, 'GameTooltipTemplate') + self.ScanTT:SetOwner(UIParent, 'ANCHOR_NONE') + end + + do --<< UnitPopup Setting >>-- + KnightInspect_UnitPopup.Highlight = KnightInspect_UnitPopup:CreateTexture(nil, 'BACKGROUND') + KnightInspect_UnitPopup.Highlight:SetTexture('Interface\\QuestFrame\\UI-QuestTitleHighlight') + KnightInspect_UnitPopup.Highlight:SetBlendMode('ADD') + KnightInspect_UnitPopup.Highlight:SetAllPoints() + KnightInspect_UnitPopup:SetHighlightTexture(KnightInspect_UnitPopup.Highlight) + --KnightInspect_UnitPopup:SetText('KnightInspect') + + KnightInspect_UnitPopup:SetScript('OnEnter', function() + UIDropDownMenu_StopCounting(DropDownList1) + end) + KnightInspect_UnitPopup:SetScript('OnLeave', function() + UIDropDownMenu_StartCounting(DropDownList1) + end) + KnightInspect_UnitPopup:SetScript('OnHide', function(self) + if self.Anchored then + self.Anchored = nil + self.Data = nil + self:SetParent(nil) + self:ClearAllPoints() + self:Hide() + end + end) + KnightInspect_UnitPopup:SetScript('OnClick', function(self) + local SendChannel + + if AISM and AISM.AISMUserList[self.Data.TableIndex] then + if self.Data.Realm == E.myrealm then + SendChannel = 'WHISPER' + elseif AISM.AISMUserList[self.Data.TableIndex] == 'GUILD' then + SendChannel = 'GUILD' + elseif SLI.CurrentGroupMode ~= 'NoGroup' and type(AISM.GroupMemberData[self.Data.TableIndex]) == 'table' then + SendChannel = IsInGroup(LE_PARTY_CATEGORY_INSTANCE) and 'INSTANCE_CHAT' or string.upper(SLI.CurrentGroupMode) + end + end + + if SendChannel then + ENI.CancelInspect(self.Data.TableIndex) + SLI:UnregisterEvent('INSPECT_READY') + + SLI.NeedModelSetting = true + SLI.CurrentInspectData = E:CopyTable({}, SLI.Default_CurrentInspectData) + AISM.CurrentInspectData[self.Data.TableIndex] = { + ['UnitID'] = self.Data.Unit, + } + + local TableIndex = self.Data.TableIndex + AISM:RegisterInspectDataRequest(function(User, UserData) + if User == TableIndex then + E:CopyTable(SLI.CurrentInspectData, UserData) + SLI:ShowFrame(SLI.CurrentInspectData) + + return true + end + end, self.Data.TableIndex, true) + SendAddonMessage('AISM_Inspect', 'AISM_DataRequestForInspecting:'..self.Data.Name..'-'..self.Data.Realm, SendChannel, self.Data.TableIndex) + elseif self.Data.Unit then + SLI.InspectUnit(self.Data.Unit) + end + + DropDownList1:Hide() + end) + KnightInspect_UnitPopup:SetScript('OnUpdate', function(self) + if not (self:GetPoint() and self:GetParent()) then + self:Hide() + return + end + + if AISM and (type(AISM.GroupMemberData[self.Data.TableIndex]) == 'table' or AISM.AISMUserList[self.Data.TableIndex]) or self.Data.Unit and UnitIsVisible(self.Data.Unit) and UnitIsConnected(self.Data.Unit) and not UnitIsDeadOrGhost('player') then + self:SetText(C.Toolkit.Color_Value(ButtonName)) + self:Enable() + else + self:SetText(ButtonName) + self:Disable() + end + end) + + hooksecurefunc('UnitPopup_ShowMenu', function(Menu, Type, Unit, Name) + if SLI.Activate and UIDROPDOWNMENU_MENU_LEVEL == 1 and SLI.UnitPopupList[Type] then + local Button + local DataTable = { + ['Name'] = Menu.name or Name, + ['Unit'] = UnitExists(Menu.name) and Menu.name or Unit, + ['Realm'] = Menu.server ~= '' and Menu.server or E.myrealm + } + + if DataTable.Name == E.myname then return end + + DataTable.TableIndex = DataTable.Unit and GetUnitName(DataTable.Unit, 1) or DataTable.Name..(DataTable.Realm ~= E.myrealm and '-'..DataTable.Realm or '') + + for i = 1, DropDownList1.numButtons do + if _G['DropDownList1Button'..i].value == 'INSPECT' then + Button = _G['DropDownList1Button'..i] + break + end + end + + if not Button then + if DataTable.Unit and (UnitCanAttack('player', DataTable.Unit) or not UnitIsConnected(DataTable.Unit) or not UnitIsPlayer(DataTable.Unit)) then + if AISM then + AISM.AISMUserList[DataTable.TableIndex] = nil + AISM.GroupMemberData[DataTable.TableIndex] = nil + end + + return + elseif DataTable.Unit or AISM and (Menu.which == 'GUILD' or AISM.AISMUserList[DataTable.TableIndex] or AISM.GroupMemberData[DataTable.TableIndex]) then + Button = UIDropDownMenu_CreateInfo() + Button.notCheckable = 1 + UIDropDownMenu_AddButton(Button) + + Button = _G['DropDownList1Button'..DropDownList1.numButtons] + end + end + + if Button then + Button.value = 'KnightInspect' + Button:SetText((' '):rep(strlen(ButtonName))) + + KnightInspect_UnitPopup:Show() + KnightInspect_UnitPopup:SetParent('DropDownList1') + KnightInspect_UnitPopup:SetFrameStrata(Button:GetFrameStrata()) + KnightInspect_UnitPopup:SetFrameLevel(Button:GetFrameLevel() + 1) + KnightInspect_UnitPopup:ClearAllPoints() + KnightInspect_UnitPopup:Point('TOPLEFT', Button) + KnightInspect_UnitPopup:Point('BOTTOMRIGHT', Button) + KnightInspect_UnitPopup.Anchored = true + KnightInspect_UnitPopup.Data = DataTable + + if AISM and not (AISM.AISMUserList[DataTable.TableIndex] or AISM.GroupMemberData[DataTable.TableIndex]) then + if DataTable.Unit and not (UnitCanAttack('player', DataTable.Unit) or not UnitIsConnected(DataTable.Unit) or not UnitIsPlayer(DataTable.Unit)) and DataTable.Realm == E.myrealm then + SendAddonMessage('AISM', 'AISM_Check', 'WHISPER', DataTable.Name) + elseif Menu.which == 'GUILD' then + SendAddonMessage('AISM', 'AISM_GUILD_Check', DataTable.Realm == E.myrealm and 'WHISPER' or 'GUILD', DataTable.Name) + end + end + end + end + end) + end + + do --<< Updater >>-- + self.Updater = CreateFrame('Frame') + self.Updater:Hide() + end + + HideUIPanel(self) + + self.CreateInspectFrame = nil +end + + +SLI.INSPECT_HONOR_UPDATE = function(Event) + if Event or HasInspectHonorData() then + for i, Type in pairs({ '2vs2', '3vs3', '5vs5' }) do + SLI.CurrentInspectData.PvP[Type] = { GetInspectArenaData(i) } + for i = 4, #SLI.CurrentInspectData.PvP[Type] do + SLI.CurrentInspectData.PvP[Type][i] = nil + end + end + SLI.CurrentInspectData.PvP.RB = { GetInspectRatedBGData() } + SLI.CurrentInspectData.PvP.Honor = select(5, GetInspectHonorData()) + end + + if not SLI.ForbidUpdatePvPInformation then + SLI:InspectFrame_PvPSetting(SLI.CurrentInspectData) + end +end + + +SLI.INSPECT_READY = function(Event, InspectedUnitGUID) + local TableIndex = SLI.CurrentInspectData.Name..(SLI.CurrentInspectData.Realm and '-'..SLI.CurrentInspectData.Realm or '') + local UnitID = TableIndex + local Name, Realm = UnitFullName(UnitID) + + if not Name then + UnitID = SLI.CurrentInspectData.UnitID + Name, Realm = UnitFullName(UnitID) + end + + if not Name then + _, _, _, _, _, Name, Realm = GetPlayerInfoByGUID(InspectedUnitGUID) + end + + if not (SLI.CurrentInspectData.Name == Name and SLI.CurrentInspectData.Realm == Realm and SLI.CurrentInspectData.UnitGUID == InspectedUnitGUID) then + if UnitGUID(UnitID) ~= SLI.CurrentInspectData.UnitGUID then + ENI.CancelInspect(TableIndex) + SLI:UnregisterEvent('INSPECT_READY') + SLI:UnregisterEvent('INSPECT_HONOR_UPDATE') + end + return + elseif HasInspectHonorData() then + SLI.INSPECT_HONOR_UPDATE() + end + + _, _, SLI.CurrentInspectData.Race, SLI.CurrentInspectData.RaceID, SLI.CurrentInspectData.GenderID = GetPlayerInfoByGUID(InspectedUnitGUID) + + local needReinspect + local CurrentSetItem = {} + local Slot, SlotTexture, SlotLink, CheckSpace, colorR, colorG, colorB, tooltipText, TransmogrifiedItem, SetName, SetItemCount, SetItemMax, SetOptionCount + for _, SlotName in pairs(C.GearList) do + Slot = SLI[SlotName] + SLI.CurrentInspectData.Gear[SlotName] = {} + + SlotTexture = GetInventoryItemTexture(UnitID, Slot.ID) + + if SlotTexture and SlotTexture..'.blp' ~= Slot.EmptyTexture then + SlotLink = GetInventoryItemLink(UnitID, Slot.ID) + + if not SlotLink then + needReinspect = 'SlotLink_NotLoaded' -- this will stop setting inspect frame + else + SLI.CurrentInspectData.Gear[SlotName].ItemLink = SlotLink + + C.CommonScript.ClearTooltip(SLI.ScanTTForInspecting) + SLI.ScanTTForInspecting:SetInventoryItem(UnitID, Slot.ID) + + TransmogrifiedItem = nil + checkSpace = 2 + SetOptionCount = 1 + + for i = 1, SLI.ScanTTForInspecting:NumLines() do + tooltipText = _G['KnightInspectScanTT_ITextLeft'..i]:GetText() + + if not TransmogrifiedItem and tooltipText:match(C.TransmogrifiedKey) then + if type(SLI.CurrentInspectData.Gear[SlotName].Transmogrify) ~= 'number' then + SLI.CurrentInspectData.Gear[SlotName].Transmogrify = tooltipText:match(C.TransmogrifiedKey) + end + + TransmogrifiedItem = true + end + + SetName, SetItemCount, SetItemMax = tooltipText:match('^(.+) %((%d)/(%d)%)$') -- find string likes 'SetName (0/5)' + if SetName then + SetItemCount = tonumber(SetItemCount) + SetItemMax = tonumber(SetItemMax) + + if (SetItemCount > SetItemMax or SetItemMax == 1) and not needReinspect then + needReinspect = true + break + else + if not (CurrentSetItem[SetName] or SLI.CurrentInspectData.SetItem[SetName]) and not needReinspect then + needReinspect = true + end + + CurrentSetItem[SetName] = CurrentSetItem[SetName] or {} + + for k = 1, SLI.ScanTTForInspecting:NumLines() do + tooltipText = _G['KnightInspectScanTT_ITextLeft'..(i+k)]:GetText() + + if tooltipText == ' ' then + checkSpace = checkSpace - 1 + + if checkSpace == 0 then break end + elseif checkSpace == 2 then + colorR, colorG, colorB = _G['KnightInspectScanTT_ITextLeft'..(i+k)]:GetTextColor() + + if colorR > LIGHTYELLOW_FONT_COLOR.r - 0.01 and colorR < LIGHTYELLOW_FONT_COLOR.r + 0.01 and colorG > LIGHTYELLOW_FONT_COLOR.g - 0.01 and colorG < LIGHTYELLOW_FONT_COLOR.g + 0.01 and colorB > LIGHTYELLOW_FONT_COLOR.b - 0.01 and colorB < LIGHTYELLOW_FONT_COLOR.b + 0.01 then + tooltipText = LIGHTYELLOW_FONT_COLOR_CODE..tooltipText + else + tooltipText = GRAY_FONT_COLOR_CODE..tooltipText + end + + if CurrentSetItem[SetName][k] and CurrentSetItem[SetName][k] ~= tooltipText and not needReinspect then + needReinspect = true + end + + CurrentSetItem[SetName][k] = tooltipText + elseif tooltipText:find(C.ItemSetBonusKey) then + tooltipText = tooltipText:match("^%((%d)%)%s.+:%s.+$") or true + + if CurrentSetItem[SetName]['SetOption'..SetOptionCount] and CurrentSetItem[SetName]['SetOption'..SetOptionCount] ~= tooltipText and not needReinspect then + needReinspect = true + end + + CurrentSetItem[SetName]['SetOption'..SetOptionCount] = tooltipText + SetOptionCount = SetOptionCount + 1 + end + end + SLI.CurrentInspectData.SetItem[SetName] = CurrentSetItem[SetName] + + break + end + end + + if checkSpace == 0 then break end + end + end + end + end + + if SLI.CurrentInspectData.SetItem then + for SetName in pairs(SLI.CurrentInspectData.SetItem) do + if not CurrentSetItem[SetName] then + SLI.CurrentInspectData.SetItem[SetName] = nil + end + end + end + + -- Specialization + SLI.CurrentInspectData.Specialization[1].SpecializationID = GetInspectSpecialization(UnitID) + for i = 1, NUM_TALENT_COLUMNS * MAX_NUM_TALENT_TIERS do + SLI.CurrentInspectData.Specialization[1]['Talent'..i] = select(5, GetTalentInfo(i, true, nil, UnitID, SLI.CurrentInspectData.ClassID)) + end + + -- Glyph + local SpellID, GlyphID + for i = 1, NUM_GLYPH_SLOTS do + _, _, _, SpellID, _, GlyphID = GetGlyphSocketInfo(i, nil, true, UnitID) + + SLI.CurrentInspectData.Glyph[1]['Glyph'..i..'SpellID'] = SpellID or 0 + SLI.CurrentInspectData.Glyph[1]['Glyph'..i..'ID'] = GlyphID or 0 + end + + -- Guild + SLI.CurrentInspectData.guildLevel, _, SLI.CurrentInspectData.guildNumMembers = GetInspectGuildInfo(UnitID) + SLI.CurrentInspectData.guildEmblem = { GetGuildLogoInfo(UnitID) } + + if needReinspect and needReinspect ~= true then + return + end + + SLI.ForbidUpdatePvPInformation = nil + SLI:ShowFrame(SLI.CurrentInspectData) + + if needReinspect then + return + elseif SLI.ReinspectCount > 0 then + SLI.ReinspectCount = SLI.ReinspectCount - 1 + else + ENI.CancelInspect(TableIndex) + SLI:UnregisterEvent('INSPECT_READY') + end +end + + +SLI.InspectUnit = function(UnitID) + if UnitID == 'mouseover' and not UnitExists('mouseover') and UnitExists('target') then + UnitID = 'target' + end + + if not UnitIsPlayer(UnitID) then + return + elseif UnitIsDeadOrGhost('player') then + SLE:Print(L["You can't inspect while dead."]) --print('|cff2eb7e4[S&L]|r : '..L["You can't inspect while dead."]) + return + elseif not UnitIsVisible(UnitID) then + + return + else + UnitID = NotifyInspect(UnitID, true) or UnitID + + SLI.CurrentInspectData = E:CopyTable({}, SLI.Default_CurrentInspectData) + + SLI.CurrentInspectData.UnitID = UnitID + SLI.CurrentInspectData.UnitGUID = UnitGUID(UnitID) + SLI.CurrentInspectData.Title = UnitPVPName(UnitID) + SLI.CurrentInspectData.Level = UnitLevel(UnitID) + SLI.CurrentInspectData.Name, SLI.CurrentInspectData.Realm = UnitFullName(UnitID) + _, SLI.CurrentInspectData.Class, SLI.CurrentInspectData.ClassID = UnitClass(UnitID) + SLI.CurrentInspectData.guildName, SLI.CurrentInspectData.guildRankName = GetGuildInfo(UnitID) + + SLI.CurrentInspectData.Realm = SLI.CurrentInspectData.Realm ~= '' and SLI.CurrentInspectData.Realm ~= E.myrealm and SLI.CurrentInspectData.Realm or nil + + SLI.ReinspectCount = 1 + SLI.NeedModelSetting = true + SLI.ForbidUpdatePvPInformation = true + SLI:RegisterEvent('INSPECT_READY') + SLI:RegisterEvent('INSPECT_HONOR_UPDATE') + end +end + + +function SLI:ShowFrame(DataTable) + self.GET_ITEM_INFO_RECEIVED = nil + self:UnregisterEvent('GET_ITEM_INFO_RECEIVED') + + for _, slotName in pairs(C.GearList) do + if DataTable.Gear[slotName] and DataTable.Gear[slotName].ItemLink and not GetItemInfo(DataTable.Gear[slotName].ItemLink) then + self.GET_ITEM_INFO_RECEIVED = function() self:ShowFrame(DataTable) end + end + end + + if self.GET_ITEM_INFO_RECEIVED then + self:RegisterEvent('GET_ITEM_INFO_RECEIVED') + return + end + + self.Updater:Show() + self.Updater:SetScript('OnUpdate', function() + if not self:InspectFrame_DataSetting(DataTable) then + self.Updater:SetScript('OnUpdate', nil) + self.Updater:Hide() + + self:InspectFrame_PvPSetting(DataTable) + ShowUIPanel(KnightInspect) + end + end) +end + + +function SLI:InspectFrame_DataSetting(DataTable) + local needUpdate, needUpdateList + local r, g, b + + do --<< Equipment Slot and Enchant, Gem Setting >>-- + local ErrorDetected + local ItemCount, ItemTotal = 0, 0 + local Slot, ItemRarity, BasicItemLevel, TrueItemLevel, ItemUpgradeID, ItemTexture, IsEnchanted, CurrentLineText, GemCount_Default, GemCount_Enable, GemCount_Now, GemCount + local arg1, itemID, enchantID, arg2, arg3, arg4, arg5, arg6 + + -- Setting except shirt and tabard + for _, slotName in pairs(self.GearUpdated or C.GearList) do + if slotName ~= 'ShirtSlot' and slotName ~= 'TabardSlot' then + Slot = self[slotName] + + do --<< Clear Setting >>-- + needUpdate, ErrorDetected, TrueItemLevel, IsEnchanted, ItemUpgradeID, ItemTexture, r, g, b = nil, nil, nil, nil, nil, nil, 0, 0, 0 + + Slot.Link = nil + Slot.ItemLevel:SetText(nil) + Slot.Gradation.ItemLevel:SetText(nil) + Slot.Gradation.ItemEnchant:SetText(nil) + for i = 1, MAX_NUM_SOCKETS do + Slot['Socket'..i].Texture:SetTexture(nil) + Slot['Socket'..i].GemItemID = nil + Slot['Socket'..i].GemType = nil + Slot['Socket'..i]:Hide() + end + Slot.EnchantWarning:Hide() + Slot.EnchantWarning.Message = nil + Slot.SocketWarning:Point(Slot.Direction, Slot.Socket1) + Slot.SocketWarning:Hide() + Slot.SocketWarning.Link = nil + Slot.SocketWarning.Message = nil + end + + if DataTable.Gear[slotName].ItemLink then + _, Slot.Link = GetItemInfo(DataTable.Gear[slotName].ItemLink) + + do --<< Gem Parts >>-- + arg1, itemID, enchantID, _, _, _, _, arg2, arg3, arg4, arg5, arg6 = strsplit(':', Slot.Link) + + C.CommonScript.ClearTooltip(self.ScanTT) + self.ScanTT:SetHyperlink(format('%s:%s:%d:0:0:0:0:%s:%s:%s:%s:%s', arg1, itemID, enchantID, arg2, arg3, arg4, arg5, arg6)) + + GemCount_Default, GemCount_Now, GemCount = 0, 0, 0 + + -- First, Counting default gem sockets + for i = 1, MAX_NUM_SOCKETS do + ItemTexture = _G['KnightInspectScanTTTexture'..i]:GetTexture() + + if ItemTexture and ItemTexture:find('Interface\\ItemSocketingFrame\\') then + GemCount_Default = GemCount_Default + 1 + Slot['Socket'..GemCount_Default].GemType = strupper(gsub(ItemTexture, 'Interface\\ItemSocketingFrame\\UI--EmptySocket--', '')) + end + end + + -- Second, Check if slot's item enable to adding a socket + GemCount_Enable = GemCount_Default + if (slotName == 'WaistSlot' and DataTable.Level >= 70) or -- buckle + ((slotName == 'WristSlot' or slotName == 'HandsSlot') and (DataTable.Profession[1].Name == GetSpellInfo(110396) and DataTable.Profession[1].Level >= 550 or DataTable.Profession[2].Name == GetSpellInfo(110396) and DataTable.Profession[2].Level >= 550)) then -- BlackSmith + + GemCount_Enable = GemCount_Enable + 1 + Slot['Socket'..GemCount_Enable].GemType = 'PRISMATIC' + end + + C.CommonScript.ClearTooltip(self.ScanTT) + self.ScanTT:SetHyperlink(Slot.Link) + + -- Apply current item's gem setting + for i = 1, MAX_NUM_SOCKETS do + ItemTexture = _G['KnightInspectScanTTTexture'..i]:GetTexture() + + if Slot['Socket'..i].GemType and C.GemColor[Slot['Socket'..i].GemType] then + r, g, b = unpack(C.GemColor[Slot['Socket'..i].GemType]) + Slot['Socket'..i].Socket:SetBackdropColor(r, g, b, 0.5) + Slot['Socket'..i].Socket:SetBackdropBorderColor(r, g, b) + else + Slot['Socket'..i].Socket:SetBackdropColor(1, 1, 1, 0.5) + Slot['Socket'..i].Socket:SetBackdropBorderColor(1, 1, 1) + end + + CurrentLineText = select(2, _G['KnightInspectScanTTTexture'..i]:GetPoint()) + CurrentLineText = DataTable.Gear[slotName]['Gem'..i] or CurrentLineText ~= self.ScanTT and CurrentLineText.GetText and CurrentLineText:GetText():gsub('|cff......', ''):gsub('|r', '') or nil + + if CurrentLineText then + Slot['Socket'..i]:Show() + GemCount_Now = GemCount_Now + 1 + Slot.SocketWarning:Point(Slot.Direction, Slot['Socket'..i], (Slot.Direction == 'LEFT' and 'RIGHT' or 'LEFT'), Slot.Direction == 'LEFT' and 3 or -3, 0) + + ItemTexture = ItemTexture or DataTable.Gear[slotName]['Gem'..i] and select(10, GetItemInfo(DataTable.Gear[slotName]['Gem'..i])) or nil + + if not ItemTexture then + needUpdate = true + elseif not C.EmptySocketString[CurrentLineText] then + GemCount = GemCount + 1 + Slot['Socket'..i].GemItemID = CurrentLineText + Slot['Socket'..i].Texture:SetTexture(ItemTexture) + end + end + end + + if GemCount_Now < GemCount_Default then -- ItemInfo not loaded + needUpdate = true + end + end + + _, _, ItemRarity, BasicItemLevel, _, _, _, _, _, ItemTexture = GetItemInfo(Slot.Link) + r, g, b = GetItemQualityColor(ItemRarity) + + ItemUpgradeID = Slot.Link:match(':(%d+)\124h%[') + + --<< Enchant Parts >>-- + for i = 1, self.ScanTT:NumLines() do + CurrentLineText = _G['KnightInspectScanTTTextLeft'..i]:GetText() + + if CurrentLineText:find(C.ItemLevelKey_Alt) then + TrueItemLevel = tonumber(CurrentLineText:match(C.ItemLevelKey_Alt)) + elseif CurrentLineText:find(C.ItemLevelKey) then + TrueItemLevel = tonumber(CurrentLineText:match(C.ItemLevelKey)) + elseif CurrentLineText:find(C.EnchantKey) then + CurrentLineText = CurrentLineText:match(C.EnchantKey) -- Get enchant string + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_AGILITY_SHORT, AGI) + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_SPIRIT_SHORT, SPI) + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_STAMINA_SHORT, STA) + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_STRENGTH_SHORT, STR) + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_INTELLECT_SHORT, INT) + CurrentLineText = gsub(CurrentLineText, ITEM_MOD_CRIT_RATING_SHORT, CRIT_ABBR) -- Critical is too long + CurrentLineText = gsub(CurrentLineText, ' + ', '+') -- Remove space + + Slot.Gradation.ItemEnchant:SetText('|cffceff00'..CurrentLineText) + + IsEnchanted = true + end + end + + --<< ItemLevel Parts >>-- + if BasicItemLevel then + ItemCount = ItemCount + 1 + + if ItemUpgradeID then + if ItemUpgradeID == '0' then + ItemUpgradeID = nil + else + ItemUpgradeID = TrueItemLevel - BasicItemLevel + end + end + + ItemTotal = ItemTotal + TrueItemLevel + + Slot.ItemLevel:SetText((ItemUpgradeID and (C.UpgradeColor[ItemUpgradeID] or '|cffffffff') or '')..TrueItemLevel) + Slot.Gradation.ItemLevel:SetText((Slot.Direction == 'LEFT' and TrueItemLevel or '')..(ItemUpgradeID and (Slot.Direction == 'LEFT' and ' ' or '')..(C.UpgradeColor[ItemUpgradeID] or '|cffaaaaaa')..'(+'..ItemUpgradeID..')|r'..(Slot.Direction == 'RIGHT' and ' ' or '') or '')..(Slot.Direction == 'RIGHT' and TrueItemLevel or '')) + end + + -- Check Error + if (not IsEnchanted and C.EnchantableSlots[slotName]) or ((slotName == 'Finger0Slot' or slotName == 'Finger1Slot') and (DataTable.Profession[1].Name == GetSpellInfo(110400) and DataTable.Profession[1].Level >= 550 or DataTable.Profession[2].Name == GetSpellInfo(110400) and DataTable.Profession[2].Level >= 550) and not IsEnchanted) then + ErrorDetected = true + Slot.EnchantWarning:Show() + Slot.Gradation.ItemEnchant:SetText('|cffff0000'..L['Not Enchanted']) + elseif slotName == 'ShoulderSlot' and C.ItemEnchant_Profession_Inscription and (DataTable.Profession[1].Name == GetSpellInfo(110417) and DataTable.Profession[1].Level >= C.ItemEnchant_Profession_Inscription.NeedLevel or DataTable.Profession[2].Name == GetSpellInfo(110417) and DataTable.Profession[2].Level >= C.ItemEnchant_Profession_Inscription.NeedLevel) and not C.ItemEnchant_Profession_Inscription[enchantID] then + ErrorDetected = true + Slot.EnchantWarning:Show() + Slot.EnchantWarning.Message = '|cff71d5ff'..GetSpellInfo(110400)..'|r : '..L['This is not profession only.'] + elseif slotName == 'WristSlot' and C.ItemEnchant_Profession_LeatherWorking and (DataTable.Profession[1].Name == GetSpellInfo(110423) and DataTable.Profession[1].Level >= C.ItemEnchant_Profession_LeatherWorking.NeedLevel or DataTable.Profession[2].Name == GetSpellInfo(110423) and DataTable.Profession[2].Level >= C.ItemEnchant_Profession_LeatherWorking.NeedLevel) and not C.ItemEnchant_Profession_LeatherWorking[enchantID] then + ErrorDetected = true + Slot.EnchantWarning:Show() + Slot.EnchantWarning.Message = '|cff71d5ff'..GetSpellInfo(110423)..'|r : '..L['This is not profession only.'] + elseif slotName == 'BackSlot' and C.ItemEnchant_Profession_Tailoring and (DataTable.Profession[1].Name == GetSpellInfo(110426) and DataTable.Profession[1].Level >= C.ItemEnchant_Profession_Tailoring.NeedLevel or DataTable.Profession[2].Name == GetSpellInfo(110426) and DataTable.Profession[2].Level >= C.ItemEnchant_Profession_Tailoring.NeedLevel) and not C.ItemEnchant_Profession_Tailoring[enchantID] then + ErrorDetected = true + Slot.EnchantWarning:Show() + Slot.EnchantWarning.Message = '|cff71d5ff'..GetSpellInfo(110426)..'|r : '..L['This is not profession only.'] + end + + if GemCount_Enable > GemCount_Now or GemCount_Enable > GemCount or GemCount_Now > GemCount then + ErrorDetected = true + + Slot.SocketWarning:Show() + + if GemCount_Enable > GemCount_Now then + if slotName == 'WaistSlot' then + if TrueItemLevel < 300 then + _, Slot.SocketWarning.Link = GetItemInfo(41611) + elseif TrueItemLevel < 417 then + _, Slot.SocketWarning.Link = GetItemInfo(55054) + else + _, Slot.SocketWarning.Link = GetItemInfo(90046) + end + + Slot.SocketWarning.Message = L['Missing Buckle'] + + Slot.SocketWarning:SetScript('OnClick', function(self) + local itemName, itemLink + + if TrueItemLevel < 300 then + itemName, itemLink = GetItemInfo(41611) + elseif TrueItemLevel < 417 then + itemName, itemLink = GetItemInfo(55054) + else + itemName, itemLink = GetItemInfo(90046) + end + + if HandleModifiedItemClick(itemLink) then + elseif IsShiftKeyDown() and BrowseName and BrowseName:IsVisible() then + AuctionFrameBrowse_Reset(BrowseResetButton) + BrowseName:SetText(itemName) + BrowseName:SetFocus() + end + end) + elseif slotName == 'HandsSlot' then + Slot.SocketWarning.Link = GetSpellLink(114112) + Slot.SocketWarning.Message = '|cff71d5ff'..GetSpellInfo(110396)..'|r : '..L['Missing Socket'] + elseif slotName == 'WristSlot' then + Slot.SocketWarning.Link = GetSpellLink(113263) + Slot.SocketWarning.Message = '|cff71d5ff'..GetSpellInfo(110396)..'|r : '..L['Missing Socket'] + end + else + Slot.SocketWarning.Message = '|cffff5678'..(GemCount_Now - GemCount)..'|r '..L['Empty Socket'] + end + end + end + + if Slot.TransmogrifyAnchor then --<< Transmogrify Parts >>-- + Slot.TransmogrifyAnchor.Link = DataTable.Gear[slotName].Transmogrify ~= 'NotDisplayed' and DataTable.Gear[slotName].Transmogrify + + if type(Slot.TransmogrifyAnchor.Link) == 'number' then + Slot.TransmogrifyAnchor:Show() + else + Slot.TransmogrifyAnchor:Hide() + end + end + + -- Change Gradation + if ErrorDetected then + if Slot.Direction == 'LEFT' then + Slot.Gradation.Texture:SetTexCoord(0, .5, .5, 1) + else + Slot.Gradation.Texture:SetTexCoord(.5, 1, .5, 1) + end + else + if Slot.Direction == 'LEFT' then + Slot.Gradation.Texture:SetTexCoord(0, .5, 0, .5) + else + Slot.Gradation.Texture:SetTexCoord(.5, 1, 0, .5) + end + end + + Slot.Texture:SetTexture(ItemTexture or Slot.EmptyTexture) + Slot:SetBackdropBorderColor(r, g, b) + + if needUpdate then + needUpdateList = needUpdateList or {} + needUpdateList[#needUpdateList + 1] = slotName + end + end + end + + for _, slotName in pairs({ 'ShirtSlot', 'TabardSlot' }) do + Slot = self[slotName] + ItemRarity, ItemTexture, r, g, b = nil, nil, 0, 0, 0 + + Slot.Link = DataTable.Gear[slotName].ItemLink + + if Slot.Link then + _, _, ItemRarity, _, _, _, _, _, _, ItemTexture = GetItemInfo(Slot.Link) + r, g, b = GetItemQualityColor(ItemRarity) + end + + Slot.Texture:SetTexture(ItemTexture or self[slotName].EmptyTexture) + Slot:SetBackdropBorderColor(r, g, b) + end + + self.SetItem = E:CopyTable({}, SLI.CurrentInspectData.SetItem) + self.Character.AverageItemLevel:SetText('|c'..RAID_CLASS_COLORS[DataTable.Class].colorStr..STAT_AVERAGE_ITEM_LEVEL..'|r: '..format('%.2f', ItemTotal / ItemCount)) + end + + if needUpdate then + self.GearUpdated = needUpdate + + return true + end + self.GearUpdated = nil + + r, g, b = RAID_CLASS_COLORS[DataTable.Class].r, RAID_CLASS_COLORS[DataTable.Class].g, RAID_CLASS_COLORS[DataTable.Class].b + + do --<< Basic Information >>-- + local iTitle = string.find(DataTable.Title, DataTable.Name) + if iTitle == 1 then + self.Title:SetText('') + self.TitleR:SetText('|cff93daff'..(DataTable.Title and string.gsub(DataTable.Title, DataTable.Name, '') or '')) + else + self.Title:SetText('|cff93daff'..(DataTable.Title and string.gsub(DataTable.Title, DataTable.Name, '') or '')) + self.TitleR:SetText('') + end + --self.Title:SetText((DataTable.Realm and DataTable.Realm ~= E.myrealm and DataTable.Realm..L[" Server "] or '')..'|cff93daff'..(DataTable.Title and string.gsub(DataTable.Title, DataTable.Name, '') or '')) + self.Guild:SetText(DataTable.guildName and '<|cff2eb7e4'..DataTable.guildName..'|r> [|cff2eb7e4'..DataTable.guildRankName..'|r]' or '') + --self.Realm:SetText((DataTable.Realm and DataTable.Realm ~= E.myrealm and L["Server: "]..DataTable.Realm or '')) + end + + do --<< Information Page Setting >>-- + do -- Profession + for i = 1, 2 do + if DataTable.Profession[i].Name then + self.Info.Profession:Show() + self.Info.Profession['Prof'..i].Bar:SetValue(DataTable.Profession[i].Level) + + if C.ProfessionList[DataTable.Profession[i].Name] then + self.Info.Profession['Prof'..i].Name:SetText('|cff77c0ff'..DataTable.Profession[i].Name) + self.Info.Profession['Prof'..i].Icon:SetTexture(C.ProfessionList[DataTable.Profession[i].Name].Texture) + self.Info.Profession['Prof'..i].Level:SetText(DataTable.Profession[i].Level) + else + self.Info.Profession['Prof'..i].Name:SetText('|cff808080'..DataTable.Profession[i].Name) + self.Info.Profession['Prof'..i].Icon:SetTexture('Interface\\ICONS\\INV_Misc_QuestionMark') + self.Info.Profession['Prof'..i].Level:SetText(nil) + end + else + self.Info.Profession:Hide() + break + end + end + end + + do -- Guild + if DataTable.guildName and DataTable.guildLevel and DataTable.guildNumMembers then + self.Info.Guild:Show() + self.Info.Guild.Banner.Name:SetText('|cff2eb7e4'..DataTable.guildName) + self.Info.Guild.Banner.LevelMembers:SetText('|cff77c0ff'..DataTable.guildLevel..'|r '..LEVEL..(DataTable.guildNumMembers > 0 and ' / '..format(INSPECT_GUILD_NUM_MEMBERS:gsub('%%d', '%%s'), '|cff77c0ff'..DataTable.guildNumMembers..'|r ') or '')) + SetSmallGuildTabardTextures('player', self.Info.Guild.Emblem, self.Info.Guild.BG, self.Info.Guild.Border, DataTable.guildEmblem) + else + self.Info.Guild:Hide() + end + end + + SLI:ReArrangeCategory() + end + + do --<< Specialization Page Setting >>-- + local SpecGroup, Name, Color, Texture, SpecRole + + if DataTable.Specialization.ActiveSpec then + SpecGroup = DataTable.Specialization.ActiveSpec + + for i = 2, MAX_TALENT_GROUPS do + self.Spec['Spec'..i]:Show() + end + else + SpecGroup = 1 + + for i = 2, MAX_TALENT_GROUPS do + self.Spec['Spec'..i]:Hide() + end + end + + self.SpecIcon:SetTexture('Interface\\ICONS\\INV_Misc_QuestionMark') + for i = 1, MAX_TALENT_GROUPS do + Color = '|cff808080' + + Name = nil + + if DataTable.Specialization[i].SpecializationID and DataTable.Specialization[i].SpecializationID ~= 0 then + _, Name, _, Texture = GetSpecializationInfoByID(DataTable.Specialization[i].SpecializationID) + + if Name then + if C.ClassRole[DataTable.Class][Name] then + + SpecRole = C.ClassRole[DataTable.Class][Name].Role + + if i == SpecGroup then + Color = C.ClassRole[DataTable.Class][Name].Color + self.SpecIcon:SetTexture(Texture) + end + + Name = (SpecRole == 'Tank' and '|TInterface\\AddOns\\ElvUI\\media\\textures\\tank.tga:16:16:-3:0|t' or SpecRole == 'Healer' and '|TInterface\\AddOns\\ElvUI\\media\\textures\\healer.tga:16:16:-3:-1|t' or '|TInterface\\AddOns\\ElvUI\\media\\textures\\dps.tga:16:16:-2:-1|t')..Name + else + self.Spec.Message = L['Specialization data seems to be corrupt. Please inspect again.'] + end + end + end + + if not Name then + Texture, SpecRole = 'Interface\\ICONS\\INV_Misc_QuestionMark.blp', nil + Name = '|cff808080'..L['No Specialization'] + end + + self.Spec['Spec'..i].Tab.text:SetText(Color..Name) + self.Spec['Spec'..i].Texture:SetTexture(Texture) + self.Spec['Spec'..i].Texture:SetDesaturated(i ~= SpecGroup) + end + + -- Talents + for i = 1, NUM_TALENT_COLUMNS * MAX_NUM_TALENT_TIERS do + Name, Texture = GetTalentInfo(i, true, nil, nil, DataTable.ClassID) + + self.Spec['Talent'..i].Icon.Texture:SetTexture(Texture) + self.Spec['Talent'..i].text:SetText(Name) + self.Spec['Talent'..i].Tooltip.Link = GetTalentLink(i, true, DataTable.ClassID) + end + end + + do --<< Model and Frame Setting When InspectUnit Changed >>-- + if DataTable.UnitID and UnitIsVisible(DataTable.UnitID) and SLI.NeedModelSetting then + self.Model:SetUnit(DataTable.UnitID) + --self.Character.Message = nil + --self.Character.Message = 'This is a test string. When contained string is too long then string will scrolling. If you check this scrolling ingame then erase this string part and make a nil. Like this : "self.Character.Message = nil". Congratulation your birthday Trevor :D' + elseif SLI.NeedModelSetting then + self.Model:SetUnit('player') + self.Model:SetCustomRace(self.ModelList[DataTable.RaceID].RaceID, DataTable.GenderID - 2) + self.Model:TryOn(HeadSlotItem) + self.Model:TryOn(BackSlotItem) + self.Model:Undress() + + for _, slotName in pairs(C.GearList) do + if type(DataTable.Gear[slotName].Transmogrify) == 'number' then + self.Model:TryOn(DataTable.Gear[slotName].Transmogrify) + elseif DataTable.Gear[slotName].ItemLink and not (DataTable.Gear[slotName].Transmogrify and DataTable.Gear[slotName].Transmogrify == 'NotDisplayed') then + self.Model:TryOn(DataTable.Gear[slotName].ItemLink) + else + self.Model:UndressSlot(self[slotName].ID) + end + end + + self.Character.Message = L['Character model may differ because it was constructed by the inspect data.'] + end + SLI.NeedModelSetting = nil + + if not (self.LastDataSetting and self.LastDataSetting == DataTable.Name..(DataTable.Realm and '-'..DataTable.Realm or '')) then + --<< Initialize Inspect Page >>-- + self.Name:SetText('|c'..RAID_CLASS_COLORS[DataTable.Class].colorStr..DataTable.Name) + self.LevelRace:SetText(format('|cff%02x%02x%02x%s|r %s'..(DataTable.Realm and DataTable.Realm ~= E.myrealm and ' | '..L["Server: "]..DataTable.Realm or ''), GetQuestDifficultyColor(DataTable.Level).r * 255, GetQuestDifficultyColor(DataTable.Level).g * 255, GetQuestDifficultyColor(DataTable.Level).b * 255, DataTable.Level, DataTable.Race)) + self.ClassIcon:SetTexture('Interface\\ICONS\\ClassIcon_'..DataTable.Class..'.blp') + + self.Model:SetPosition(self.ModelList[DataTable.RaceID][DataTable.GenderID] and self.ModelList[DataTable.RaceID][DataTable.GenderID].z or 0, self.ModelList[DataTable.RaceID][DataTable.GenderID] and self.ModelList[DataTable.RaceID][DataTable.GenderID].x or 0, self.ModelList[DataTable.RaceID][DataTable.GenderID] and self.ModelList[DataTable.RaceID][DataTable.GenderID].y or 0) + self.Model:SetFacing(-5.67) + self.Model:SetPortraitZoom(1) + self.Model:SetPortraitZoom(0) + + self:ChangePage('CharacterButton') + + do --<< Color Setting >>-- + self.ClassIconSlot:SetBackdropBorderColor(r, g, b) + self.SpecIconSlot:SetBackdropBorderColor(r, g, b) + + self.Info.BG:SetBackdropBorderColor(r, g, b) + + self.Info.Profession.IconSlot:SetBackdropBorderColor(r, g, b) + self.Info.Profession.Tab:SetBackdropColor(r, g, b, .3) + self.Info.Profession.Tab:SetBackdropBorderColor(r, g, b) + self.Info.Profession.Prof1.Bar:SetStatusBarColor(r, g, b) + self.Info.Profession.Prof2.Bar:SetStatusBarColor(r, g, b) + + self.Info.Guild.IconSlot:SetBackdropBorderColor(r, g, b) + self.Info.Guild.Tab:SetBackdropColor(r, g, b, .3) + self.Info.Guild.Tab:SetBackdropBorderColor(r, g, b) + + self.Info.PvP.IconSlot:SetBackdropBorderColor(r, g, b) + self.Info.PvP.Tab:SetBackdropColor(r, g, b, .3) + self.Info.PvP.Tab:SetBackdropBorderColor(r, g, b) + end + + self:ToggleSpecializationTab(DataTable.Specialization.ActiveSpec or 1, DataTable) + elseif not (self.LastActiveSpec and self.LastActiveSpec == (DataTable.Specialization.ActiveSpec or 1)) then + self:ToggleSpecializationTab(DataTable.Specialization.ActiveSpec or 1, DataTable) + end + end + + self.LastDataSetting = DataTable.Name..(DataTable.Realm and '-'..DataTable.Realm or '') +end + + +function SLI:InspectFrame_PvPSetting(DataTable) + local Rating, Played, Won + local needExpand = 0 + + for _, Type in pairs({ '2vs2', '3vs3', '5vs5', 'RB' }) do + if DataTable.PvP[Type] and DataTable.PvP[Type][2] > 0 then + Rating = DataTable.PvP[Type][1] or 0 + Played = DataTable.PvP[Type][2] or 0 + Won = DataTable.PvP[Type][3] or 0 + + if Rating >= 2000 then + Rating = '|cffffe65a'..Rating + self.Info.PvP[Type].Rank:Show() + self.Info.PvP[Type].Rank:SetTexCoord(0, .5, 0, .5) + self.Info.PvP[Type].Rank:SetBlendMode('ADD') + self.Info.PvP[Type].Rank:SetVertexColor(1, 1, 1) + self.Info.PvP[Type].RankGlow:Show() + self.Info.PvP[Type].RankGlow:SetTexCoord(0, .5, 0, .5) + self.Info.PvP[Type].RankNoLeaf:Hide() + elseif Rating >= 1750 then + self.Info.PvP[Type].Rank:Show() + self.Info.PvP[Type].Rank:SetTexCoord(.5, 1, 0, .5) + self.Info.PvP[Type].Rank:SetBlendMode('ADD') + self.Info.PvP[Type].Rank:SetVertexColor(1, 1, 1) + self.Info.PvP[Type].RankGlow:Show() + self.Info.PvP[Type].RankGlow:SetTexCoord(.5, 1, 0, .5) + self.Info.PvP[Type].RankNoLeaf:Hide() + elseif Rating >= 1550 then + Rating = '|cffc17611'..Rating + self.Info.PvP[Type].Rank:Show() + self.Info.PvP[Type].Rank:SetTexCoord(0, .5, 0, .5) + self.Info.PvP[Type].Rank:SetBlendMode('BLEND') + self.Info.PvP[Type].Rank:SetVertexColor(.6, .5, 0) + self.Info.PvP[Type].RankGlow:Hide() + self.Info.PvP[Type].RankNoLeaf:Hide() + else + Rating = '|cff2eb7e4'..Rating + self.Info.PvP[Type].Rank:Hide() + self.Info.PvP[Type].RankGlow:Hide() + self.Info.PvP[Type].RankNoLeaf:Show() + end + needExpand = needExpand < 106 and 106 or needExpand + + self.Info.PvP[Type].Rating:SetText(Rating) + self.Info.PvP[Type].Record:SetText('|cff77c0ff'..Won..'|r / |cffB24C4C'..(Played - Won)) + else + needExpand = needExpand < 88 and 88 or needExpand + + self.Info.PvP[Type].Rank:Hide() + self.Info.PvP[Type].RankGlow:Hide() + self.Info.PvP[Type].RankNoLeaf:Hide() + + self.Info.PvP[Type].Rating:SetText('|cff8080800') + self.Info.PvP[Type].Record:SetText(nil) + end + end + + self.Info.PvP.CategoryHeight = needExpand > 0 and needExpand or INFO_TAB_SIZE + SPACING * 2 + self:ReArrangeCategory() +end + + +function SLI:ReArrangeCategory() + local InfoPage_Height = 0 + local PrevCategory + + for _, CategoryType in pairs(self.InfoPageCategoryList) do + if self.Info[CategoryType]:IsShown() then + if self.Info[CategoryType].Closed then + self.Info[CategoryType].Page:Hide() + InfoPage_Height = InfoPage_Height + INFO_TAB_SIZE + SPACING * 2 + self.Info[CategoryType]:Height(INFO_TAB_SIZE + SPACING * 2) + else + self.Info[CategoryType].Page:Show() + InfoPage_Height = InfoPage_Height + self.Info[CategoryType].CategoryHeight + self.Info[CategoryType]:Height(self.Info[CategoryType].CategoryHeight) + end + + if PrevCategory then + InfoPage_Height = InfoPage_Height + SPACING * 2 + self.Info[CategoryType]:Point('TOP', PrevCategory, 'BOTTOM', 0, -SPACING * 2) + else + self.Info[CategoryType]:Point('TOP', self.Info.Page) + end + + PrevCategory = self.Info[CategoryType] + end + end + + self.Info.Page:Height(InfoPage_Height) + self.ScrollFrame_OnMouseWheel(self.Info, 0) +end + + +function SLI:ToggleSpecializationTab(Group, DataTable) + local r, g, b + self.LastActiveSpec = DataTable.Specialization.ActiveSpec or 1 + + for i = 1, MAX_TALENT_GROUPS do + if i == Group then + self.Spec['Spec'..i].BottomLeftBorder:Show() + self.Spec['Spec'..i].BottomRightBorder:Show() + self.Spec['Spec'..i].Tab:SetFrameLevel(CORE_FRAME_LEVEL + 3) + self.Spec['Spec'..i].Tab.text:Point('BOTTOMRIGHT', 0, -10) + else + self.Spec['Spec'..i].BottomLeftBorder:Hide() + self.Spec['Spec'..i].BottomRightBorder:Hide() + self.Spec['Spec'..i].Tab:SetFrameLevel(CORE_FRAME_LEVEL + 2) + self.Spec['Spec'..i].Tab.text:Point('BOTTOMRIGHT', 0, 0) + end + end + + if Group == self.LastActiveSpec then + r, g, b = RAID_CLASS_COLORS[DataTable.Class].r, RAID_CLASS_COLORS[DataTable.Class].g, RAID_CLASS_COLORS[DataTable.Class].b + else + r, g, b = .4, .4, .4 + end + + self.Spec.BottomBorder:SetTexture(r, g, b) + self.Spec.LeftBorder:SetTexture(r, g, b) + self.Spec.RightBorder:SetTexture(r, g, b) + + local LevelTable = CLASS_TALENT_LEVELS[DataTable.Class] or CLASS_TALENT_LEVELS.DEFAULT + for i = 1, MAX_NUM_TALENT_TIERS do + for k = 1, NUM_TALENT_COLUMNS do + if DataTable.Specialization[Group]['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)] then + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)]:SetBackdropColor(r, g, b, .3) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)]:SetBackdropBorderColor(r, g, b) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon:SetBackdropBorderColor(r, g, b) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon.Texture:SetDesaturated(0) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].text:SetTextColor(1, 1, 1) + else + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)]:SetBackdropColor(.1, .1, .1) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)]:SetBackdropBorderColor(0, 0, 0) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon:SetBackdropBorderColor(0, 0, 0) + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].Icon.Texture:SetDesaturated(1) + + if DataTable.Level < LevelTable[i] then + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].text:SetTextColor(.7, .3, .3) + else + self.Spec['Talent'..((i - 1) * NUM_TALENT_COLUMNS + k)].text:SetTextColor(.5, .5, .5) + end + end + end + end + + local Name, Texture + for i = 1, NUM_GLYPH_SLOTS do + Name, _, Texture = GetSpellInfo(DataTable.Glyph[Group]['Glyph'..i..'SpellID']) + + self.Spec['Glyph'..i].text:SetJustifyH('LEFT') + self.Spec['Glyph'..i].text:SetText(Name) + self.Spec['Glyph'..i].Icon.Texture:SetTexture(Texture) + self.Spec['Glyph'..i].Tooltip.Link = DataTable.Glyph[Group]['Glyph'..i..'ID'] ~= 0 and GetGlyphLinkByID(DataTable.Glyph[Group]['Glyph'..i..'ID']) + + if DataTable.Glyph[Group]['Glyph'..i..'SpellID'] ~= 0 then + self.Spec['Glyph'..i]:SetBackdropColor(r, g, b, .3) + self.Spec['Glyph'..i]:SetBackdropBorderColor(r, g, b) + self.Spec['Glyph'..i].Icon:SetBackdropBorderColor(r, g, b) + else + self.Spec['Glyph'..i]:SetBackdropColor(.1, .1, .1) + self.Spec['Glyph'..i]:SetBackdropBorderColor(0, 0, 0) + self.Spec['Glyph'..i].Icon:SetBackdropBorderColor(0, 0, 0) + + if self.Spec['Glyph'..i].NeedLevel > DataTable.Level then + self.Spec['Glyph'..i].text:SetJustifyH('CENTER') + self.Spec['Glyph'..i].text:SetText(E:RGBToHex(.7, .3, .3)..self.Spec['Glyph'..i].NeedLevel..' '..LEVEL) + end + end + end + + for i = 1, MAX_TALENT_GROUPS do + if i == self.LastActiveSpec then + r, g, b = RAID_CLASS_COLORS[DataTable.Class].r, RAID_CLASS_COLORS[DataTable.Class].g, RAID_CLASS_COLORS[DataTable.Class].b + else + r, g, b = .3, .3, .3 + end + + self.Spec['Spec'..i].TopBorder:SetTexture(r, g, b) + self.Spec['Spec'..i].LeftBorder:SetTexture(r, g, b) + self.Spec['Spec'..i].RightBorder:SetTexture(r, g, b) + self.Spec['Spec'..i].BottomLeftBorder:SetTexture(r, g, b) + self.Spec['Spec'..i].BottomRightBorder:SetTexture(r, g, b) + self.Spec['Spec'..i].Icon:SetBackdropBorderColor(r, g, b) + end +end + +function IFO:Initialize() + if not E.private.sle.inspectframeoptions.enable then return end + + Default_NotifyInspect = _G['NotifyInspect'] + Default_InspectUnit = _G['InspectUnit'] + + if SLI.CreateInspectFrame then + SLI:CreateInspectFrame() + end + + --_G['NotifyInspect'] = ENI.NotifyInspect or _G['NotifyInspect'] + NotifyInspect = ENI.NotifyInspect or NotifyInspect + InspectUnit = SLI.InspectUnit + --_G['InspectUnit'] = SLI.InspectUnit + + --[[ + tinsert(UnitPopupMenus.FRIEND, 5, 'KnightInspect') + tinsert(UnitPopupMenus.GUILD, 5, 'KnightInspect') + tinsert(UnitPopupMenus.RAID, 12, 'KnightInspect') + tinsert(UnitPopupMenus.FOCUS, 5, 'KnightInspect') + for _, GroupType in pairs({ 'PLAYER', 'PARTY', 'RAID_PLAYER' }) do + for Index, MenuType in pairs(UnitPopupMenus[GroupType]) do + if MenuType == 'INSPECT' then + UnitPopupMenus[GroupType][Index] = 'KnightInspect' + break + end + end + end + ]] + + SLI.Activate = true +end +-- E:RegisterModule(IFO:GetName()) \ No newline at end of file diff --git a/ElvUI_SLE/modules/characterframe/load_characterframe.xml b/ElvUI_SLE/modules/characterframe/load_characterframe.xml new file mode 100644 index 0000000..8cf435e --- /dev/null +++ b/ElvUI_SLE/modules/characterframe/load_characterframe.xml @@ -0,0 +1,19 @@ +<Ui xmlns="http://www.blizzard.com/wow/ui/"> + <Script file='core.lua'/> + <Script file='communication.lua'/> + <Script file='notifyinspect.lua'/> + <Script file='characterframe.lua'/> + <Script file='inspectframe.lua'/> + <Button name="KnightInspect_UnitPopup" hidden="true" toplevel="true"> + <ButtonText> + <Anchors> + <Anchor point="LEFT"> + <Offset x="0" y="0"/> + </Anchor> + </Anchors> + </ButtonText> + <NormalFont style="GameFontHighlightSmallLeft"/> + <HighlightFont style="GameFontHighlightSmallLeft"/> + <DisabledFont style="GameFontDisableSmallLeft"/> + </Button> +</Ui> \ No newline at end of file diff --git a/ElvUI_SLE/modules/characterframe/notifyinspect.lua b/ElvUI_SLE/modules/characterframe/notifyinspect.lua new file mode 100644 index 0000000..0d801c4 --- /dev/null +++ b/ElvUI_SLE/modules/characterframe/notifyinspect.lua @@ -0,0 +1,138 @@ +local type, tinsert = type, tinsert +local ENI = _G['EnhancedNotifyInspectFrame'] +local CurrentFileRevision = 1.0 + +if not ENI then + ENI = CreateFrame('Frame', 'EnhancedNotifyInspectFrame', UIParent) + ENI.UpdatedTime = 0 + ENI.InspectList = {} + ENI:SetScript('OnEvent', function(self, Event, ...) + if self[Event] then + self[Event](...) + end + end) + ENI:Hide() +end + +if not (ENI.Revision and ENI.Revision >= CurrentFileRevision) then + ENI.Revision = CurrentFileRevision + ENI.UpdateInterval = 1 + + local BlizzardNotifyInspect = _G['NotifyInspect'] + local playerRealm = GetRealmName() + + local UnitID + ENI.TryInspect = function() + for i = 1, #ENI.InspectList do + if ENI.InspectList[(ENI.InspectList[i])] then + UnitID = ENI.InspectList[(ENI.InspectList[i])].UnitID + + if UnitID and UnitIsConnected(UnitID) and CanInspect(UnitID) then + ENI.CurrentInspectUnitGUID = UnitGUID(UnitID) + + BlizzardNotifyInspect(UnitID) + + if ENI.InspectList[(ENI.InspectList[i])].CancelInspectByManual then + RequestInspectHonorData() + end + else + ENI.CancelInspect(ENI.InspectList[i]) + end + return + end + end + + ENI.UpdatedTime = 0 + ENI:Hide() + end + + ENI.NotifyInspect = function(Unit, InspectFirst) + if Unit ~= 'target' and UnitIsUnit(Unit, 'target') then + Unit = 'target' + end + + if Unit ~= 'focus' and UnitIsUnit(Unit, 'focus') then + Unit = 'focus' + end + + if UnitInParty(Unit) or UnitInRaid(Unit) then + Unit = GetUnitName(Unit, true) + end + + if UnitIsPlayer(Unit) and CanInspect(Unit) then + local TableIndex = GetUnitName(Unit, true) + + if not ENI.InspectList[TableIndex] then + if InspectFirst then + tinsert(ENI.InspectList, 1, TableIndex) + else + tinsert(ENI.InspectList, TableIndex) + end + + ENI.InspectList[TableIndex] = { + ['UnitID'] = Unit, + ['CancelInspectByManual'] = InspectFirst, + } + ENI:Show() + elseif InspectFirst and ENI.InspectList[TableIndex] then + ENI.CancelInspect(TableIndex) + ENI.NotifyInspect(Unit, InspectFirst) + end + end + + return Unit + end + + ENI.CancelInspect = function(Unit) + if ENI.InspectList[Unit] then + local Index + + for i = 1, #ENI.InspectList do + if ENI.InspectList[i] == Unit then + Index = i + break + end + end + + tremove(ENI.InspectList, Index) + ENI.InspectList[Unit] = nil + end + end + + ENI.INSPECT_READY = function(InspectedUnitGUID) + if InspectedUnitGUID == ENI.CurrentInspectUnitGUID then + local Name, Realm + + _, _, _, _, _, Name, Realm = GetPlayerInfoByGUID(InspectedUnitGUID) + Name = Name..(Realm and Realm ~= '' and Realm ~= playerRealm and '-'..Realm or '') + + if ENI.InspectList[Name] then + if ENI.InspectList[Name].CancelInspectByManual then + return + end + + ENI.CancelInspect(Name) + ENI.UpdatedTime = 0 + end + + ENI.CurrentInspectUnitGUID = nil + else + ENI.TryInspect() + ENI.UpdatedTime = -ENI.UpdateInterval + end + end + ENI:RegisterEvent('INSPECT_READY') + + ENI.Updater = function(_, elapsed) + ENI.UpdatedTime = ENI.UpdatedTime + elapsed + + if ENI.UpdatedTime < 0 then + return + else + ENI.UpdatedTime = -ENI.UpdateInterval + end + + ENI.TryInspect() + end + ENI:SetScript('OnUpdate', ENI.Updater) +end \ No newline at end of file diff --git a/ElvUI_SLE/modules/marks/flares.lua b/ElvUI_SLE/modules/marks/flares.lua new file mode 100644 index 0000000..0e7edf0 --- /dev/null +++ b/ElvUI_SLE/modules/marks/flares.lua @@ -0,0 +1,196 @@ +local E, L, V, P, G, _ = unpack(ElvUI); +local RF = E:GetModule('SLE_RaidFlares'); +-- local RF = E:NewModule('SLE_RaidFlares', 'AceHook-3.0', 'AceEvent-3.0'); +local template = "SecureActionButtonTemplate" + +BINDING_HEADER_SHADOWLIGHT_WORLDMARKER = "|cff1784d1Shadow & Light|r" +_G["BINDING_NAME_CLICK SquareFlareMarker:LeftButton"] = L["Square Flare"]; +_G["BINDING_NAME_CLICK TriangleFlareMarker:LeftButton"] = L["Triangle Flare"]; +_G["BINDING_NAME_CLICK DiamondFlareMarker:LeftButton"] = L["Diamond Flare"]; +_G["BINDING_NAME_CLICK CrossFlareMarker:LeftButton"] = L["Cross Flare"]; +_G["BINDING_NAME_CLICK StarFlareMarker:LeftButton"] = L["Star Flare"]; + +local mainFlares, f1, f2, f3, f4, f5, f6, FlareB + +function RF:CreateFrame() + mainFlares = CreateFrame("Frame", "Main_Flares", E.UIParent) + mainFlares:Point("CENTER", E.UIParent, "CENTER", 0, 40); + mainFlares:SetFrameStrata('LOW'); + mainFlares:CreateBackdrop(); + mainFlares.backdrop:SetAllPoints(); + mainFlares:Hide(); + + f1 = CreateFrame("Button", "SquareFlareMarker", Main_Flares, template) + f2 = CreateFrame("Button", "TriangleFlareMarker", Main_Flares, template) + f3 = CreateFrame("Button", "DiamondFlareMarker", Main_Flares, template) + f4 = CreateFrame("Button", "CrossFlareMarker", Main_Flares, template) + f5 = CreateFrame("Button", "StarFlareMarker", Main_Flares, template) + f6 = CreateFrame("Button", "ClearFlaresMarker", Main_Flares, template) + + FlareB = {f1,f2,f3,f4,f5,f6} +end + +function RF:SetupButton(button, flare) + if not mainFlares then return end + button:CreateBackdrop() + button.backdrop:SetAllPoints() + button:SetAttribute("type", "macro") + button:SetAttribute("macrotext", flare) + button:RegisterForClicks("AnyDown") + + button.tex = button:CreateTexture(nil, 'OVERLAY') + button.tex:Point('TOPLEFT', button, 'TOPLEFT', 2, -2) + button.tex:Point('BOTTOMRIGHT', button, 'BOTTOMRIGHT', -2, 2) + if button == f1 then + button.tex:SetTexture("INTERFACE/TARGETINGFRAME/UI-RaidTargetingIcon_6") + button:SetScript("OnEnter", function(self) if (E.db.sle.flares.tooltips==true) then GameTooltip:SetOwner(self, "ANCHOR_CURSOR"); GameTooltip:ClearLines(); GameTooltip:AddLine(L["Square World Marker"]); GameTooltip:Show() end end) + button:SetScript("OnLeave", function(self) GameTooltip:Hide() end) + elseif button == f2 then + button.tex:SetTexture("INTERFACE/TARGETINGFRAME/UI-RaidTargetingIcon_4") + button:SetScript("OnEnter", function(self) if (E.db.sle.flares.tooltips==true) then GameTooltip:SetOwner(self, "ANCHOR_CURSOR"); GameTooltip:ClearLines(); GameTooltip:AddLine(L["Triangle World Marker"]); GameTooltip:Show() end end) + button:SetScript("OnLeave", function(self) GameTooltip:Hide() end) + elseif button == f3 then + button.tex:SetTexture("INTERFACE/TARGETINGFRAME/UI-RaidTargetingIcon_3") + button:SetScript("OnEnter", function(self) if (E.db.sle.flares.tooltips==true) then GameTooltip:SetOwner(self, "ANCHOR_CURSOR"); GameTooltip:ClearLines(); GameTooltip:AddLine(L["Diamond World Marker"]); GameTooltip:Show() end end) + button:SetScript("OnLeave", function(self) GameTooltip:Hide() end) + elseif button == f4 then + button.tex:SetTexture("INTERFACE/TARGETINGFRAME/UI-RaidTargetingIcon_7") + button:SetScript("OnEnter", function(self) if (E.db.sle.flares.tooltips==true) then GameTooltip:SetOwner(self, "ANCHOR_CURSOR"); GameTooltip:ClearLines(); GameTooltip:AddLine(L["Cross World Marker"]); GameTooltip:Show() end end) + button:SetScript("OnLeave", function(self) GameTooltip:Hide() end) + elseif button == f5 then + button.tex:SetTexture("INTERFACE/TARGETINGFRAME/UI-RaidTargetingIcon_1") + button:SetScript("OnEnter", function(self) if (E.db.sle.flares.tooltips==true) then GameTooltip:SetOwner(self, "ANCHOR_CURSOR"); GameTooltip:ClearLines(); GameTooltip:AddLine(L["Star World Marker"]); GameTooltip:Show() end end) + button:SetScript("OnLeave", function(self) GameTooltip:Hide() end) + elseif button == f6 then + button.tex:SetTexture("Interface\\AddOns\\ElvUI_SLE\\media\\textures\\clearmarker.blp") + button:SetScript("OnEnter", function(self) if (E.db.sle.flares.tooltips==true) then GameTooltip:SetOwner(self, "ANCHOR_CURSOR"); GameTooltip:ClearLines(); GameTooltip:AddLine(L["Clear World Markers"]); GameTooltip:Show() end end) + button:SetScript("OnLeave", function(self) GameTooltip:Hide() end) + end +end + +function RF:CreateButtons() + if not mainFlares then return end + RF:SetupButton(f1, "/clearworldmarker 1\n/worldmarker 1") + RF:SetupButton(f2, "/clearworldmarker 2\n/worldmarker 2") + RF:SetupButton(f3, "/clearworldmarker 3\n/worldmarker 3") + RF:SetupButton(f4, "/clearworldmarker 4\n/worldmarker 4") + RF:SetupButton(f5, "/clearworldmarker 5\n/worldmarker 5") + RF:SetupButton(f6, "/clearworldmarker all") +end + +function RF:FrameButtonsSize() + if not mainFlares then return end + for i = 1, 6 do + FlareB[i]:Size(E.db.sle.flares.size) + end +end + +function RF:FrameButtonsGrowth() + if not mainFlares then return end + local db = E.db.sle.flares + local size = db.size + local width, height, x, y, anchor, point + local t = {6*size+9,size+4,"LEFT","RIGHT","TOP","BOTTOM",1,0,-1} + for i = 1, 6 do + FlareB[i]:ClearAllPoints() + end + + if db.growth == "RIGHT" then + width, height, anchor, point, _, _, x, y = unpack(t) + elseif db.growth == "LEFT" then + width, height, point, anchor, _, _, _, y, x = unpack(t) + elseif db.growth == "UP" then + height, width, _, _, point, anchor, y, x = unpack(t) + elseif db.growth == "DOWN" then + height, width, _, _, anchor, point, _, x, y = unpack(t) + end + + mainFlares:SetWidth(width) + mainFlares:SetHeight(height) + + for i = 1, 6 do + if i == 1 then + FlareB[i]:Point(anchor, Main_Flares, anchor, 2 * x, 2 * y) + else + FlareB[i]:Point(anchor, FlareB[i-1], point, x, y) + end + end +end + +function RF:UpdateVisibility() + if not mainFlares then return end + local inInstance, instanceType = IsInInstance() + local db = E.db.sle.flares + local show = false + + if (inInstance and instanceType ~= "pvp") and db.showinside then + show = true + elseif not inInstance and db.showinside then + show = false + elseif not db.showinside then + show = true + end + + if show then + E.FrameLocks['Main_Flares'] = true + mainFlares:Show() + for i = 1, 6 do + FlareB[i]:Show() + end + else + E.FrameLocks['Main_Flares'] = nil + mainFlares:Hide() + for i = 1, 6 do + FlareB[i]:Hide() + end + end + RF:Mouseover() +end + +function RF:Backdrop() + if not mainFlares then return end + if E.db.sle.flares.backdrop then + mainFlares.backdrop:Show() + else + mainFlares.backdrop:Hide() + end +end + +function RF:Mouseover() + if not mainFlares then return end + local db = E.db.sle.flares + if db.mouseover then + mainFlares:SetScript("OnUpdate", function(self) + if MouseIsOver(self) then + UIFrameFadeIn(self, 0.2, self:GetAlpha(), 1) + else + UIFrameFadeOut(self, 0.2, self:GetAlpha(), 0) + end + end) + else + mainFlares:SetScript("OnUpdate", nil) + if mainFlares:IsShown() then + UIFrameFadeIn(mainFlares, 0.2, mainFlares:GetAlpha(), 1) + end + end +end + +function RF:Update() + if not mainFlares then return end + RF:FrameButtonsSize() + RF:FrameButtonsGrowth() + RF:UpdateVisibility() + RF:Backdrop() +end + +function RF:Initialize() + if not E.private.sle.marks.flares then return end + RF:CreateFrame() + RF:Update() + RF:CreateButtons() + self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdateVisibility"); + + E:CreateMover(mainFlares, "FlareMover", "RF", nil, nil, nil, "ALL,S&L,S&L MISC") +end + +-- E:RegisterModule(RF:GetName()) \ No newline at end of file diff --git a/ElvUI_SLE/modules/marks/load_marks.xml b/ElvUI_SLE/modules/marks/load_marks.xml new file mode 100644 index 0000000..248f4e3 --- /dev/null +++ b/ElvUI_SLE/modules/marks/load_marks.xml @@ -0,0 +1,5 @@ +<Ui xmlns="http://www.blizzard.com/wow/ui/"> + <Script file='flares.lua'/> + <Script file='marks.lua'/> + <Script file='options.lua'/> +</Ui> \ No newline at end of file diff --git a/ElvUI_SLE/modules/marks/marks.lua b/ElvUI_SLE/modules/marks/marks.lua new file mode 100644 index 0000000..f2316ee --- /dev/null +++ b/ElvUI_SLE/modules/marks/marks.lua @@ -0,0 +1,194 @@ +--Raid mark bar. Similar to quickmark which just semms to be impossible to skin +local E, L, V, P, G, _ = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB, Localize Underscore +-- local RM = E:NewModule('SLE_RaidMarks', 'AceHook-3.0', 'AceEvent-3.0'); +local RM = E:GetModule('SLE_RaidMarks') +local Mtemplate = "SecureActionButtonTemplate" +local IsInInstance = IsInInstance +local UnitExists = UnitExists +local mark_menu, m1, m2, m3, m4, m5, m6, m7, m8, MarkB +local UIFrameFadeIn = UIFrameFadeIn +local UIFrameFadeOut = UIFrameFadeOut + +--Main frame +function RM:CreateFrame() + mark_menu = CreateFrame("Frame", "Mark_Menu", E.UIParent) + mark_menu:Point("BOTTOMRIGHT", RightChatTab, "TOPRIGHT", 2, 3) --Default positon + mark_menu:SetFrameStrata('LOW'); + mark_menu:CreateBackdrop(); + mark_menu.backdrop:SetAllPoints(); + + m1 = CreateFrame("Button", "M1", Mark_Menu, Mtemplate) + m2 = CreateFrame("Button", "M2", Mark_Menu, Mtemplate) + m3 = CreateFrame("Button", "M3", Mark_Menu, Mtemplate) + m4 = CreateFrame("Button", "M4", Mark_Menu, Mtemplate) + m5 = CreateFrame("Button", "M5", Mark_Menu, Mtemplate) + m6 = CreateFrame("Button", "M6", Mark_Menu, Mtemplate) + m7 = CreateFrame("Button", "M7", Mark_Menu, Mtemplate) + m8 = CreateFrame("Button", "M8", Mark_Menu, Mtemplate) + + MarkB = {m1,m2,m3,m4,m5,m6,m7,m8} + + mark_menu:Hide() +end + +function RM:SetupButton(button, mark) + button:CreateBackdrop() + button.backdrop:SetAllPoints() + button:SetAttribute("type", "macro") + button:SetAttribute("macrotext", '/script SetRaidTargetIcon("target",'..mark..')') + + button.tex = button:CreateTexture(nil, 'OVERLAY') + button.tex:Point('TOPLEFT', button, 'TOPLEFT', 2, -2) + button.tex:Point('BOTTOMRIGHT', button, 'BOTTOMRIGHT', -2, 2) + button.tex:SetTexture("INTERFACE/TARGETINGFRAME/UI-RaidTargetingIcon_"..mark) +end + +--Buttons creation +function RM:CreateButtons() + if not mark_menu then return end + for i = 1, 8 do + RM:SetupButton(MarkB[i], 9 - i) + end +end + +--Setting/updating buttons' size +function RM:FrameButtonsSize() + if not mark_menu then return end + for i = 1, 8 do + MarkB[i]:Size(E.db.sle.marks.size) + end +end + +--Setting growth direction for buttons +function RM:FrameButtonsGrowth() + if not mark_menu then return end + local db = E.db.sle.marks + local size = db.size + local width, height, x, y, anchor, point + local t = {8*size+11,size+4,"LEFT","RIGHT","TOP","BOTTOM",1,0,-1} + for i = 1, 8 do + MarkB[i]:ClearAllPoints() + end + + if db.growth == "RIGHT" then + width, height, anchor, point, _, _, x, y = unpack(t) + elseif db.growth == "LEFT" then + width, height, point, anchor, _, _, _, y, x = unpack(t) + elseif db.growth == "UP" then + height, width, _, _, point, anchor, y, x = unpack(t) + elseif db.growth == "DOWN" then + height, width, _, _, anchor, point, _, x, y = unpack(t) + end + + mark_menu:SetWidth(width) + mark_menu:SetHeight(height) + + for i = 1, 8 do + if i == 1 then + MarkB[i]:Point(anchor, Mark_Menu, anchor, 2 * x, 2 * y) + else + MarkB[i]:Point(anchor, MarkB[i-1], point, x, y) + end + end +end + +--Visibility/enable check +function RM:UpdateVisibility() + if not mark_menu then return end + local inInstance, instanceType = IsInInstance() + local db = E.db.sle.marks + local show = false + if (inInstance and instanceType ~= "pvp") and db.showinside then + if db.target and UnitExists("target") then + show = true + elseif db.target and not UnitExists("target") then + show = false + else + show = true + end + elseif not inInstance and db.showinside then + show = false + elseif not db.showinside then + if db.target and UnitExists("target") then + show = true + elseif db.target and not UnitExists("target") then + show = false + else + show = true + end + end + + if show then + E.FrameLocks['Mark_Menu'] = true + mark_menu:Show() + for i = 1, 8 do + MarkB[i]:Show() + end + else + E.FrameLocks['Mark_Menu'] = nil + mark_menu:Hide() + for i = 1, 8 do + MarkB[i]:Hide() + end + end + RM:Mouseover() +end + +function RM:Target() + if not mark_menu then return end + local db = E.db.sle.marks + if db.target then + self:RegisterEvent("PLAYER_TARGET_CHANGED", "UpdateVisibility"); + else + self:UnregisterEvent("PLAYER_TARGET_CHANGED"); + end +end + +function RM:Backdrop() + if not mark_menu then return end + if E.db.sle.marks.backdrop then + mark_menu.backdrop:Show() + else + mark_menu.backdrop:Hide() + end +end + +function RM:Mouseover() + if not mark_menu then return end + local db = E.db.sle.marks + if db.mouseover then + mark_menu:SetScript("OnUpdate", function(self) + if MouseIsOver(self) then + UIFrameFadeIn(self, 0.2, self:GetAlpha(), 1) + else + UIFrameFadeOut(self, 0.2, self:GetAlpha(), 0) + end + end) + else + mark_menu:SetScript("OnUpdate", nil) + if mark_menu:IsShown() then + UIFrameFadeIn(mark_menu, 0.2, mark_menu:GetAlpha(), 1) + end + end +end + +function RM:Update() + if not mark_menu then return end + RM:FrameButtonsSize() + RM:FrameButtonsGrowth() + RM:Target() + RM:UpdateVisibility() + RM:Backdrop() +end + +function RM:Initialize() + if not E.private.sle.marks.marks then return end + RM:CreateFrame() + RM:Update() + RM:CreateButtons() + self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdateVisibility"); + + E:CreateMover(mark_menu, "MarkMover", "RM", nil, nil, nil, "ALL,S&L,S&L MISC") +end + +-- E:RegisterModule(RM:GetName()) \ No newline at end of file diff --git a/ElvUI_SLE/modules/minimap/load_minimap.xml b/ElvUI_SLE/modules/minimap/load_minimap.xml new file mode 100644 index 0000000..a1cd949 --- /dev/null +++ b/ElvUI_SLE/modules/minimap/load_minimap.xml @@ -0,0 +1,5 @@ +<Ui xmlns="http://www.blizzard.com/wow/ui/"> + <Script file='minimapcoords.lua'/> + <Script file='minimapicons.lua'/> + <Script file='options.lua'/> +</Ui> \ No newline at end of file diff --git a/ElvUI_SLE/modules/minimap/minimapcoords.lua b/ElvUI_SLE/modules/minimap/minimapcoords.lua new file mode 100644 index 0000000..fa94a4a --- /dev/null +++ b/ElvUI_SLE/modules/minimap/minimapcoords.lua @@ -0,0 +1,87 @@ +local E, L, V, P, G, _ = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB, Localize Underscore +local M = E:GetModule('Minimap') + +local GetPlayerMapPosition = GetPlayerMapPosition +local framescreated = false +local panel, xpos, ypos +local middle + +local function UpdateCoords(self, elapsed) + panel.elapsed = (panel.elapsed or 0) + elapsed + if panel.elapsed < .1 then return end + + xpos.pos, ypos.pos = GetPlayerMapPosition('player') + xpos.text:SetFormattedText(E.db.sle.minimap.coords.middle == "CENTER" and '%.2f/' or '%.2f', xpos.pos * 100) + ypos.text:SetFormattedText('%.2f', ypos.pos * 100) + + panel.elapsed = 0 +end + +local function UpdatePosition(middle) + xpos:ClearAllPoints() + ypos:ClearAllPoints() + if middle == "CENTER" then + xpos:Point('BOTTOMRIGHT', panel, 'BOTTOM',10, 0) + else + xpos:Point('LEFT', panel, 'LEFT', 2, 0) + end + if middle == "CENTER" then + ypos:Point('BOTTOMLEFT', panel, 'BOTTOM', 0, 0) + else + ypos:Point('RIGHT', panel, 'RIGHT', 2, 0) + end +end + +local function CreateCoordsFrame(middle) + panel = CreateFrame('Frame', 'CoordsPanel', E.UIParent) + panel:SetFrameStrata("MEDIUM") + panel:Point("CENTER", Minimap, "CENTER", 0, 0) + panel:Size(E.MinimapSize, 22) + E.FrameLocks['CoordsPanel'] = true; + + xpos = CreateFrame('Frame', "MapCoordinatesX", panel) + xpos:Size(40, 22) + + xpos.text = xpos:CreateFontString(nil, "OVERLAY") + xpos.text:FontTemplate(E.media.font, 12, "OUTLINE") + xpos.text:SetAllPoints(xpos) + + ypos = CreateFrame('Frame', "MapCoordinatesY", panel) + ypos:Size(40, 22) + + ypos.text = ypos:CreateFontString(nil, "OVERLAY") + ypos.text:FontTemplate(E.media.font, 12, "OUTLINE") + ypos.text:SetAllPoints(ypos) + Minimap:HookScript('OnEnter', function(self) + if E.db.sle.minimap.coords.display ~= 'MOUSEOVER' or not E.private.general.minimap.enable or not E.db.sle.minimap.enable then return; end + panel:Show() + end) + + Minimap:HookScript('OnLeave', function(self) + if E.db.sle.minimap.coords.display ~= 'MOUSEOVER' or not E.private.general.minimap.enable or not E.db.sle.minimap.enable then return; end + panel:Hide() + end) + framescreated = true + + UpdatePosition(middle) +end + +M.UpdateSettingsSLE = M.UpdateSettings +function M:UpdateSettings() + M.UpdateSettingsSLE(self) + middle = E.db.sle.minimap.coords.middle + + if not framescreated then + CreateCoordsFrame(middle) + end + + panel:SetPoint('BOTTOM', Minimap, 'BOTTOM', 0, -(E.PixelMode and 1 or 2)) + panel:Size(E.MinimapSize, 22) + panel:SetScript('OnUpdate', UpdateCoords) + UpdatePosition(middle) + if E.db.sle.minimap.coords.display ~= 'SHOW' or not E.private.general.minimap.enable or not E.db.sle.minimap.enable then + panel:Hide() + else + panel:Show() + end +end \ No newline at end of file diff --git a/ElvUI_SLE/modules/minimap/minimapicons.lua b/ElvUI_SLE/modules/minimap/minimapicons.lua new file mode 100644 index 0000000..e6105c5 --- /dev/null +++ b/ElvUI_SLE/modules/minimap/minimapicons.lua @@ -0,0 +1,355 @@ +local E, L, V, P, G, _ = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB, Localize Underscore +-- local SMB = E:NewModule('SLE_SquareMinimapButtons', 'AceHook-3.0', 'AceEvent-3.0'); +local SMB = E:GetModule('SLE_SquareMinimapButtons'); + + +local AddOnName, NS = ... +local strsub, strlen, strfind, ceil = strsub, strlen, strfind, ceil +local tinsert, pairs, unpack = tinsert, pairs, unpack + +local SkinnedMinimapButtons = {} +local BorderColor = E['media'].bordercolor +local TexCoords = { 0.1, 0.9, 0.1, 0.9 } +local SquareMinimapButtonBar + +if E.private.sle == nil then E.private.sle = {} end +if E.private.sle.minimap == nil then E.private.sle.minimap = {} end +if E.private.sle.minimap.mapicons == nil then E.private.sle.minimap.mapicons = {} end +if E.private.sle.minimap.mapicons.enable == nil then E.private.sle.minimap.mapicons.enable = false end +if E.private.sle.minimap.mapicons.barenable == nil then E.private.sle.minimap.mapicons.barenable = false end + +if E.db.sle.minimap == nil then E.db.sle.minimap = {} end +if E.db.sle.minimap.mapicons == nil then E.db.sle.minimap.mapicons = {} end +if E.db.sle.minimap.mapicons.iconmouseover == nil then E.db.sle.minimap.mapicons.iconmouseover = false end +if E.db.sle.minimap.mapicons.iconsize == nil then E.db.sle.minimap.mapicons.iconsize = 27 end +if E.db.sle.minimap.mapicons.iconperrow == nil then E.db.sle.minimap.mapicons.iconperrow = 12 end +if E.db.sle.minimap.mapicons.skindungeon == nil then E.db.sle.minimap.mapicons.skindungeon = false end +if E.db.sle.minimap.mapicons.skinmail == nil then E.db.sle.minimap.mapicons.skinmail = false end + +QueueStatusMinimapButton:SetParent(Minimap) + +local function OnEnter(self) + UIFrameFadeIn(SquareMinimapButtonBar, 0.2, SquareMinimapButtonBar:GetAlpha(), 1) + if self:GetName() ~= 'SquareMinimapButtonBar' then + self:SetBackdropBorderColor(.7, 0, .7) + end +end + +local function OnLeave(self) + if E.db.sle.minimap.mapicons.iconmouseover then + UIFrameFadeOut(SquareMinimapButtonBar, 0.2, SquareMinimapButtonBar:GetAlpha(), 0) + end + if self:GetName() ~= 'SquareMinimapButtonBar' then + self:SetBackdropBorderColor(unpack(BorderColor)) + end +end + +function SMB:ChangeMouseOverSetting() + if E.db.sle.minimap.mapicons.iconmouseover then + SquareMinimapButtonBar:SetAlpha(0) + else + SquareMinimapButtonBar:SetAlpha(1) + end +end + +local ignoreButtons = { + 'ElvConfigToggle', + 'GameTimeFrame', + 'HelpOpenTicketButton', + 'MiniMapTrackingButton', + 'MiniMapVoiceChatFrame', + 'TimeManagerClockButton', +} + +local GenericIgnores = { + 'Archy', + 'GatherMatePin', + 'GatherNote', + 'GuildInstance', + 'HandyNotesPin', + 'MinimMap', + 'poiMinimap', + 'Spy_MapNoteList_mini', + 'ZGVMarker', +} + +local PartialIgnores = { + 'Node', + 'Note', + 'Pin', + 'POI', +} + +local WhiteList = { + 'LibDBIcon', +} + +local AcceptedFrames = { + 'BagSync_MinimapButton', + 'VendomaticButtonFrame', + 'MiniMapMailFrame', +} + +local AddButtonsToBar = { + 'SmartBuff_MiniMapButton', + 'QueueStatusMinimapButton', + 'MiniMapMailFrame', +} + +local function SkinButton(Button) + if not Button.isSkinned then + local Name = Button:GetName() + + if Button:IsObjectType('Button') then + local ValidIcon = false + + for i = 1, #WhiteList do + if strsub(Name, 1, strlen(WhiteList[i])) == WhiteList[i] then ValidIcon = true break end + end + + if not ValidIcon then + for i = 1, #ignoreButtons do + if Name == ignoreButtons[i] then return end + end + + for i = 1, #GenericIgnores do + if strsub(Name, 1, strlen(GenericIgnores[i])) == GenericIgnores[i] then return end + end + + for i = 1, #PartialIgnores do + if strfind(Name, PartialIgnores[i]) ~= nil then return end + end + end + + Button:SetPushedTexture(nil) + Button:SetHighlightTexture(nil) + Button:SetDisabledTexture(nil) + end + + for i = 1, Button:GetNumRegions() do + local Region = select(i, Button:GetRegions()) + if Region:GetObjectType() == 'Texture' then + local Texture = Region:GetTexture() + + if Texture and (strfind(Texture, 'Border') or strfind(Texture, 'Background') or strfind(Texture, 'AlphaMask')) then + Region:SetTexture(nil) + else + if Name == 'BagSync_MinimapButton' then Region:SetTexture('Interface\\AddOns\\BagSync\\media\\icon') end + if Name == 'DBMMinimapButton' then Region:SetTexture('Interface\\Icons\\INV_Helmet_87') end + if Name == 'SmartBuff_MiniMapButton' then Region:SetTexture(select(3, GetSpellInfo(12051))) end + if Name == 'MiniMapMailFrame' then + Region:ClearAllPoints() + Region:SetPoint('CENTER', Button) + end + if not (Name == 'MiniMapMailFrame' or Name == 'SmartBuff_MiniMapButton') then + Region:ClearAllPoints() + Region:SetInside() + Region:SetTexCoord(unpack(TexCoords)) + Button:HookScript('OnLeave', function(self) Region:SetTexCoord(unpack(TexCoords)) end) + end + Region:SetDrawLayer('ARTWORK') + Region.SetPoint = function() return end + end + end + end + + Button:SetFrameLevel(Minimap:GetFrameLevel() + 5) + Button:Size(E.db.sle.minimap.mapicons.iconsize) + + if Name == 'SmartBuff_MiniMapButton' then + Button:SetNormalTexture("Interface\\Icons\\Spell_Nature_Purge") + Button:GetNormalTexture():SetTexCoord(unpack(TexCoords)) + Button.SetNormalTexture = function() end + Button:SetDisabledTexture("Interface\\Icons\\Spell_Nature_Purge") + Button:GetDisabledTexture():SetTexCoord(unpack(TexCoords)) + elseif Name == 'VendomaticButtonFrame' then + VendomaticButton:StripTextures() + VendomaticButton:SetInside() + VendomaticButtonIcon:SetTexture('Interface\\Icons\\INV_Misc_Rabbit_2') + VendomaticButtonIcon:SetTexCoord(unpack(TexCoords)) + end + + if Name == 'QueueStatusMinimapButton' then + QueueStatusMinimapButton:HookScript('OnUpdate', function(self) + QueueStatusMinimapButtonIcon:SetFrameLevel(QueueStatusMinimapButton:GetFrameLevel() + 1) + end) + local Frame = CreateFrame('Frame', QueueDummyFrame, SquareMinimapButtonBar) + Frame:SetTemplate() + Frame.Icon = Frame:CreateTexture(nil, 'ARTWORK') + Frame.Icon:SetInside() + Frame.Icon:SetTexture([[Interface\LFGFrame\LFG-Eye]]) + Frame.Icon:SetTexCoord(0, 64 / 512, 0, 64 / 256) + Frame:SetScript('OnMouseDown', function() + if PVEFrame:IsShown() then + HideUIPanel(PVEFrame) + else + ShowUIPanel(PVEFrame) + GroupFinderFrame_ShowGroupFrame() + end + end) + SquareMinimapButtonBar:HookScript('OnUpdate', function() + if E.db.sle.minimap.mapicons.skindungeon then + Frame:Show() + else + Frame:Hide() + end + end) + QueueStatusMinimapButton:HookScript('OnShow', function() + if E.db.sle.minimap.mapicons.skindungeon then + Frame:Show() + else + Frame:Hide() + end + end) + Frame:HookScript('OnEnter', OnEnter) + Frame:HookScript('OnLeave', OnLeave) + Frame:SetScript('OnUpdate', function(self) + if QueueStatusMinimapButton:IsShown() then + self:EnableMouse(false) + else + self:EnableMouse(true) + end + self:Size(E.db.sle.minimap.mapicons.iconsize) + self:SetFrameStrata(QueueStatusMinimapButton:GetFrameStrata()) + self:SetFrameLevel(QueueStatusMinimapButton:GetFrameLevel()) + self:SetPoint(QueueStatusMinimapButton:GetPoint()) + end) + elseif Name == 'MiniMapMailFrame' then + local Frame = CreateFrame('Frame', 'MailDummyFrame', SquareMinimapButtonBar) + Frame:Size(E.db.sle.minimap.mapicons.iconsize) + Frame:SetTemplate() + Frame.Icon = Frame:CreateTexture(nil, 'ARTWORK') + Frame.Icon:SetPoint('CENTER') + Frame.Icon:Size(18) + Frame.Icon:SetTexture(MiniMapMailIcon:GetTexture()) + Frame:SetScript('OnEnter', OnEnter) + Frame:SetScript('OnLeave', OnLeave) + Frame:SetScript('OnUpdate', function(self) + if E.db.sle.minimap.mapicons.skinmail then + Frame:Show() + Frame:SetPoint(MiniMapMailFrame:GetPoint()) + else + Frame:Hide() + end + end) + MiniMapMailFrame:HookScript('OnShow', function(self) + if E.db.sle.minimap.mapicons.skinmail then + MiniMapMailIcon:SetVertexColor(0, 1, 0) + end + end) + MiniMapMailFrame:HookScript('OnHide', function(self) MiniMapMailIcon:SetVertexColor(1, 1, 1) end) + else + Button:SetTemplate() + Button:SetBackdropColor(0, 0, 0, 0) + end + + Button.isSkinned = true + tinsert(SkinnedMinimapButtons, Button) + end +end + +local function SkinMinimapButtons() + for i = 1, Minimap:GetNumChildren() do + local object = select(i, Minimap:GetChildren()) + if object then + if object:IsObjectType('Button') and object:GetName() then + SkinButton(object) + end + for _, frame in pairs(AcceptedFrames) do + if object:IsObjectType('Frame') and object:GetName() == frame then + SkinButton(object) + end + end + end + end +end + +function SMB:Update() + if not E.private.sle.minimap.mapicons.barenable then return end + + OnLeave(SquareMinimapButtonBar) + local AnchorX, AnchorY, MaxX = 0, 1, E.db.sle.minimap.mapicons.iconperrow + local ButtonsPerRow = E.db.sle.minimap.mapicons.iconperrow + local NumColumns = ceil(#SkinnedMinimapButtons / ButtonsPerRow) + local Spacing, Mult = 4, 1 + local Size = E.db.sle.minimap.mapicons.iconsize + local ActualButtons, Maxed = 0 + + if NumColumns == 1 and ButtonsPerRow > #SkinnedMinimapButtons then + ButtonsPerRow = #SkinnedMinimapButtons + end + + for Key, Frame in pairs(SkinnedMinimapButtons) do + local Name = Frame:GetName() + local Exception = false + for _, Button in pairs(AddButtonsToBar) do + if Name == Button then + Exception = true + if Name == 'SmartBuff_MiniMapButton' then + SMARTBUFF_MinimapButton_CheckPos = function() end + SMARTBUFF_MinimapButton_OnUpdate = function() end + end + if not E.db.sle.minimap.mapicons.skindungeon and Name == 'QueueStatusMinimapButton' then + Exception = false + end + if (not E.db.sle.minimap.mapicons.skinmail and Name == 'MiniMapMailFrame') then + Exception = false + end + end + end + if Frame:IsVisible() and not (Name == 'QueueStatusMinimapButton' or Name == 'MiniMapMailFrame') or Exception then + AnchorX = AnchorX + 1 + ActualButtons = ActualButtons + 1 + if AnchorX > MaxX then + AnchorY = AnchorY + 1 + AnchorX = 1 + Maxed = true + end + local yOffset = - Spacing - ((Size + Spacing) * (AnchorY - 1)) + local xOffset = Spacing + ((Size + Spacing) * (AnchorX - 1)) + Frame:SetTemplate() + Frame:SetBackdropColor(0, 0, 0, 0) + Frame:SetParent(SquareMinimapButtonBar) + Frame:ClearAllPoints() + Frame:Point('TOPLEFT', SquareMinimapButtonBar, 'TOPLEFT', xOffset, yOffset) + Frame:SetSize(E.db.sle.minimap.mapicons.iconsize, E.db.sle.minimap.mapicons.iconsize) + Frame:SetFrameStrata('LOW') + Frame:SetFrameLevel(3) + Frame:SetScript('OnDragStart', function() end) + Frame:SetScript('OnDragStop', function() end) + Frame:HookScript('OnEnter', OnEnter) + Frame:HookScript('OnLeave', OnLeave) + if Maxed then ActualButtons = ButtonsPerRow end + + local BarWidth = (Spacing + ((Size * (ActualButtons * Mult)) + ((Spacing * (ActualButtons - 1)) * Mult) + (Spacing * Mult))) + local BarHeight = (Spacing + ((Size * (AnchorY * Mult)) + ((Spacing * (AnchorY - 1)) * Mult) + (Spacing * Mult))) + SquareMinimapButtonBar:SetSize(BarWidth, BarHeight) + E:CreateMover(SquareMinimapButtonBar, "SquareMinimapBar", "Square Minimap Bar", nil, nil, nil, "ALL,SOLO") + end + end + + SquareMinimapButtonBar:Show() +end + +function SMB:Initialize() + if not E.private.sle.minimap.mapicons.enable then return end + SquareMinimapButtonBar = CreateFrame('Frame', 'SquareMinimapButtonBar', E.UIParent) + SquareMinimapButtonBar:Hide() + SquareMinimapButtonBar:SetTemplate('Transparent', true) + SquareMinimapButtonBar:SetFrameStrata('LOW') + SquareMinimapButtonBar:SetFrameLevel(1) + SquareMinimapButtonBar:SetClampedToScreen(true) + SquareMinimapButtonBar:SetPoint('RIGHT', UIParent, 'RIGHT', -45, 0) + SquareMinimapButtonBar:SetScript('OnEnter', OnEnter) + SquareMinimapButtonBar:SetScript('OnLeave', OnLeave) + RegisterStateDriver(SquareMinimapButtonBar, 'visibility', '[petbattle] hide; show') + SkinMinimapButtons() + self:RegisterEvent('PLAYER_ENTERING_WORLD', 'Update') + self:RegisterEvent('ADDON_LOADED', SkinMinimapButtons) + E:Delay(5, function() + SkinMinimapButtons() + SMB:Update() + end) +end + +-- E:RegisterModule(SMB:GetName()) \ No newline at end of file