annotate Modules/ArtifactPower.lua @ 101:f32b63c93275

- implement caching to reduce the number of tooltip queries made for each scan prompt
author Nenue
date Sat, 21 Jan 2017 20:12:17 -0500
parents 74d6d97a2d24
children 1e511e9aaca5
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@99 9 numItems = 0,
Nenue@99 10 Tokens = {},
Nenue@101 11 cache = {},
Nenue@101 12 fishingCache = {},
Nenue@101 13 scanQueue = {},
Nenue@99 14 ItemButtons = {},
Nenue@97 15 anchorPoint = 'TOP',
Nenue@97 16 anchorFrom = 'TOP',
Nenue@97 17 }
Nenue@101 18 local defaultSettings = {
Nenue@101 19 firstUse = true,
Nenue@101 20 autoHide = true,
Nenue@101 21 }
Nenue@97 22 local ap = VeneerArtifactPowerMixin
Nenue@97 23 local BAGS_TO_SCAN = {BACKPACK_CONTAINER }
Nenue@97 24 local TOOLTIP_NAME = 'VeneerAPScanner'
Nenue@98 25 local POINT_COSTS = {
Nenue@98 26 100, 300, 325, 350, 375,
Nenue@98 27 400, 425, 450, 525, 625,
Nenue@98 28 750, 875, 1000, 6840, 8830,
Nenue@98 29 11280, 14400, 18620, 24000, 30600,
Nenue@98 30 39520, 50880, 64800, 82500, 105280,
Nenue@98 31 138650, 182780, 240870, 325520, 417560,
Nenue@98 32 546000, 718200, 946660, 1245840, 1635200,
Nenue@98 33 191500, 2010000, 2110000, 2215000, 2325000,
Nenue@98 34 2440000, 2560000, 2690000, 2825000, 2965000,
Nenue@98 35 3115000, 3270000, 3435000, 3605000, 3785000,
Nenue@98 36 3975000, 4175000, 4385000, 4605000
Nenue@98 37 }
Nenue@97 38
Nenue@99 39 local FRAME_LIST = {'ContainerFrame1', 'BankFrame'}
Nenue@99 40 local BAG_FRAMES = {'ContainerFrame1'}
Nenue@99 41 local BANK_FRAMES = {'BankFrame'}
Nenue@99 42
Nenue@97 43 function ap:OnLoad()
Nenue@97 44 self:RegisterEvent('BAG_UPDATE') -- use to obtain bag IDs to scan
Nenue@97 45 self:RegisterEvent('BAG_UPDATE_DELAYED') -- use to trigger actual scan activity
Nenue@97 46 self:RegisterEvent('BANKFRAME_OPENED') -- determine when bank info is available
Nenue@97 47 self:RegisterEvent('BANKFRAME_CLOSED') -- " " "
Nenue@97 48 self:RegisterEvent('ARTIFACT_UPDATE') -- when artifact data has changed
Nenue@98 49 self:RegisterEvent('ARTIFACT_XP_UPDATE') -- when artifact xp has changed (but not necessarily data)
Nenue@97 50 self:RegisterEvent('PLAYER_REGEN_ENABLED')
Nenue@97 51 self:RegisterEvent('PLAYER_REGEN_DISABLED')
Nenue@99 52 self:RegisterEvent('PLAYER_ENTERING_WORLD')
Nenue@97 53 Veneer:AddHandler(self, self.anchorPoint, true)
Nenue@97 54 SLASH_VENEER_AP1 = "/vap"
Nenue@97 55 SLASH_VENEER_AP2 = "/veneerap"
Nenue@98 56 SlashCmdList.VENEER_AP = function(arg)
Nenue@98 57 if arg == 'fishing' then
Nenue@98 58 if VeneerData.ArtifactPower.EnableFishing then
Nenue@98 59 VeneerData.ArtifactPower.EnableFishing = nil
Nenue@98 60 else
Nenue@98 61 VeneerData.ArtifactPower.EnableFishing = true
Nenue@98 62 end
Nenue@98 63 self:Print('Show Underlight Angler:', (VeneerData.ArtifactPower.EnableFishing and 'ON' or 'OFF'))
Nenue@98 64 self:Update()
Nenue@98 65
Nenue@98 66 else
Nenue@98 67 self:Show()
Nenue@98 68 end
Nenue@97 69 end
Nenue@97 70
Nenue@97 71 self.tooltip = CreateFrame('GameTooltip', TOOLTIP_NAME, self, 'GameTooltipTemplate')
Nenue@99 72 tinsert(UISpecialFrames, self:GetName())
Nenue@99 73
Nenue@97 74
Nenue@97 75 end
Nenue@97 76
Nenue@99 77 local addonCompatibility = {
Nenue@99 78 ['Bagnon'] = {
Nenue@99 79 BagFrames = {'BagnonFrameinventory'},
Nenue@99 80 BankFrames = {'BagnonFramebank'},
Nenue@99 81 PostHooks = {'ToggleAllBags', 'ToggleBackpack' },
Nenue@99 82 MethodClass = 'Bagnon',
Nenue@99 83 MethodHooks = {'BANK_OPENED', 'BANKFRAME_CLOSED'}
Nenue@99 84 }
Nenue@97 85 }
Nenue@97 86
Nenue@99 87
Nenue@97 88 function ap:Setup()
Nenue@97 89 print(self:GetName()..':Setup()')
Nenue@97 90 local guid = UnitGUID('player')
Nenue@97 91 VeneerData.ArtifactPower = VeneerData.ArtifactPower or defaultSettings
Nenue@101 92 self.db = VeneerData.ArtifactPower
Nenue@101 93 self.db[guid] = self.db[guid] or {}
Nenue@101 94 self.db.cache = self.db.cache or {}
Nenue@101 95 self.db.fishingCache = self.db.fishingCache or {}
Nenue@101 96
Nenue@101 97 for i, data in pairs(self.cache) do
Nenue@101 98 -- bring in anything found before player data is active
Nenue@101 99 self.db.cache[i] = data
Nenue@101 100 end
Nenue@101 101 for i, data in pairs(self.fishingCache) do
Nenue@101 102 self.db.fishingCache[i] = data
Nenue@101 103 end
Nenue@101 104
Nenue@101 105
Nenue@101 106 self.cache = self.db.cache
Nenue@101 107 self.profile = self.db[guid]
Nenue@97 108 self.profile.bagslots = self.profile.bagslots or {}
Nenue@97 109 self.profile.artifacts = self.profile.artifacts or {}
Nenue@97 110 self.updateSummary = true
Nenue@97 111
Nenue@101 112 VeneerArtifactPowerTimer:SetScript('OnUpdate', function()
Nenue@101 113 self:OnUpdate()
Nenue@101 114 end)
Nenue@101 115
Nenue@99 116 local DoTryToShow = function()
Nenue@99 117 self:TryToShow()
Nenue@99 118 end
Nenue@99 119 hooksecurefunc("OpenBackpack", DoTryToShow)
Nenue@99 120 hooksecurefunc("CloseBackpack", DoTryToShow)
Nenue@99 121
Nenue@97 122 -- Bagnon compatibility
Nenue@97 123 -- todo: ArkInventory, Elv, etc
Nenue@99 124 for addon, args in pairs(addonCompatibility) do
Nenue@99 125 if IsAddOnLoaded(addon) then
Nenue@99 126 for _, name in ipairs(args.BagFrames) do
Nenue@99 127 tinsert(FRAME_LIST, name)
Nenue@99 128 tinsert(BAG_FRAMES, name)
Nenue@99 129 end
Nenue@99 130 for _, name in ipairs(args.BankFrames) do
Nenue@99 131 tinsert(FRAME_LIST, name)
Nenue@99 132 tinsert(BAG_FRAMES, name)
Nenue@99 133 end
Nenue@99 134 for _, name in ipairs(args.PostHooks) do
Nenue@99 135 local oFunc = _G[name]
Nenue@99 136 _G[name] = function(...)
Nenue@99 137 print('|cFFFF0088' .. name .. '|r', ...)
Nenue@99 138 oFunc(...)
Nenue@99 139 self:TryToShow()
Nenue@99 140 end
Nenue@99 141 end
Nenue@99 142 local frame = _G[args.MethodClass]
Nenue@99 143 if frame then
Nenue@99 144 for _, name in ipairs(args.MethodHooks) do
Nenue@99 145 hooksecurefunc(frame, name, DoTryToShow)
Nenue@99 146 end
Nenue@97 147 end
Nenue@97 148 end
Nenue@97 149 end
Nenue@101 150
Nenue@101 151 if self.db.firstUse then
Nenue@101 152 self.db.firstUse = nil
Nenue@101 153
Nenue@101 154 end
Nenue@99 155 end
Nenue@97 156
Nenue@97 157 local UNDERLIGHT_ANGLER_ID = 133755
Nenue@98 158 function ap:SetArtifact(itemID, name, texture, currentXP, pointsSpent)
Nenue@98 159 print('|cFF00FF00SetArtifact()|r')
Nenue@97 160 if not self.profile then
Nenue@97 161 return
Nenue@97 162 end
Nenue@97 163 local artifacts = self.profile.artifacts
Nenue@97 164
Nenue@101 165 local multi = C_ArtifactUI.GetArtifactKnowledgeMultiplier()
Nenue@101 166 self.profile.knowledgeMultiplier = multi or self.profile.knowledgeMultiplier
Nenue@101 167 print('multiplier:', multi)
Nenue@97 168
Nenue@97 169 if itemID then
Nenue@99 170
Nenue@99 171 self.currentEquipped = itemID
Nenue@99 172
Nenue@98 173 artifacts[itemID] = artifacts[itemID] or {}
Nenue@98 174 table.wipe(artifacts[itemID])
Nenue@98 175 local artifact = artifacts[itemID]
Nenue@97 176
Nenue@98 177 artifact.name = name
Nenue@98 178 artifact.texture = texture
Nenue@98 179 artifact.currentXP = currentXP
Nenue@98 180 artifact.level = pointsSpent
Nenue@98 181 local cost = C_ArtifactUI.GetCostForPointAtRank(pointsSpent)
Nenue@98 182 artifact.cost = cost
Nenue@97 183
Nenue@98 184 local pointsAvailable = pointsSpent
Nenue@98 185 local actualCost = cost
Nenue@98 186 local actualXP = currentXP
Nenue@98 187 while actualXP >= actualCost do
Nenue@98 188 pointsAvailable = pointsAvailable + 1
Nenue@98 189 actualXP = actualXP - actualCost
Nenue@98 190 print(pointsAvailable, '-', actualCost, '=', actualXP)
Nenue@98 191 actualCost = C_ArtifactUI.GetCostForPointAtRank(pointsAvailable)
Nenue@98 192 end
Nenue@98 193 print('updating', itemID, name, currentXP, pointsSpent, pointsAvailable, actualXP)
Nenue@98 194 artifact.actualXP = actualXP
Nenue@98 195 artifact.actualLevel = pointsAvailable
Nenue@98 196 artifact.actualCost = actualCost
Nenue@97 197
Nenue@97 198 end
Nenue@97 199 end
Nenue@97 200 function ap:QueueBag(containerID)
Nenue@97 201 containerID = tonumber(containerID)
Nenue@97 202 if not containerID then
Nenue@97 203 return
Nenue@97 204 end
Nenue@97 205
Nenue@97 206 if not tContains(BAGS_TO_SCAN, containerID) then
Nenue@97 207 print(' queueing', containerID, type(containerID), #BAGS_TO_SCAN , 'in line')
Nenue@97 208 BAGS_TO_SCAN[#BAGS_TO_SCAN + 1] = containerID
Nenue@97 209 end
Nenue@97 210 end
Nenue@97 211
Nenue@99 212 function ap:Reanchor()
Nenue@99 213 if Veneer then
Nenue@99 214 Veneer:DynamicReanchor()
Nenue@99 215 end
Nenue@99 216 end
Nenue@99 217
Nenue@97 218 function ap:OnShow()
Nenue@99 219 print('|cFFFFFF00OnShow()|r')
Nenue@97 220 self.enabled = true
Nenue@99 221 self:ScanAllBags()
Nenue@99 222 self:Reanchor()
Nenue@99 223 if not self.postShowSetup then
Nenue@99 224 self.postShowSetup = true
Nenue@99 225 hooksecurefunc("HideUIPanel", function() self:TryToShow() end)
Nenue@99 226 end
Nenue@97 227 end
Nenue@97 228 function ap:OnHide()
Nenue@99 229 print('|cFF88FF00OnHide()|r')
Nenue@99 230 self:Reanchor()
Nenue@97 231 end
Nenue@97 232 function ap:OnEnter()
Nenue@97 233
Nenue@97 234 GameTooltip:SetOwner(self, 'ANCHOR_CURSOR')
Nenue@97 235
Nenue@99 236
Nenue@97 237 GameTooltip:AddLine(self.bagAP)
Nenue@97 238 GameTooltip:AddLine(self.bankAP)
Nenue@97 239
Nenue@97 240 end
Nenue@97 241
Nenue@99 242 function ap:TryToShow()
Nenue@99 243
Nenue@99 244 print('|cFFFFFF00TryToShow()')
Nenue@99 245
Nenue@99 246 if not InCombatLockdown() then
Nenue@99 247 for _, name in ipairs(FRAME_LIST) do
Nenue@99 248 --print(name, (_G[name] and _G[name]:IsShown()))
Nenue@99 249 if _G[name] and _G[name]:IsShown() then
Nenue@99 250 if self:IsShown() then
Nenue@99 251 self:Update()
Nenue@99 252 else
Nenue@99 253 self:Show()
Nenue@99 254 end
Nenue@99 255 return
Nenue@99 256 end
Nenue@99 257 end
Nenue@99 258 end
Nenue@99 259
Nenue@99 260
Nenue@99 261 self:Hide()
Nenue@99 262 end
Nenue@99 263
Nenue@99 264
Nenue@97 265 function ap:OnEvent(event, ...)
Nenue@99 266 print('|cFF00FF88OnEvent()', event, ...)
Nenue@99 267 if event == 'PLAYER_ENTERING_WORLD' then
Nenue@99 268 self:TryToShow()
Nenue@99 269 elseif event == 'BAG_UPDATE' then
Nenue@97 270 local containerID = ...
Nenue@97 271 self:QueueBag(containerID)
Nenue@97 272 elseif event == 'PLAYER_BANKSLOTS_CHANGED' then
Nenue@99 273 self:ScanAllBags()
Nenue@97 274 elseif event == 'BAG_UPDATE_DELAYED' then
Nenue@99 275 if not self.firstHit then
Nenue@99 276 self.firstHit = true
Nenue@99 277 else
Nenue@99 278 self:ScanAllBags()
Nenue@99 279 end
Nenue@97 280 elseif event == 'BANKFRAME_OPENED' then
Nenue@97 281 self.bankAccess = true
Nenue@99 282 self:ScanAllBags()
Nenue@97 283 elseif event == 'BANKFRAME_CLOSED' then
Nenue@99 284 self.bankAccess = nil
Nenue@97 285 elseif event == 'ARTIFACT_UPDATE' then
Nenue@98 286 local newItem = ...
Nenue@98 287 if newItem then
Nenue@98 288 local itemID, _, name, texture, currentXP, pointsSpent = C_ArtifactUI:GetArtifactInfo()
Nenue@98 289 self:SetArtifact(itemID, name, texture, currentXP, pointsSpent)
Nenue@98 290 self:ScanAllBags(self.bankAccess)
Nenue@98 291 end
Nenue@98 292 elseif event == 'ARTIFACT_XP_UPDATE' then
Nenue@98 293 local itemID, _, name, texture, currentXP, pointsSpent = C_ArtifactUI:GetEquippedArtifactInfo()
Nenue@98 294 self:SetArtifact(itemID, name, texture, currentXP, pointsSpent)
Nenue@98 295 self:ScanAllBags(self.bankAccess)
Nenue@97 296 elseif event == 'PLAYER_REGEN_ENABLED' then
Nenue@97 297 if self.enabled then
Nenue@99 298 if self.queuedScan then
Nenue@99 299 self:ScanAllBags(self.backAccess)
Nenue@99 300 else
Nenue@99 301 self:TryToShow()
Nenue@99 302 end
Nenue@97 303 end
Nenue@97 304
Nenue@97 305 elseif event == 'PLAYER_REGEN_DISABLED' then
Nenue@97 306 self:Hide()
Nenue@97 307 end
Nenue@97 308 end
Nenue@97 309
Nenue@101 310 function ap:OnUpdate()
Nenue@101 311 if #self.scanQueue >= 1 then
Nenue@101 312 local scanInfo = tremove(self.scanQueue, 1)
Nenue@101 313
Nenue@101 314 end
Nenue@101 315 end
Nenue@101 316
Nenue@97 317 function ap:OnMouseDown()
Nenue@97 318 self.enabled = nil
Nenue@97 319 self:Hide()
Nenue@97 320 end
Nenue@97 321
Nenue@97 322 function ap:Update()
Nenue@97 323 if not self:IsShown() then
Nenue@99 324 print('|cFFFF4400Update()|r')
Nenue@97 325 return
Nenue@97 326 end
Nenue@97 327 print('|cFF00FFFFUpdate()|r')
Nenue@97 328
Nenue@97 329 local bankText, bagText
Nenue@101 330 if not self.profile.knowledgeMultiplier then
Nenue@101 331 bankText = '|cFF00FF00Shift-Right-Click an artifact weapon to start building data.'
Nenue@101 332 elseif not (self.bankAP and self.bagAP) then
Nenue@97 333 bankText = '|cFFFF0000Open bank frame to count all AP|r '
Nenue@97 334 else
Nenue@98 335 if (self.bagAP + self.bankAP) == 0 then
Nenue@99 336 bankText = '|cFFFF4400No Artifact Power tokens on hand|r'
Nenue@98 337 else
Nenue@98 338 if self.bagAP and (self.bagAP > 0) then
Nenue@98 339 bankText = '|cFFFFFFFF' .. tostring(self.bagAP) .. '|r'
Nenue@98 340 end
Nenue@98 341 if self.bankAP and (self.bankAP > 0) then
Nenue@98 342 bankText = (bankText and (bankText .. ' | ') or '') .. '|cFFFFFF00'..tostring(self.bankAP)..'|r'
Nenue@98 343 end
Nenue@98 344 end
Nenue@97 345 end
Nenue@99 346 if self.fishingAP and self.fishingAP >= 1 then
Nenue@99 347 bankText = (bankText and (bankText .. ' ') or '') .. '|cFF0088FF' .. tostring(self.fishingAP) .. ' fishing AP|r'
Nenue@99 348 end
Nenue@99 349
Nenue@97 350 self.SummaryHeader:SetText(bankText)
Nenue@97 351
Nenue@101 352 local numButtons = 0
Nenue@101 353 local contentsHeight = 64
Nenue@101 354 if self.profile.knowledgeMultiplier then
Nenue@101 355 numButtons = self:UpdateArtifactButtons()
Nenue@101 356 contentsHeight = contentsHeight + self:UpdateItemButtons()
Nenue@101 357 end
Nenue@101 358
Nenue@101 359
Nenue@101 360
Nenue@101 361 self:SetWidth(64*numButtons + 4 * (numButtons+1))
Nenue@101 362 self:SetHeight(16 + self.SummaryHeader:GetHeight() + contentsHeight)
Nenue@101 363 self:Reanchor()
Nenue@101 364 end
Nenue@101 365
Nenue@101 366 function ap:UpdateArtifactButtons()
Nenue@101 367
Nenue@97 368 -- Artifact icons, in no particular order
Nenue@99 369 self.equippedID = C_ArtifactUI.GetEquippedArtifactInfo()
Nenue@97 370 local numButtons = 0
Nenue@99 371 local lastFrame = self
Nenue@99 372 local fishingID, fishingData
Nenue@98 373 local index, button
Nenue@97 374 for itemID, artifact in pairs(self.profile.artifacts) do
Nenue@99 375 if (itemID == UNDERLIGHT_ANGLER_ID) then
Nenue@98 376 if VeneerData.ArtifactPower.EnableFishing then
Nenue@98 377 fishingID = itemID
Nenue@98 378 fishingData = artifact
Nenue@98 379 end
Nenue@97 380
Nenue@98 381 else
Nenue@98 382 numButtons = numButtons + 1
Nenue@98 383 button = self.Artifact[numButtons]
Nenue@99 384 button.relativeFrame = lastFrame
Nenue@99 385 lastFrame = button:SetButton(itemID, artifact, numButtons, (self.equippedID == itemID))
Nenue@97 386 end
Nenue@97 387
Nenue@98 388 end
Nenue@97 389
Nenue@98 390 if fishingData then
Nenue@98 391 numButtons = numButtons + 1
Nenue@99 392 local button = self.Artifact[numButtons]
Nenue@99 393 button.relativeFrame = lastFrame
Nenue@99 394 button:SetButton(fishingID, fishingData, numButtons, self.equippedID == fishingID)
Nenue@98 395 end
Nenue@97 396
Nenue@99 397 for i = numButtons+ 1, #self.Artifact do
Nenue@97 398 print('hide', i)
Nenue@97 399 self.Artifact[i]:Hide()
Nenue@97 400 end
Nenue@97 401
Nenue@101 402 return numButtons
Nenue@97 403 end
Nenue@97 404
Nenue@99 405
Nenue@99 406 function ap:UpdateItemButtons()
Nenue@99 407 print('|cFF00FFFFUpdateItemButtons()|r')
Nenue@99 408 local lastFrame, upFrame
Nenue@99 409 local numButtons = 0
Nenue@101 410 local buttonsHeight = 0
Nenue@101 411 local buttonWidth = 0
Nenue@99 412 for index, button in ipairs(self.Tokens) do
Nenue@99 413 if button.numItems >= 1 then
Nenue@99 414 if button.itemName then
Nenue@99 415 self:SetItemAction(button)
Nenue@99 416 end
Nenue@99 417
Nenue@99 418 button:ClearAllPoints()
Nenue@99 419 numButtons = numButtons + 1
Nenue@99 420 print(index, button:GetID(), button.Icon:GetTexture())
Nenue@99 421 if numButtons == 1 then
Nenue@101 422 button:SetPoint('TOPLEFT', self, 'TOPLEFT', 4, -76)
Nenue@99 423 upFrame = button
Nenue@101 424 buttonsHeight = 52
Nenue@99 425 elseif mod(numButtons,8) == 1 then
Nenue@99 426 button:SetPoint('TOPLEFT', upFrame, 'BOTTOMLEFT', 0, -2)
Nenue@99 427 upFrame = button
Nenue@101 428 buttonsHeight = buttonsHeight + 52
Nenue@99 429 else
Nenue@99 430 button:SetPoint('TOPLEFT', lastFrame, 'TOPRIGHT', 2, 0)
Nenue@99 431 end
Nenue@99 432 button.Count:SetText(button.numItems)
Nenue@99 433 lastFrame = button
Nenue@99 434 button:Show()
Nenue@99 435 else
Nenue@99 436 button:Hide()
Nenue@99 437 end
Nenue@99 438 end
Nenue@99 439
Nenue@101 440
Nenue@101 441
Nenue@101 442 return buttonsHeight
Nenue@99 443 end
Nenue@99 444
Nenue@99 445 function ap:SetItemAction(button, name)
Nenue@99 446 name = name or self.itemName
Nenue@99 447 if InCombatLockdown() then
Nenue@99 448 self.itemName = name
Nenue@99 449 return
Nenue@99 450 else
Nenue@99 451 button:SetAttribute('*type*','item')
Nenue@99 452 button:SetAttribute('*item*', name)
Nenue@99 453 end
Nenue@99 454 end
Nenue@99 455
Nenue@99 456 function ap:GetItemButton(itemID, texture, itemAP)
Nenue@99 457 print('|cFF00FFFFGetItemButton()|r', itemID, texture, itemAP)
Nenue@99 458 local button = self.ItemButtons[itemID]
Nenue@101 459
Nenue@99 460 if not button then
Nenue@99 461 button = CreateFrame('Button', 'VeneerAPToken'..itemID, self, 'VeneerItemButton')
Nenue@101 462 button.baseAP = itemAP
Nenue@101 463
Nenue@99 464 button:SetPushedTexture([[Interface\Buttons\UI-Quickslot-Depress]])
Nenue@99 465 button:SetHighlightTexture([[Interface\Buttons\ButtonHilight-Square]],"ADD")
Nenue@99 466 button:SetID(itemID)
Nenue@99 467 button.numItems = 0
Nenue@99 468 button.Icon:SetTexture(texture)
Nenue@99 469 button:RegisterForClicks("AnyUp")
Nenue@99 470 self:SetItemAction(button, GetItemInfo(itemID))
Nenue@99 471
Nenue@99 472 print(' created')
Nenue@99 473 self.ItemButtons[itemID] = button
Nenue@99 474 self.numItems = self.numItems + 1
Nenue@99 475 end
Nenue@99 476
Nenue@101 477 local itemAPtext = itemAP * self.profile.knowledgeMultiplier
Nenue@101 478 if itemAPtext >= 100000 then
Nenue@101 479 itemAPtext = floor(itemAPtext/1000) .. 'k'
Nenue@101 480 elseif itemAPtext >= 1000 then
Nenue@101 481 itemAPtext = (floor(itemAPtext/100)/10 ) .. 'k'
Nenue@101 482 end
Nenue@101 483 button.Label:SetText(itemAPtext)
Nenue@101 484
Nenue@99 485 button.numItems = button.numItems + 1
Nenue@99 486 return button
Nenue@99 487 end
Nenue@99 488
Nenue@101 489 function ap:GetItemAP(itemID, itemLink, bagData)
Nenue@101 490 if not self.cache[itemID] then
Nenue@101 491
Nenue@101 492 print('doing tooltip scan')
Nenue@101 493 self.tooltip:SetOwner(self, 'ANCHOR_NONE')
Nenue@101 494 self.tooltip:SetHyperlink(itemLink)
Nenue@101 495 self.tooltip:Show()
Nenue@101 496 local numLines = self.tooltip:NumLines()
Nenue@101 497 if numLines >= 3 then
Nenue@101 498 local subText = _G[TOOLTIP_NAME .. 'TextLeft2']:GetText()
Nenue@101 499 if subText and subText:match(ARTIFACT_POWER) then
Nenue@101 500 for i = 3, numLines do
Nenue@101 501 local text = _G[TOOLTIP_NAME .. 'TextLeft'.. i]:GetText()
Nenue@101 502 if text and text:match(ARTIFACT_POWER) then
Nenue@101 503 text = text:gsub('[,%D]', '')
Nenue@101 504 print(itemLink, '-', tonumber(text))
Nenue@101 505 local itemAP = tonumber(text)
Nenue@101 506 if itemAP then
Nenue@101 507 itemAP = itemAP / self.profile.knowledgeMultiplier
Nenue@101 508 self.cache[itemID] = itemAP
Nenue@101 509 return itemAP
Nenue@101 510 end
Nenue@101 511 end
Nenue@101 512 end
Nenue@101 513 end
Nenue@101 514 local fishingText = _G[TOOLTIP_NAME .. 'TextLeft3']:GetText()
Nenue@101 515 if fishingText and fishingText:match('fishing artifact') then
Nenue@101 516 local fishingAP = fishingText:match("%d+")
Nenue@101 517 fishingAP = tonumber(fishingAP)
Nenue@101 518 if fishingAP then
Nenue@101 519 self.cache[itemID] = fishingAP
Nenue@101 520 self.fishingCache[itemID] = true
Nenue@101 521 return fishingAP, true
Nenue@101 522 end
Nenue@101 523 end
Nenue@101 524 else
Nenue@101 525
Nenue@101 526 self.cache[itemID] = 0
Nenue@101 527 end
Nenue@101 528 end
Nenue@101 529 return self.cache[itemID], self.fishingCache[itemID]
Nenue@101 530 end
Nenue@101 531
Nenue@97 532 function ap:ScanBag(id)
Nenue@97 533 print('|cFF00FFFFScanBag()|r', id, IsBagOpen(id), GetContainerNumSlots(id))
Nenue@97 534 local numSlots = GetContainerNumSlots(id)
Nenue@97 535 local requiresUpdate
Nenue@97 536 if numSlots == 0 then
Nenue@97 537 return nil
Nenue@97 538 end
Nenue@97 539
Nenue@97 540
Nenue@97 541 self.profile.bagslots[id] = self.profile.bagslots[id] or {}
Nenue@97 542 table.wipe(self.profile.bagslots[id])
Nenue@97 543 local bagData = self.profile.bagslots[id]
Nenue@97 544 bagData.totalAP = 0
Nenue@99 545 bagData.fishingAP = 0
Nenue@99 546 bagData.items = bagData.items or {}
Nenue@99 547 table.wipe(bagData.items)
Nenue@99 548
Nenue@97 549 for slotID = 1, numSlots do
Nenue@97 550 local texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(id, slotID)
Nenue@101 551 if link then
Nenue@101 552 local itemID = GetContainerItemID(id, slotID)
Nenue@101 553 local name, _, quality, iLevel, reqLevel, class, subclass = GetItemInfo(link)
Nenue@97 554
Nenue@101 555 if class == 'Consumable' and subclass == 'Other' then
Nenue@101 556 print(GetItemInfo(link))
Nenue@101 557 local itemAP, isFishingAP = self:GetItemAP(itemID, link)
Nenue@101 558 print(itemAP, isFishingAP)
Nenue@101 559 if itemAP > 0 then
Nenue@101 560 if isFishingAP then
Nenue@101 561 bagData.fishingItems = (bagData.fishingItems or 0) + 1
Nenue@101 562 bagData.fishingAP = (bagData.fishingAP or 0) + itemAP
Nenue@101 563 else
Nenue@99 564
Nenue@101 565 bagData.numItems = (bagData.numItems or 0) + 1
Nenue@101 566 bagData.totalAP = (bagData.totalAP or 0) + itemAP
Nenue@101 567 end
Nenue@101 568 bagData.items[itemID] = (bagData.items[itemID] or 0) + 1
Nenue@101 569 local itemButton = self:GetItemButton(itemID, texture, itemAP)
Nenue@101 570 end
Nenue@101 571 elseif self.profile.artifacts[itemID] then
Nenue@101 572 print('artfiact weapon', itemID, link, id, slotID)
Nenue@101 573 self.profile.artifacts[itemID].containerID = id
Nenue@101 574 self.profile.artifacts[itemID].slotID = slotID
Nenue@101 575 end
Nenue@99 576
Nenue@97 577 end
Nenue@97 578
Nenue@97 579 end
Nenue@97 580
Nenue@97 581 end
Nenue@97 582
Nenue@98 583 local BAG_SLOTS = {0, 1, 2, 3, 4 }
Nenue@98 584 local BANK_SLOTS = {-1, 5, 6,7, 8, 9, 10, 11, 12}
Nenue@99 585 local ItemCounts = {}
Nenue@99 586 function ap:ScanAllBags()
Nenue@99 587 if InCombatLockdown() then
Nenue@99 588 self.queuedScan = true
Nenue@99 589 return
Nenue@99 590 end
Nenue@101 591 if not self.profile.knowledgeMultiplier then
Nenue@101 592 print('need to get knowledge level')
Nenue@101 593 return
Nenue@101 594 end
Nenue@101 595
Nenue@99 596 self.queuedScan = nil
Nenue@98 597
Nenue@101 598 print('|cFFFF0088ScanAllBags()|r', self.profile.knowledgeMultiplier)
Nenue@97 599
Nenue@99 600 for _, button in ipairs(self.Tokens) do
Nenue@99 601 button.numItems = 0
Nenue@99 602 end
Nenue@99 603
Nenue@99 604
Nenue@98 605 for _, bagID in ipairs(BAG_SLOTS) do
Nenue@98 606 self:ScanBag(bagID)
Nenue@97 607 end
Nenue@97 608
Nenue@99 609 if self.bankAccess then
Nenue@98 610 for _, bagID in ipairs(BANK_SLOTS) do
Nenue@98 611 self:ScanBag(bagID)
Nenue@98 612 end
Nenue@98 613 end
Nenue@98 614
Nenue@98 615 self.bankAP = 0
Nenue@98 616 self.bagAP = 0
Nenue@99 617 self.fishingAP = 0
Nenue@99 618
Nenue@99 619 table.wipe(ItemCounts)
Nenue@98 620 for id, bagData in pairs(self.profile.bagslots) do
Nenue@98 621 print(id, GetBagName(id), bagData.totalAP)
Nenue@98 622 id = tonumber(id)
Nenue@98 623 if bagData.totalAP then
Nenue@98 624 if (id == BANK_CONTAINER) or (id >= 5) then
Nenue@98 625 self.bankAP = self.bankAP + bagData.totalAP
Nenue@98 626 else
Nenue@98 627 self.bagAP = self.bagAP + bagData.totalAP
Nenue@97 628 end
Nenue@98 629 end
Nenue@99 630 if bagData.fishingAP then
Nenue@99 631 self.fishingAP = self.fishingAP + bagData.fishingAP
Nenue@99 632 end
Nenue@97 633
Nenue@97 634 end
Nenue@98 635 self.lastUpdate = GetTime()
Nenue@99 636 self:TryToShow()
Nenue@97 637 end
Nenue@97 638
Nenue@97 639 VeneerArtifactButtonMixin = {}
Nenue@98 640
Nenue@99 641 function VeneerArtifactButtonMixin:SetButton(itemID, artifact, index, equipped)
Nenue@99 642 print(itemID, index)
Nenue@98 643 print(artifact.name, artifact.texture, artifact.currentXP)
Nenue@98 644 self:SetID(itemID)
Nenue@98 645 for k,v in pairs(artifact) do
Nenue@98 646 --print('::',k,v)
Nenue@98 647 self[k] = v
Nenue@98 648 end
Nenue@98 649
Nenue@98 650 -- this can change between artifact parses
Nenue@98 651 local potentialPoints = self.actualLevel
Nenue@99 652 local totalAP = (itemID ~= UNDERLIGHT_ANGLER_ID) and ((self:GetParent().bankAP or 0) + (self:GetParent().bagAP or 0)) or (self:GetParent().fishingAP or 0)
Nenue@99 653 print(totalAP)
Nenue@98 654 local potentialXP = self.actualXP + totalAP
Nenue@99 655
Nenue@98 656 self.potentialXP = potentialXP
Nenue@98 657 local potentialCost = C_ArtifactUI.GetCostForPointAtRank(potentialPoints)
Nenue@98 658 while potentialXP >= potentialCost do
Nenue@98 659 potentialXP = potentialXP - potentialCost
Nenue@98 660 potentialPoints = potentialPoints + 1
Nenue@98 661 print('inc estimate', potentialXP, potentialPoints)
Nenue@98 662 potentialCost = C_ArtifactUI.GetCostForPointAtRank(potentialPoints)
Nenue@98 663 end
Nenue@98 664 self.potentialCost = potentialCost
Nenue@98 665 self.potentialLevel = potentialPoints
Nenue@98 666 self.potentialAdjustedXP = potentialXP
Nenue@98 667
Nenue@98 668
Nenue@99 669 if index ~= 1 then
Nenue@99 670 self:ClearAllPoints()
Nenue@99 671 self:SetPoint('TOPLEFT', self.relativeFrame, 'TOPRIGHT', 4, 0)
Nenue@99 672 else
Nenue@99 673 self:ClearAllPoints()
Nenue@99 674 self:SetPoint('TOPLEFT', self.relativeFrame, 'TOPLEFT', 4, -4)
Nenue@99 675 end
Nenue@98 676
Nenue@99 677 self.isEquipped = equipped
Nenue@98 678 self:Update()
Nenue@98 679 self:Show()
Nenue@98 680 return self
Nenue@98 681 end
Nenue@98 682
Nenue@97 683 function VeneerArtifactButtonMixin:Update()
Nenue@97 684
Nenue@99 685 local r, g, b = 1, 1, 1
Nenue@99 686 local lR, lG, lB = 1, 1, 0
Nenue@99 687 local levelText = self.level
Nenue@99 688 local xpValue = self.currentXP
Nenue@99 689 local costValue = self.cost
Nenue@97 690 if self.actualLevel ~= self.level then
Nenue@99 691 levelText, r,g,b = self.actualLevel, 0,1,0
Nenue@99 692 xpValue, costValue, lR, lG, lB = self.actualXP, self.actualCost, 0, 1, 0
Nenue@99 693 elseif self.potentialLevel ~= self.level then
Nenue@99 694 levelText, r, g, b = self.potentialLevel, 0,1,1
Nenue@99 695 xpValue, costValue, lR, lG, lB = self.potentialAdjustedXP, self.potentialCost, 0,1,0
Nenue@99 696
Nenue@97 697 end
Nenue@97 698
Nenue@99 699 if xpValue >= 100000 then
Nenue@99 700 xpValue = tostring(floor(xpValue/1000))..'k'
Nenue@99 701 elseif xpValue > 1000 then
Nenue@99 702 xpValue = tostring(floor(xpValue/100)/10)..'k'
Nenue@99 703 end
Nenue@99 704 if costValue >= 100000 then
Nenue@99 705 costValue = tostring(floor(costValue/1000))..'k'
Nenue@99 706 elseif costValue >= 1000 then
Nenue@99 707 costValue = tostring(floor(costValue/100)/10)..'k'
Nenue@99 708 end
Nenue@99 709
Nenue@99 710
Nenue@99 711 self.Level:SetText(levelText)
Nenue@99 712 self.Level:SetTextColor(r, g, b)
Nenue@99 713 self.CurrentXP:SetText(xpValue)
Nenue@99 714 self.CurrentXP:SetTextColor(lR, lG, lB)
Nenue@99 715
Nenue@97 716 if self.isEquipped then
Nenue@97 717 self:SetNormalTexture([[Interface\Buttons\ButtonHilight-Square]])
Nenue@97 718 self:GetNormalTexture():SetBlendMode('ADD')
Nenue@97 719 self:GetNormalTexture():SetVertexColor(0,1,0)
Nenue@97 720 else
Nenue@97 721 self:SetNormalTexture(nil, 'ADD')
Nenue@97 722 end
Nenue@97 723
Nenue@98 724 local currentProgress = (self.currentXP < self.cost) and (self.currentXP / self.cost) or 1
Nenue@98 725 if self.level <= 53 then
Nenue@99 726
Nenue@98 727 self.CurrentProgress.animateFrom = self.CurrentProgress:GetHeight() or 1
Nenue@98 728 self.CurrentProgress.animateTo = currentProgress * self:GetHeight()
Nenue@98 729 self.CurrentProgress:Show()
Nenue@101 730 self.ProgressLine:Show()
Nenue@98 731 else
Nenue@98 732 self.CurrentProgress:Hide()
Nenue@101 733 self.ProgressLine:Hide()
Nenue@98 734 end
Nenue@99 735
Nenue@98 736 if self.potentialXP > self.currentXP then
Nenue@99 737 local projectedProgress = (self.potentialAdjustedXP < self.potentialCost) and (self.potentialXP / self.potentialCost) or 1
Nenue@99 738
Nenue@98 739 if (projectedProgress > currentProgress) then
Nenue@98 740 self.AdjustedProgress:SetPoint('BOTTOM', self.CurrentProgress, 'TOP')
Nenue@98 741 projectedProgress = projectedProgress - currentProgress
Nenue@99 742
Nenue@98 743 else
Nenue@98 744 self.AdjustedProgress:SetPoint('BOTTOM', self, 'BOTTOM')
Nenue@98 745 end
Nenue@99 746 print('show potential', currentProgress, projectedProgress)
Nenue@98 747 self.AdjustedProgress.animateFrom = self.AdjustedProgress:GetHeight() or 1
Nenue@98 748 self.AdjustedProgress.animateTo = projectedProgress * self:GetHeight()
Nenue@97 749
Nenue@101 750 self.AdjustedLine:Show()
Nenue@98 751 self.AdjustedProgress:Show()
Nenue@98 752 else
Nenue@98 753 self.AdjustedProgress:Hide()
Nenue@101 754 self.AdjustedLine:Hide()
Nenue@98 755 end
Nenue@97 756
Nenue@99 757
Nenue@97 758 self.Icon:SetTexture(self.texture)
Nenue@97 759 self:SetSize(64,64)
Nenue@97 760 end
Nenue@97 761
Nenue@98 762
Nenue@98 763 function VeneerArtifactButtonMixin:AnimateProgress(region)
Nenue@98 764 local cTime = GetTime()
Nenue@98 765 if not region.animateStart then
Nenue@98 766 region.animateStart = cTime
Nenue@98 767 end
Nenue@98 768 local progressTo, progressFrom = region.animateTo, region.animateFrom
Nenue@98 769 local elapsed = cTime - region.animateStart
Nenue@98 770 if elapsed >= .5 then
Nenue@98 771 region:SetHeight(progressTo)
Nenue@98 772 region.animateTo = nil
Nenue@98 773 region.animateStart = nil
Nenue@98 774 region.animateFrom = nil
Nenue@98 775 else
Nenue@98 776 local progress = elapsed / .5
Nenue@98 777 local height = (progressFrom + (progressTo - progressFrom) * progress)
Nenue@98 778 --print(self:GetName(), progressTo, progressFrom, (progressTo - progressFrom), ceil(progress*10)/10, ceil(height))
Nenue@98 779 region:SetHeight(height)
Nenue@98 780 end
Nenue@98 781 end
Nenue@98 782
Nenue@98 783 function VeneerArtifactButtonMixin:OnUpdate(sinceLast)
Nenue@98 784 if self.CurrentProgress.animateTo then
Nenue@98 785 self:AnimateProgress(self.CurrentProgress)
Nenue@98 786 end
Nenue@98 787
Nenue@98 788 if self.AdjustedProgress.animateTo then
Nenue@98 789 self:AnimateProgress(self.AdjustedProgress)
Nenue@98 790 end
Nenue@98 791
Nenue@98 792 end
Nenue@98 793
Nenue@97 794 function VeneerArtifactButtonMixin:OnEnter()
Nenue@97 795 GameTooltip:SetOwner(self, 'ANCHOR_CURSOR')
Nenue@97 796 GameTooltip:SetText(self.name)
Nenue@98 797 GameTooltip:AddLine(tostring(self.currentXP) .. ' / '..tostring(self.cost), 1, 1, 0)
Nenue@98 798 if self.potentialXP > self.currentXP then
Nenue@98 799 GameTooltip:AddLine(tostring(self.potentialXP) .. ' potential XP', 0, 1, 1)
Nenue@99 800 if self.potentialAdjustedXP ~= self.potentialXP then
Nenue@99 801 GameTooltip:AddLine(tostring(self.potentialAdjustedXP) .. ' / ' .. tostring(self.potentialCost).. ' after', 0, 1, 0)
Nenue@98 802 end
Nenue@97 803 end
Nenue@99 804 if self.actualLevel ~= self.level then
Nenue@99 805 GameTooltip:AddLine(tostring(self.actualLevel - self.level) .. ' points unlocked', 0, 1, 1)
Nenue@99 806 end
Nenue@99 807
Nenue@97 808 GameTooltip:Show()
Nenue@97 809 end
Nenue@97 810 function VeneerArtifactButtonMixin:OnLeave()
Nenue@97 811 if GameTooltip:IsOwned(self) then
Nenue@97 812 GameTooltip:Hide()
Nenue@97 813 end
Nenue@97 814 end
Nenue@97 815
Nenue@97 816 function VeneerArtifactButtonMixin:OnClick(button, down)
Nenue@97 817 if self.isEquipped then
Nenue@97 818 SocketInventoryItem(16)
Nenue@97 819 else
Nenue@97 820 SocketContainerItem(self.containerID, self.slotID)
Nenue@97 821 end
Nenue@97 822 end