Nenue@62: -- Veneer Nenue@62: -- PaperDoll.lua Nenue@62: -- Created: 8/16/2016 8:18 AM Nenue@62: -- %file-revision% Nenue@80: -- Displays the item level and modifications of character sheet equipment, including artifact power Nenue@93: local print = DEVIAN_WORKSPACE and function(...) print('PaperDoll', ...) end or nop Nenue@96: local artifactSlot Nenue@93: local slot_overlays = {} Nenue@93: VeneerPaperDollMixin = { Nenue@93: anchorFrame = 'CharacterFrame', Nenue@93: anchorPoint = 'TOPLEFT', Nenue@93: KnownRelics = {}, Nenue@93: } Nenue@93: Nenue@93: local relic_slot_paths = { Nenue@93: Arcane = {"Relic-Arcane-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.849609375, 0.919921875, 0.1181640625, 0.1884765625, false, false}, Nenue@93: Blood = {"Relic-Blood-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.921875, 0.9921875, 0.1181640625, 0.1884765625, false, false}, Nenue@93: Fel = {"Relic-Fel-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.59765625, 0.66796875, 0.572265625, 0.642578125, false, false}, Nenue@93: Fire = {"Relic-Fire-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.669921875, 0.740234375, 0.572265625, 0.642578125, false, false}, Nenue@93: Frost = {"Relic-Frost-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.7421875, 0.8125, 0.572265625, 0.642578125, false, false}, Nenue@93: Holy = {"Relic-Holy-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.814453125, 0.884765625, 0.572265625, 0.642578125, false, false}, Nenue@93: Iron = {"Relic-Iron-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.88671875, 0.95703125, 0.572265625, 0.642578125, false, false}, Nenue@93: Life = {"Relic-Life-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.59765625, 0.66796875, 0.64453125, 0.71484375, false, false}, Nenue@93: Shadow = {"Relic-Shadow-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.59765625, 0.66796875, 0.716796875, 0.787109375, false, false}, Nenue@93: Water = {"Relic-Water-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.59765625, 0.66796875, 0.7890625, 0.859375, false, false}, Nenue@93: Wind = {"Relic-Wind-Slot", [[Interface\Artifacts\Artifacts.BLP]], 72, 72, 0.59765625, 0.66796875, 0.861328125, 0.931640625, false, false}, Nenue@93: } Nenue@93: Nenue@93: local slots_left = {'TOPLEFT', 'TOPRIGHT', 1, 0, 'TOPLEFT', 'BOTTOMLEFT', 0, -1} Nenue@93: local slots_right = {'TOPRIGHT', 'TOPLEFT', -1, 0, 'TOPRIGHT', 'BOTTOMRIGHT', 0, -1} Nenue@93: local slots_bottomleft = {'BOTTOMRIGHT', 'TOPRIGHT', 0, 1, 'BOTTOMRIGHT', 'TOPRIGHT', 0, 1 } Nenue@93: local slots_bottomright = {'BOTTOMLEFT', 'TOPLEFT', 0, -1, 'BOTTOMLEFT', 'TOPLEFT', 0, 1} Nenue@62: Nenue@64: local slot_anchors = { Nenue@93: [1] = slots_left, Nenue@93: [2] = slots_left, Nenue@93: [3] = slots_left, Nenue@93: [15] = slots_left, Nenue@93: [5] = slots_left, Nenue@93: [9] = slots_left, Nenue@62: Nenue@93: [10] = slots_right, Nenue@93: [6] = slots_right, Nenue@93: [7] = slots_right, Nenue@93: [8] = slots_right, Nenue@93: [11] = slots_right, Nenue@93: [12] = slots_right, Nenue@93: [13] = slots_right, Nenue@93: [14] = slots_right, Nenue@64: Nenue@93: [16] = slots_bottomleft, Nenue@93: [17] = slots_bottomright, Nenue@64: } Nenue@64: Nenue@64: Nenue@93: function VeneerPaperDollMixin:OnLoad() Nenue@93: hooksecurefunc("PaperDollItemSlotButton_Update", function(...) Nenue@93: self:GetSlotButton(PaperDollItemsFrame, ...) Nenue@93: end) Nenue@64: Nenue@93: hooksecurefunc("PaperDollFrame_UpdateStats", function(...) Nenue@93: self:GetStats(PaperDollItemsFrame, ...) Nenue@93: end) Nenue@64: Nenue@93: self:RegisterEvent('INSPECT_READY') Nenue@102: Veneer:AddHandler(self) Nenue@80: end Nenue@80: Nenue@93: function VeneerPaperDollMixin:SetupInspectFrame() Nenue@93: hooksecurefunc("InspectPaperDollItemSlotButton_Update", function(...) Nenue@93: self:GetSlotButton(InspectFrame, ...) Nenue@93: end) Nenue@93: self:RegisterEvent('INSPECT_READY') Nenue@93: end Nenue@93: function VeneerPaperDollMixin:SetupArtifactUI() Nenue@80: end Nenue@80: Nenue@93: function VeneerPaperDollMixin:Setup() Nenue@93: VeneerData.PaperDoll = VeneerData.PaperDoll or {} Nenue@93: VeneerData.PaperDoll.KnownRelics = VeneerData.PaperDoll.KnownRelics or {} Nenue@93: self.KnownRelics = VeneerData.PaperDoll.KnownRelics Nenue@80: Nenue@93: self:RegisterEvent('UNIT_INVENTORY_CHANGED') Nenue@93: self:RegisterEvent('PLAYER_EQUIPMENT_CHANGED') Nenue@93: self:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED') Nenue@116: self:RegisterEvent('ARTIFACT_RELIC_INFO_RECEIVED') Nenue@96: self:RegisterEvent('ARTIFACT_UPDATE') Nenue@80: Nenue@93: self:MarkForUpdate() Nenue@133: Nenue@133: Nenue@62: end Nenue@62: Nenue@93: function VeneerPaperDollMixin:MarkForUpdate() Nenue@93: for frame, overlays in pairs(slot_overlays) do Nenue@93: for slot, overlay in pairs(overlays) do Nenue@93: if overlay:IsVisible() then Nenue@93: overlay:Update() Nenue@93: else Nenue@93: overlay.isDirty = true Nenue@93: end Nenue@64: end Nenue@64: end Nenue@64: end Nenue@64: Nenue@93: function VeneerPaperDollMixin:GetStats() Nenue@93: end Nenue@93: function VeneerPaperDollMixin:GetSlotButton(panel, frame) Nenue@93: print('|cFF00FF88'..self:GetName()..':GetSlotButton()', frame:GetName(), frame:GetID()) Nenue@93: local slot = frame:GetID() Nenue@93: local unit = panel.unit or 'player' Nenue@93: if slot_anchors[slot] then Nenue@93: slot_overlays[panel] = slot_overlays[panel] or {} Nenue@93: local overlay = slot_overlays[panel][slot] Nenue@93: if not overlay then Nenue@96: print('creating slot overlay', slot) Nenue@93: overlay = CreateFrame('Frame', 'VeneerPaperDollSlot' .. unit .. slot, frame, 'VeneerPaperDollSlotInfoTemplate') Nenue@93: overlay:SetID(slot) Nenue@93: slot_overlays[panel][slot] = overlay Nenue@93: overlay.checkRelic = frame.checkRelic Nenue@71: Nenue@93: local anchorPoint, relativePoint, dX, dY, statPoint, statRelative, statdX, statdY = unpack(slot_anchors[slot]) Nenue@93: local offset = 7 Nenue@93: overlay:SetPoint(anchorPoint, frame, relativePoint, dX * offset, dY * offset) Nenue@93: overlay:SetSize(frame:GetWidth()*3, frame:GetHeight()) Nenue@93: Nenue@93: local relativeFrame = overlay Nenue@93: for i, region in ipairs(overlay.StatsLeft) do Nenue@93: region:ClearAllPoints() Nenue@93: print(statPoint, relativeFrame, (i == 1) and statPoint or statRelative) Nenue@93: region:SetPoint(statPoint, relativeFrame, (i == 1) and statPoint or statRelative, 0, 0) Nenue@93: relativeFrame = region Nenue@93: end Nenue@93: if slot == 16 then Nenue@93: overlay.Sockets:ClearAllPoints() Nenue@93: overlay.Sockets:SetPoint('BOTTOM', CharacterFrameInsetBg, 'BOTTOM', 0, frame:GetHeight() + 14) Nenue@93: overlay.ItemLevel:SetFontObject(VeneerNumberFontLarge) Nenue@93: overlay.ItemLevel:ClearAllPoints() Nenue@93: overlay.ItemLevel:SetPoint('BOTTOM', overlay.Sockets, 'TOP', 0, 4) Nenue@96: if unit == 'player' then Nenue@96: artifactSlot = overlay Nenue@96: end Nenue@96: Nenue@93: end Nenue@93: Nenue@93: print(overlay.Sockets:GetPoint(1)) Nenue@93: overlay.anchors = slot_anchors[slot] Nenue@93: end Nenue@93: Nenue@93: overlay.unit = unit Nenue@93: overlay.checkRelic = (unit == 'player' and slot == 16) Nenue@93: Nenue@93: Nenue@93: if frame.hasItem then Nenue@93: overlay.isDirty = true Nenue@93: overlay:Show() Nenue@93: else Nenue@93: overlay:Hide() Nenue@93: end Nenue@64: end Nenue@64: end Nenue@64: Nenue@93: function VeneerPaperDollMixin:OnEvent(event, arg) Nenue@93: print(event, arg) Nenue@93: if event == 'ADDON_LOADED' then Nenue@93: if arg == 'Blizzard_InspectUI' then Nenue@93: self:SetupInspectFrame() Nenue@93: end Nenue@93: if arg == 'Blizzard_ArtifactUI' then Nenue@93: self:SetupArtifactUI() Nenue@93: self:MarkForUpdate() Nenue@93: end Nenue@93: elseif event == 'ARTIFACT_UPDATE' then Nenue@133: self:ScoopRelics() Nenue@96: if artifactSlot then Nenue@133: artifactSlot.isDirty = true Nenue@116: end Nenue@116: elseif event == 'ARTIFACT_RELIC_INFO_RECEIVED' then Nenue@116: if artifactSlot then Nenue@133: artifactSlot.isDirty = true Nenue@96: end Nenue@93: else Nenue@93: if (event == 'PLAYER_SPECIALIZATION_CHANGED' or event == 'UNIT_INVENTORY_CHANGED') then Nenue@93: if arg ~= 'player' then Nenue@93: return Nenue@93: end Nenue@65: end Nenue@93: self:MarkForUpdate() Nenue@65: end Nenue@80: end Nenue@66: Nenue@64: Nenue@93: VeneerPaperDollSlotMixin = {} Nenue@66: Nenue@93: function VeneerPaperDollSlotMixin:OnLoad() Nenue@93: self.SocketText = {} Nenue@93: self.SocketType = {} Nenue@93: self.SocketLink = {} Nenue@133: self.SocketForge = {} Nenue@93: end Nenue@93: function VeneerPaperDollSlotMixin:OnShow() Nenue@93: if self.isDirty then Nenue@93: self:Update() Nenue@93: end Nenue@93: end Nenue@133: Nenue@133: function VeneerPaperDollSlotMixin:OnHide() Nenue@133: if GameTooltip:IsOwned(self) then Nenue@133: GameTooltip:Hide() Nenue@133: end Nenue@133: end Nenue@133: Nenue@93: function VeneerPaperDollSlotMixin:OnUpdate() Nenue@93: if self.isDirty then Nenue@93: --print('|cFF00FF00pushing update for', self:GetID()) Nenue@93: self:Update() Nenue@93: end Nenue@80: Nenue@93: if self.checkRelic then Nenue@133: local setTip Nenue@93: for i = 1, 3 do Nenue@133: if self.SocketType[i] and self.Sockets.SocketIcon[i]:IsMouseOver() then Nenue@133: setTip = self.SocketForge[i] Nenue@93: end Nenue@93: end Nenue@133: if setTip then Nenue@133: GameTooltip:SetOwner(self, 'ANCHOR_RIGHT') Nenue@133: for _, info in ipairs(setTip) do Nenue@133: if type(info) == 'table' then Nenue@133: GameTooltip:AddLine(unpack(info)) Nenue@133: elseif type(info) == 'string' then Nenue@133: GameTooltip:AddLine(info) Nenue@133: end Nenue@93: end Nenue@133: GameTooltip:Show() Nenue@133: elseif GameTooltip:IsOwned(self) then Nenue@133: GameTooltip:Hide() Nenue@93: end Nenue@93: end Nenue@93: end Nenue@93: Nenue@133: local tooltipName= 'VeneerPaperDollTooltip' Nenue@93: function VeneerPaperDollSlotMixin:UpdateRelicInfo() Nenue@93: Nenue@93: Nenue@93: local itemID = GetInventoryItemID(self.unit, 16) Nenue@93: if not itemID then Nenue@93: return Nenue@93: end Nenue@93: Nenue@133: print('|cFF00FFFFRelic Info:', itemID) Nenue@133: local guid = UnitGUID(self.unit or 'player') Nenue@133: local relicCache = VeneerPaperDoll.KnownRelics[guid] and VeneerPaperDoll.KnownRelics[guid][itemID] Nenue@93: Nenue@133: if not relicCache then Nenue@133: relicCache = {} Nenue@133: VeneerPaperDoll.KnownRelics[guid] = VeneerPaperDoll.KnownRelics[guid] or {} Nenue@133: VeneerPaperDoll.KnownRelics[guid][itemID] = relicCache Nenue@133: end Nenue@133: Nenue@133: for i = 1, 3 do Nenue@133: if relicCache[i] then Nenue@133: local relicIcon, relicLevel, relicType, relicLink, relicForge = unpack(relicCache[i]) Nenue@133: Nenue@133: print('reading', i, unpack(relicCache[i])) Nenue@133: self.SocketInfo[i] = relicIcon Nenue@133: self.SocketText[i] = relicLevel Nenue@133: self.SocketType[i] = relicType Nenue@133: self.SocketLink[i] = relicLink Nenue@133: self.SocketForge[i] = self.SocketForge[i] or {} Nenue@133: if relicForge then Nenue@133: for l, info in ipairs(relicForge) do Nenue@133: self.SocketForge[i][l] = info Nenue@133: end Nenue@133: end Nenue@133: Nenue@133: end Nenue@133: end Nenue@133: end Nenue@133: Nenue@133: function VeneerPaperDollMixin:ScoopRelics() Nenue@133: Nenue@133: -- not a viewed artifact Nenue@133: local itemID = C_ArtifactUI.GetArtifactInfo() Nenue@133: if not itemID then Nenue@133: return Nenue@133: end Nenue@133: Nenue@133: print('|cFFFF00FFScoopRelics:|r', itemID) Nenue@93: local guid = UnitGUID(self.unit or 'player') Nenue@93: local relicCache = VeneerPaperDoll.KnownRelics[guid] and VeneerPaperDoll.KnownRelics[guid][itemID] Nenue@93: if VeneerPaperDoll.KnownRelics[guid] then Nenue@93: for k, v in pairs(VeneerPaperDoll.KnownRelics[guid]) do Nenue@93: if tonumber(k) and tonumber(k) < 72 then Nenue@93: VeneerPaperDoll.KnownRelics[guid][k] = nil Nenue@93: end Nenue@93: end Nenue@93: end Nenue@93: Nenue@93: Nenue@93: if not relicCache then Nenue@93: relicCache = {} Nenue@93: VeneerPaperDoll.KnownRelics[guid] = VeneerPaperDoll.KnownRelics[guid] or {} Nenue@93: VeneerPaperDoll.KnownRelics[guid][itemID] = relicCache Nenue@93: end Nenue@93: Nenue@93: local numRelics = C_ArtifactUI.GetNumRelicSlots() Nenue@93: local isEquipped = C_ArtifactUI.IsViewedArtifactEquipped() Nenue@93: local tooltip = VeneerPaperDollTooltip Nenue@93: Nenue@133: for i = 1, numRelics do Nenue@135: relicCache[i] = relicCache[i] or {} Nenue@133: local relicName, relicIcon, relicType, relicLink = C_ArtifactUI.GetRelicInfo(i); Nenue@133: local relicLevel = relicCache[i][2] or "" Nenue@133: local relicForge = relicCache[i][5] or {} Nenue@133: local relicType = C_ArtifactUI.GetRelicSlotType(i); Nenue@133: Nenue@133: if relicType then Nenue@133: if relicLink then Nenue@133: tooltip:SetSocketedRelic(i) Nenue@133: print(tooltip:NumLines()) Nenue@133: Nenue@133: local numLines = tooltip:NumLines() Nenue@133: if numLines >= 1 then Nenue@133: wipe(relicForge) Nenue@133: local foundRank = 0 Nenue@133: for line = 1, numLines do Nenue@133: --print( _G[tooltipName .. 'TextLeft' .. line]:GetText(), _G[tooltipName .. 'TextLeft' .. line]:GetTextColor()) Nenue@133: local lineText = _G[tooltipName .. 'TextLeft' .. line]:GetText() Nenue@133: Nenue@133: if lineText then Nenue@133: local iLevel = lineText:match('Item Level (%d+)') Nenue@133: local rank = lineText:match('+1 Rank: (.+)') Nenue@133: Nenue@133: if iLevel then Nenue@133: relicLevel = iLevel Nenue@133: print('iLevel = ',iLevel) Nenue@133: end Nenue@133: Nenue@133: tinsert(relicForge, {lineText, _G[tooltipName .. 'TextLeft' .. line]:GetTextColor()}) Nenue@133: end Nenue@105: end Nenue@93: end Nenue@93: end Nenue@93: Nenue@133: print('storing', i, relicIcon, relicLevel, relicType, relicLink, relicForge) Nenue@93: Nenue@133: relicCache[i] = {relicIcon, relicLevel, relicType, relicLink, relicForge} Nenue@93: end Nenue@93: end Nenue@133: Nenue@133: Nenue@133: end Nenue@133: Nenue@133: function VeneerPaperDollSlotMixin:OnLeave() Nenue@133: Nenue@93: end Nenue@93: Nenue@96: function VeneerPaperDollSlotMixin:Update(forced) Nenue@93: local id = self:GetID() Nenue@93: Nenue@93: self.SocketInfo = self.SocketInfo or {} Nenue@93: table.wipe(self.SocketInfo) Nenue@93: self.ItemLevel:SetText(nil) Nenue@93: Nenue@93: local tooltip = VeneerPaperDollTooltip Nenue@93: tooltip:SetOwner(self, 'ANCHOR_NONE') Nenue@96: if forced then Nenue@96: print('refresh', self.unit, id) Nenue@96: end Nenue@96: Nenue@93: tooltip:SetInventoryItem(self.unit or 'player', id) Nenue@93: tooltip:Show() Nenue@93: Nenue@93: local numLines = tooltip:NumLines() Nenue@93: local numTextures = 0 Nenue@93: local itemLevel Nenue@131: local ignoreIL = IsAddOnLoaded("DejaCharacterStats") Nenue@93: local itemLevelLine Nenue@96: --print('|cFFFFFF00Sockets scan:', numLines) Nenue@133: for i = 1, numLines do Nenue@133: local line = _G['VeneerPaperDollTooltipTextLeft'..i] Nenue@133: local text = line and line:GetText() Nenue@133: if text and not ignoreIL then Nenue@133: itemLevel = text:match('Item Level (%d+)') Nenue@133: if itemLevel then Nenue@133: self.ItemLevel:SetText(itemLevel) Nenue@133: break Nenue@93: end Nenue@93: end Nenue@133: Nenue@133: local texture = _G['VeneerPaperDollTooltipTexture'..i] Nenue@133: if texture and texture:IsShown() then Nenue@133: numTextures = numTextures + 1 Nenue@133: --print('picked up socket', numTextures, texture:GetTexture()) Nenue@133: self.SocketInfo[numTextures] = texture:GetTexture() Nenue@133: end Nenue@133: end Nenue@133: Nenue@93: if self.checkRelic then Nenue@93: self:UpdateRelicInfo() Nenue@93: end Nenue@93: Nenue@93: Nenue@93: local relativeIcon Nenue@93: local socketsWidth = 0 Nenue@93: local socketsHeight = 24 Nenue@93: for index, icon in ipairs(self.Sockets.SocketIcon) do Nenue@93: if self.SocketInfo[index] then Nenue@116: print('|cFF0088FFsocketInfo|r', index, self.SocketType[index], self.SocketInfo[index]) Nenue@93: icon:ClearAllPoints() Nenue@93: Nenue@93: icon:SetTexture(self.SocketInfo[index]) Nenue@93: icon:SetSize(16, 16) Nenue@93: icon:Show() Nenue@93: if index == 1 then Nenue@93: icon:SetPoint('LEFT', self.Sockets, 'LEFT', 0, 0) Nenue@93: socketsWidth = socketsWidth + icon:GetWidth() Nenue@93: socketsHeight = icon:GetHeight() Nenue@93: else Nenue@93: if id == 16 then Nenue@93: icon:SetPoint('LEFT', relativeIcon, 'RIGHT', 14, 0) Nenue@93: socketsWidth = socketsWidth + 14 Nenue@93: else Nenue@93: icon:SetPoint('LEFT', relativeIcon, 'RIGHT', 2, 0) Nenue@93: socketsWidth = socketsWidth + 2 Nenue@93: end Nenue@93: socketsWidth = socketsWidth + icon:GetWidth() Nenue@93: end Nenue@96: print( '|cFFFF4400', icon:GetPoint(1)) Nenue@93: Nenue@93: local label = self.Sockets.SocketLabel[index] Nenue@93: label:ClearAllPoints() Nenue@93: label:SetPoint('BOTTOM', icon, 'TOP',0, 2) Nenue@93: label:SetFontObject(VeneerNumberFont) Nenue@93: label:SetText(self.SocketText[index]) Nenue@93: Nenue@105: if self.checkRelic and self.SocketType[index] then Nenue@105: print(self.SocketType[index]) Nenue@116: self.Sockets.SocketBg = self.Sockets.SocketBg or {} Nenue@116: self.Sockets.SocketBg[index] = self.Sockets.SocketBg[index] or self.Sockets:CreateTexture(nil, 'OVERLAY') Nenue@116: Nenue@116: Nenue@116: local relicBG = self.Sockets.SocketBg[index] Nenue@93: local relicAtlasName = ("Relic-%s-Slot"):format(self.SocketType[index]); Nenue@116: relicBG:SetMask(nil) Nenue@116: relicBG:SetAtlas(relicAtlasName) Nenue@116: relicBG:SetPoint('TOPRIGHT', icon, 'TOPRIGHT', 10, 10) Nenue@116: relicBG:SetPoint('BOTTOMLEFT', icon, 'BOTTOMLEFT', -10,-10) Nenue@96: --print('', self.SocketType[index], relicAtlasName) Nenue@105: if self.SocketInfo[index] == 0 then Nenue@105: icon:SetAtlas("Relic-SlotBG") Nenue@116: else Nenue@116: icon:SetMask(nil); Nenue@116: icon:SetTexCoord(0, 1, 0, 1); -- Masks may overwrite our tex coords (even ones set by an atlas), force it back to using the full item icon texture Nenue@116: icon:SetMask("Interface\\CharacterFrame\\TempPortraitAlphaMask"); Nenue@116: icon:SetTexture(self.SocketInfo[index]) Nenue@116: Nenue@105: end Nenue@93: Nenue@93: socketsHeight = self.Sockets.SocketBg[index]:GetHeight() Nenue@96: print(socketsWidth, socketsHeight) Nenue@93: end Nenue@93: Nenue@93: Nenue@93: relativeIcon = icon Nenue@93: else Nenue@93: if self.checkRelic and self.Sockets.SocketBg and self.Sockets.SocketBg[index] then Nenue@93: self.Sockets.SocketBg[index]:SetTexture(nil) Nenue@93: self.Sockets.SocketLabel[index]:SetText(nil) Nenue@93: end Nenue@93: Nenue@93: icon:Hide() Nenue@93: end Nenue@93: Nenue@93: Nenue@93: end Nenue@93: self.Sockets:SetWidth(socketsWidth) Nenue@93: self.Sockets:SetHeight(socketsHeight) Nenue@93: Nenue@93: Nenue@93: Nenue@93: Nenue@93: Nenue@93: self.isDirty = nil Nenue@93: end