annotate Modules/ArtifactPower.lua @ 97:5476337198ec

- apply default anchors when docking modules - Arifact Power tracker: totals AP items in bags and bank, and forecasts progress on each weapon. Requires user to shift-click each weapon at least once to get initial XP data.
author Nenue
date Mon, 16 Jan 2017 20:24:12 -0500
parents
children dadddb8a551f
rev   line source
Nenue@97 1 -- Veneer
Nenue@97 2 -- ArtifactPower.lua
Nenue@97 3 -- Created: 1/15/2017 11:44 PM
Nenue@97 4 -- %file-revision%
Nenue@97 5 --
Nenue@97 6
Nenue@97 7 local print = DEVIAN_WORKSPACE and function(...) print('VnAP', ...) end or nop
Nenue@97 8 VeneerArtifactPowerMixin = {
Nenue@97 9
Nenue@97 10 anchorPoint = 'TOP',
Nenue@97 11 anchorFrom = 'TOP',
Nenue@97 12 }
Nenue@97 13 local ap = VeneerArtifactPowerMixin
Nenue@97 14 local BAGS_TO_SCAN = {BACKPACK_CONTAINER }
Nenue@97 15 local TOOLTIP_NAME = 'VeneerAPScanner'
Nenue@97 16
Nenue@97 17 function ap:OnLoad()
Nenue@97 18 self:RegisterEvent('BAG_UPDATE') -- use to obtain bag IDs to scan
Nenue@97 19 self:RegisterEvent('BAG_UPDATE_DELAYED') -- use to trigger actual scan activity
Nenue@97 20 self:RegisterEvent('BANKFRAME_OPENED') -- determine when bank info is available
Nenue@97 21 self:RegisterEvent('BANKFRAME_CLOSED') -- " " "
Nenue@97 22 self:RegisterEvent('ARTIFACT_UPDATE') -- when artifact data has changed
Nenue@97 23 self:RegisterEvent('ARTIFACT_UPDATE_XP') -- when artifact xp has changed (but not necessarily data)
Nenue@97 24 self:RegisterEvent('MODIFIER_STATE_CHANGED')
Nenue@97 25 self:RegisterEvent('PLAYER_REGEN_ENABLED')
Nenue@97 26 self:RegisterEvent('PLAYER_REGEN_DISABLED')
Nenue@97 27 Veneer:AddHandler(self, self.anchorPoint, true)
Nenue@97 28 SLASH_VENEER_AP1 = "/vap"
Nenue@97 29 SLASH_VENEER_AP2 = "/veneerap"
Nenue@97 30 SlashCmdList.VENEER_AP = function()
Nenue@97 31 self:Show()
Nenue@97 32 end
Nenue@97 33
Nenue@97 34 self.tooltip = CreateFrame('GameTooltip', TOOLTIP_NAME, self, 'GameTooltipTemplate')
Nenue@97 35
Nenue@97 36 end
Nenue@97 37
Nenue@97 38 local defaultSettings = {
Nenue@97 39 }
Nenue@97 40
Nenue@97 41 function ap:Setup()
Nenue@97 42 print(self:GetName()..':Setup()')
Nenue@97 43 local guid = UnitGUID('player')
Nenue@97 44 VeneerData.ArtifactPower = VeneerData.ArtifactPower or defaultSettings
Nenue@97 45 VeneerData.ArtifactPower[guid] = VeneerData.ArtifactPower[guid] or {}
Nenue@97 46 self.profile = VeneerData.ArtifactPower[guid]
Nenue@97 47 self.profile.bagslots = self.profile.bagslots or {}
Nenue@97 48 self.profile.artifacts = self.profile.artifacts or {}
Nenue@97 49 self:GetCurrentArtifact(true)
Nenue@97 50 self.updateSummary = true
Nenue@97 51
Nenue@97 52 -- Bagnon compatibility
Nenue@97 53 -- todo: ArkInventory, Elv, etc
Nenue@97 54 if IsAddOnLoaded('Bagnon') then
Nenue@97 55 local oToggleAllBags = ToggleAllBags
Nenue@97 56 ToggleAllBags = function()
Nenue@97 57 print('|cFFFF0088ToggleAllBags')
Nenue@97 58 oToggleAllBags()
Nenue@97 59 if BagnonFrameinventory:IsShown() then
Nenue@97 60 self:Show()
Nenue@97 61 else
Nenue@97 62 self.enabled = nil
Nenue@97 63 self:Hide()
Nenue@97 64 end
Nenue@97 65 end
Nenue@97 66 else
Nenue@97 67 hooksecurefunc("OpenBackpack", function()
Nenue@97 68 self:Show()
Nenue@97 69 end)
Nenue@97 70 hooksecurefunc("CloseBackpack", function()
Nenue@97 71 self.enabled = nil
Nenue@97 72 self:Hide()
Nenue@97 73 end)
Nenue@97 74 end
Nenue@97 75
Nenue@97 76
Nenue@97 77 end
Nenue@97 78 local UNDERLIGHT_ANGLER_ID = 133755
Nenue@97 79 function ap:GetCurrentArtifact(newItem)
Nenue@97 80 if not self.profile then
Nenue@97 81 return
Nenue@97 82 end
Nenue@97 83 local artifacts = self.profile.artifacts
Nenue@97 84 local itemID, altItemID, name, texture, currentXP, pointsSpent, _, _, artifactAppearanceID, appearanceModID, itemAppearanceID, altItemAppearanceID, altOnTop = C_ArtifactUI:GetArtifactInfo()
Nenue@97 85
Nenue@97 86
Nenue@97 87 if itemID then
Nenue@97 88
Nenue@97 89
Nenue@97 90
Nenue@97 91
Nenue@97 92 print('updating', itemID, name, currentXP, pointsSpent, pointsAvailable, adjustedXP)
Nenue@97 93 table.wipe(artifacts[itemID])
Nenue@97 94 artifacts[itemID] = artifacts[itemID] or {}
Nenue@97 95 artifacts[itemID].name = name
Nenue@97 96 artifacts[itemID].texture = texture
Nenue@97 97 artifacts[itemID].currentXP = currentXP
Nenue@97 98 artifacts[itemID].level = pointsSpent
Nenue@97 99 end
Nenue@97 100
Nenue@97 101
Nenue@97 102 self:Update()
Nenue@97 103 end
Nenue@97 104 function ap:QueueBag(containerID)
Nenue@97 105 containerID = tonumber(containerID)
Nenue@97 106 if not containerID then
Nenue@97 107 return
Nenue@97 108 end
Nenue@97 109
Nenue@97 110 if not tContains(BAGS_TO_SCAN, containerID) then
Nenue@97 111 print(' queueing', containerID, type(containerID), #BAGS_TO_SCAN , 'in line')
Nenue@97 112 BAGS_TO_SCAN[#BAGS_TO_SCAN + 1] = containerID
Nenue@97 113 end
Nenue@97 114 end
Nenue@97 115
Nenue@97 116 function ap:OnShow()
Nenue@97 117 self.enabled = true
Nenue@97 118 self:Update()
Nenue@97 119 Veneer:DynamicReanchor()
Nenue@97 120 end
Nenue@97 121 function ap:OnHide()
Nenue@97 122 Veneer:DynamicReanchor()
Nenue@97 123 end
Nenue@97 124
Nenue@97 125 function ap:OnEnter()
Nenue@97 126
Nenue@97 127 GameTooltip:SetOwner(self, 'ANCHOR_CURSOR')
Nenue@97 128
Nenue@97 129 GameTooltip:AddLine(self.bagAP)
Nenue@97 130 GameTooltip:AddLine(self.bankAP)
Nenue@97 131
Nenue@97 132 end
Nenue@97 133
Nenue@97 134 function ap:OnEvent(event, ...)
Nenue@97 135 print(self:GetName()..':OnEvent()', event, ...)
Nenue@97 136 if event == 'BAG_UPDATE' then
Nenue@97 137 local containerID = ...
Nenue@97 138 self:QueueBag(containerID)
Nenue@97 139 elseif event == 'PLAYER_BANKSLOTS_CHANGED' then
Nenue@97 140 self:QueueBag(BANK_CONTAINER)
Nenue@97 141 elseif event == 'BAG_UPDATE_DELAYED' then
Nenue@97 142 self:ScanAllBags()
Nenue@97 143 elseif event == 'BANKFRAME_OPENED' then
Nenue@97 144 self.bankAccess = true
Nenue@97 145 self:QueueBag(BANK_CONTAINER)
Nenue@97 146 for i = 1, GetNumBankSlots() do
Nenue@97 147 self:QueueBag(i+NUM_BAG_SLOTS)
Nenue@97 148 end
Nenue@97 149 self:ScanAllBags()
Nenue@97 150 elseif event == 'BANKFRAME_CLOSED' then
Nenue@97 151 self.bankAccess = false
Nenue@97 152 self:Update()
Nenue@97 153 elseif event == 'ARTIFACT_UPDATE' then
Nenue@97 154 self:GetCurrentArtifact(...)
Nenue@97 155 elseif event == 'ARTIFACT_UPDATE_XP' then
Nenue@97 156 self:GetCurrentArtifact(...)
Nenue@97 157 self:Update()
Nenue@97 158 elseif event == 'MODIFIER_STATE_CHANGED' then
Nenue@97 159 self:Update()
Nenue@97 160 elseif event == 'PLAYER_REGEN_ENABLED' then
Nenue@97 161 if self.enabled then
Nenue@97 162 self:Show()
Nenue@97 163 end
Nenue@97 164
Nenue@97 165 elseif event == 'PLAYER_REGEN_DISABLED' then
Nenue@97 166 self:Hide()
Nenue@97 167 end
Nenue@97 168 end
Nenue@97 169
Nenue@97 170 function ap:OnMouseDown()
Nenue@97 171 self.enabled = nil
Nenue@97 172 self:Hide()
Nenue@97 173 end
Nenue@97 174
Nenue@97 175 function ap:Update()
Nenue@97 176 if not self:IsShown() then
Nenue@97 177 return
Nenue@97 178 end
Nenue@97 179 print('|cFF00FFFFUpdate()|r')
Nenue@97 180
Nenue@97 181 local bankText, bagText
Nenue@97 182 if not (self.bankAP and self.bagAP) then
Nenue@97 183 bankText = '|cFFFF0000Open bank frame to count all AP|r '
Nenue@97 184 else
Nenue@97 185 bankText = '|cFFFFFFFFAP:|r' .. tostring(self.bagAP + self.bankAP) .. ' |cFFFFFF00('..tostring(self.bankAP)..' banked)|r'
Nenue@97 186 end
Nenue@97 187 self.SummaryHeader:SetText(bankText)
Nenue@97 188
Nenue@97 189 -- Artifact icons, in no particular order
Nenue@97 190 local equippedID = C_ArtifactUI.GetEquippedArtifactInfo()
Nenue@97 191 local numButtons = 0
Nenue@97 192 local lastFrame
Nenue@97 193 for itemID, artifact in pairs(self.profile.artifacts) do
Nenue@97 194 print(artifact.name, artifact.texture, artifact.currentXP)
Nenue@97 195 numButtons = numButtons + 1
Nenue@97 196 local button = self.Artifact[numButtons]
Nenue@97 197
Nenue@97 198 button:SetID(itemID)
Nenue@97 199 for k,v in pairs(artifact) do
Nenue@97 200 --print('::',k,v)
Nenue@97 201 button[k] = v
Nenue@97 202 end
Nenue@97 203
Nenue@97 204
Nenue@97 205 local pointsAvailable = button.level
Nenue@97 206 local cost = C_ArtifactUI.GetCostForPointAtRank(pointsAvailable)
Nenue@97 207 local adjustedXP = button.currentXP
Nenue@97 208 if itemID ~= UNDERLIGHT_ANGLER_ID then
Nenue@97 209 adjustedXP = adjustedXP + (self.bankAP or 0) + (self.bagAP or 0)
Nenue@97 210 print('not UL angler', adjustedXP)
Nenue@97 211 else
Nenue@97 212 print('UL angler', adjustedXP)
Nenue@97 213 end
Nenue@97 214
Nenue@97 215 while adjustedXP >= cost do
Nenue@97 216 pointsAvailable = pointsAvailable + 1
Nenue@97 217 adjustedXP = adjustedXP - cost
Nenue@97 218 print(pointsAvailable, '-', cost, '=', adjustedXP)
Nenue@97 219 cost = C_ArtifactUI.GetCostForPointAtRank(pointsAvailable)
Nenue@97 220 end
Nenue@97 221 button.adjustedXP = adjustedXP
Nenue@97 222 button.actualLevel = pointsAvailable
Nenue@97 223
Nenue@97 224 button.isEquipped = (equippedID == itemID)
Nenue@97 225 button.relativeFrame = lastFrame
Nenue@97 226 button:Update()
Nenue@97 227 lastFrame = button
Nenue@97 228 button:Show()
Nenue@97 229 end
Nenue@97 230 for i = numButtons+1, #self.Artifact do
Nenue@97 231 print('hide', i)
Nenue@97 232 self.Artifact[i]:Hide()
Nenue@97 233 end
Nenue@97 234
Nenue@97 235
Nenue@97 236
Nenue@97 237 self:SetWidth(64*3+ 16)
Nenue@97 238 self:SetHeight(8 + self.SummaryHeader:GetHeight() + 64)
Nenue@97 239 self:Reanchor()
Nenue@97 240
Nenue@97 241 end
Nenue@97 242
Nenue@97 243 function ap:ScanBag(id)
Nenue@97 244 print('|cFF00FFFFScanBag()|r', id, IsBagOpen(id), GetContainerNumSlots(id))
Nenue@97 245 local numSlots = GetContainerNumSlots(id)
Nenue@97 246 local requiresUpdate
Nenue@97 247 if numSlots == 0 then
Nenue@97 248 return nil
Nenue@97 249 end
Nenue@97 250
Nenue@97 251
Nenue@97 252 self.profile.bagslots[id] = self.profile.bagslots[id] or {}
Nenue@97 253 table.wipe(self.profile.bagslots[id])
Nenue@97 254 local bagData = self.profile.bagslots[id]
Nenue@97 255 bagData.totalAP = 0
Nenue@97 256 for slotID = 1, numSlots do
Nenue@97 257 local texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(id, slotID)
Nenue@97 258 local itemID = GetContainerItemID(id, slotID)
Nenue@97 259
Nenue@97 260 if link then
Nenue@97 261 self.tooltip:SetOwner(self, 'ANCHOR_NONE')
Nenue@97 262 self.tooltip:SetHyperlink(link)
Nenue@97 263 self.tooltip:Show()
Nenue@97 264 local numLines = self.tooltip:NumLines()
Nenue@97 265 if numLines >= 3 then
Nenue@97 266 local subText = _G[TOOLTIP_NAME .. 'TextLeft2']:GetText()
Nenue@97 267 if subText and subText:match(ARTIFACT_POWER) then
Nenue@97 268 for i = 3, numLines do
Nenue@97 269 local text = _G[TOOLTIP_NAME .. 'TextLeft'.. i]:GetText()
Nenue@97 270 if text and text:match(ARTIFACT_POWER) then
Nenue@97 271 text = text:gsub('[,%D]', '')
Nenue@97 272 print(link, '-', tonumber(text))
Nenue@97 273 local itemAP = tonumber(text)
Nenue@97 274 if itemAP then
Nenue@97 275 bagData.numItems = (bagData.numItems or 0) + 1
Nenue@97 276 bagData.totalAP = (bagData.totalAP or 0) + itemAP
Nenue@97 277 bagData.items = bagData.items or {}
Nenue@97 278 if not bagData.items[itemID] then
Nenue@97 279 requiresUpdate = true
Nenue@97 280 bagData.numUnique = (bagData.numUnique or 0) + 1
Nenue@97 281 end
Nenue@97 282 bagData.items[itemID] = (bagData.items[itemAP] or 0) + 1
Nenue@97 283 end
Nenue@97 284 end
Nenue@97 285 end
Nenue@97 286 end
Nenue@97 287 end
Nenue@97 288 end
Nenue@97 289
Nenue@97 290 if self.profile.artifacts[itemID] then
Nenue@97 291 print('artfiact weapon', itemID, link, id, slotID)
Nenue@97 292 self.profile.artifacts[itemID].containerID = id
Nenue@97 293 self.profile.artifacts[itemID].slotID = slotID
Nenue@97 294 end
Nenue@97 295
Nenue@97 296 end
Nenue@97 297
Nenue@97 298 return requiresUpdate
Nenue@97 299 end
Nenue@97 300
Nenue@97 301 function ap:ScanAllBags()
Nenue@97 302 print('|cFFFF0088ScanAllBags()|r')
Nenue@97 303
Nenue@97 304 local bagID = tremove(BAGS_TO_SCAN, 1)
Nenue@97 305 while bagID do
Nenue@97 306 self.updateSummary = self:ScanBag(bagID) or self.updateSummary
Nenue@97 307 bagID = tremove(BAGS_TO_SCAN, 1)
Nenue@97 308 end
Nenue@97 309
Nenue@97 310 if self.updateSummary then
Nenue@97 311 print('tripped updater')
Nenue@97 312 self.bankAP = 0
Nenue@97 313 self.bagAP = 0
Nenue@97 314 for id, bagData in pairs(self.profile.bagslots) do
Nenue@97 315 print(id, GetBagName(id), bagData.totalAP)
Nenue@97 316 id = tonumber(id)
Nenue@97 317 if bagData.totalAP then
Nenue@97 318 if (id == BANK_CONTAINER) or (id >= 5) then
Nenue@97 319 self.bankAP = self.bankAP + bagData.totalAP
Nenue@97 320 else
Nenue@97 321 self.bagAP = self.bagAP + bagData.totalAP
Nenue@97 322 end
Nenue@97 323 end
Nenue@97 324
Nenue@97 325 end
Nenue@97 326 self.lastUpdate = GetTime()
Nenue@97 327 self:Update()
Nenue@97 328 end
Nenue@97 329 self.updateSummary = nil
Nenue@97 330 end
Nenue@97 331
Nenue@97 332 VeneerArtifactButtonMixin = {}
Nenue@97 333 function VeneerArtifactButtonMixin:Update()
Nenue@97 334
Nenue@97 335 if self.actualLevel ~= self.level then
Nenue@97 336 self.Level:SetText(self.actualLevel)
Nenue@97 337 self.Level:SetTextColor(0,1,0)
Nenue@97 338 self.CurrentXP:SetText(self.adjustedXP)
Nenue@97 339 self.CurrentXP:SetTextColor(0,1,0)
Nenue@97 340 else
Nenue@97 341 self.Level:SetText(self.level, 1, 1, 1)
Nenue@97 342 self.Level:SetTextColor(1,1,1)
Nenue@97 343 self.CurrentXP:SetText(self.currentXP)
Nenue@97 344 self.CurrentXP:SetTextColor(1,1,0)
Nenue@97 345 end
Nenue@97 346
Nenue@97 347 if self.isEquipped then
Nenue@97 348 self:SetNormalTexture([[Interface\Buttons\ButtonHilight-Square]])
Nenue@97 349 self:GetNormalTexture():SetBlendMode('ADD')
Nenue@97 350 self:GetNormalTexture():SetVertexColor(0,1,0)
Nenue@97 351 else
Nenue@97 352 self:SetNormalTexture(nil, 'ADD')
Nenue@97 353 end
Nenue@97 354
Nenue@97 355 self:ClearAllPoints()
Nenue@97 356 if self.relativeFrame then
Nenue@97 357 self:SetPoint('BOTTOMLEFT', self.relativeFrame, 'BOTTOMRIGHT', 4, 0)
Nenue@97 358 else
Nenue@97 359 self:SetPoint('BOTTOMLEFT', 4, 4)
Nenue@97 360 end
Nenue@97 361
Nenue@97 362
Nenue@97 363
Nenue@97 364 self.Icon:SetTexture(self.texture)
Nenue@97 365 self.Name:SetText(self.name)
Nenue@97 366 self:SetSize(64,64)
Nenue@97 367 end
Nenue@97 368
Nenue@97 369 function VeneerArtifactButtonMixin:OnEnter()
Nenue@97 370 GameTooltip:SetOwner(self, 'ANCHOR_CURSOR')
Nenue@97 371 GameTooltip:SetText(self.name)
Nenue@97 372 GameTooltip:AddLine(self.currentXP, 1, 1, 0)
Nenue@97 373 if self.adjustedXP ~= self.currentXP then
Nenue@97 374 GameTooltip:AddLine(self.adjustedXP, 0, 1, 1)
Nenue@97 375 end
Nenue@97 376
Nenue@97 377
Nenue@97 378 GameTooltip:Show()
Nenue@97 379 end
Nenue@97 380 function VeneerArtifactButtonMixin:OnLeave()
Nenue@97 381 if GameTooltip:IsOwned(self) then
Nenue@97 382 GameTooltip:Hide()
Nenue@97 383 end
Nenue@97 384 end
Nenue@97 385
Nenue@97 386 function VeneerArtifactButtonMixin:OnClick(button, down)
Nenue@97 387 if self.isEquipped then
Nenue@97 388 SocketInventoryItem(16)
Nenue@97 389 else
Nenue@97 390 SocketContainerItem(self.containerID, self.slotID)
Nenue@97 391 end
Nenue@97 392 end