annotate Modules/ArtifactPower.lua @ 122:ea2c616a3b4f

Standardize anchor variables - anchorGroup sets general position, defers to anchorPoint - anchorPoint and anchorFrom are used in SetPoint, deferring to anchorGroup and its inverse Artifact Power: - scan and update triggers trimmed down BuffFrame: - extra values can be right clicked to hide for particular auras LFG: - Desolate Host link placed above Sisters when searching for best cheevos TalkingHead - Re-enable TalkingHeadFrame click behaviour
author Nenue
date Mon, 21 Aug 2017 22:15:46 -0400
parents 1f68c46bc4de
children b3c0258b419d
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@119 14 worldQuestAP = 0,
Nenue@119 15 worldQuestItems = {},
Nenue@99 16 ItemButtons = {},
Nenue@121 17 anchorGroup = 'TOP',
Nenue@122 18 anchorPoint = 'TOPLEFT',
Nenue@116 19 anchorPriority = 3,
Nenue@121 20 anchorFrom = 'BOTTOMLEFT',
Nenue@115 21 moduleName = 'Artifactor',
Nenue@115 22 HideCombat = true
Nenue@97 23 }
Nenue@122 24
Nenue@122 25 VeneerArtifactButtonMixin = {}
Nenue@122 26 local Artifact = VeneerArtifactButtonMixin
Nenue@122 27
Nenue@101 28 local defaultSettings = {
Nenue@101 29 firstUse = true,
Nenue@101 30 autoHide = true,
Nenue@101 31 }
Nenue@116 32 local Module = VeneerArtifactPowerMixin
Nenue@122 33 local BAGS_TO_SCAN = {BACKPACK_CONTAINER}
Nenue@97 34 local TOOLTIP_NAME = 'VeneerAPScanner'
Nick@111 35 local FISHING_MAX_TRAITS = 24
Nenue@116 36 local WEAPON_MAX_TRAITS = 92
Nenue@116 37 local FRAME_PADDING = 4
Nenue@116 38 local EQUIPPED_SIZE = 64
Nick@111 39 local BUTTON_SIZE = 48
Nenue@99 40 local FRAME_LIST = {'ContainerFrame1', 'BankFrame'}
Nenue@99 41 local BAG_FRAMES = {'ContainerFrame1'}
Nenue@99 42 local BANK_FRAMES = {'BankFrame'}
Nenue@99 43
Nenue@116 44 function Module:OnLoad()
Nenue@97 45 self:RegisterEvent('BAG_UPDATE') -- use to obtain bag IDs to scan
Nenue@97 46 self:RegisterEvent('BAG_UPDATE_DELAYED') -- use to trigger actual scan activity
Nenue@122 47 self:RegisterEvent('BANKFRAME_OPENED') -- bank info available
Nenue@122 48 self:RegisterEvent('BANKFRAME_CLOSED') --
Nenue@122 49 self:RegisterEvent('ARTIFACT_UPDATE') -- visible data change
Nenue@122 50 self:RegisterEvent('ARTIFACT_XP_UPDATE') -- xp for equipped artifact
Nenue@122 51 self:RegisterEvent('PLAYER_REGEN_ENABLED') -- combat
Nenue@122 52 self:RegisterEvent('PLAYER_REGEN_DISABLED') --
Nenue@122 53 self:RegisterEvent('PLAYER_ENTERING_WORLD') -- zone/instance transfer
Nick@108 54 self:RegisterEvent('ITEM_LOCK_CHANGED') -- use to clear bag slot cache data
Nenue@115 55 Veneer:AddHandler(self)
Nenue@97 56 SLASH_VENEER_AP1 = "/vap"
Nenue@97 57 SLASH_VENEER_AP2 = "/veneerap"
Nenue@98 58 SlashCmdList.VENEER_AP = function(arg)
Nenue@98 59 if arg == 'fishing' then
Nenue@98 60 if VeneerData.ArtifactPower.EnableFishing then
Nenue@98 61 VeneerData.ArtifactPower.EnableFishing = nil
Nenue@98 62 else
Nenue@98 63 VeneerData.ArtifactPower.EnableFishing = true
Nenue@98 64 end
Nenue@98 65 self:Print('Show Underlight Angler:', (VeneerData.ArtifactPower.EnableFishing and 'ON' or 'OFF'))
Nenue@98 66 self:Update()
Nick@108 67 elseif arg == 'reset' then
Nick@108 68 if self.db then
Nick@108 69 table.wipe(self.db.cache)
Nick@108 70 table.wipe(self.db.fishingCache)
Nick@108 71 end
Nick@108 72 self:Print('Cache data reset.')
Nick@108 73 self:Update()
Nenue@122 74 elseif arg:match('item') then
Nenue@122 75 print('name', arg:match("^item (%S.+)"))
Nenue@122 76 print('num', arg:match("Hitem:(%d+)"))
Nenue@122 77 local linkOrID = arg:match("item:(%d+)") or arg:match("^item (%S+)")
Nenue@122 78 if linkOrID then
Nenue@122 79 local name, etc = GetItemInfo(linkOrID)
Nenue@122 80 end
Nenue@122 81
Nenue@98 82 else
Nenue@122 83
Nenue@98 84 self:Show()
Nenue@98 85 end
Nenue@97 86 end
Nenue@97 87
Nenue@97 88 self.tooltip = CreateFrame('GameTooltip', TOOLTIP_NAME, self, 'GameTooltipTemplate')
Nenue@99 89
Nenue@97 90
Nenue@97 91 end
Nick@108 92 local ShortNumberString = function (value)
Nenue@122 93 if value >= 1000000000 then
Nenue@122 94
Nenue@122 95 return tostring(floor(value/10000000)/100) .. 'B'
Nenue@122 96 elseif value >= 1000000 then
Nenue@116 97 return tostring(floor(value/100000)/10) .. 'M'
Nenue@116 98 elseif value >= 100000 then
Nick@108 99 return tostring(floor(value/1000)) .. 'k'
Nick@108 100 elseif value >= 1000 then
Nick@108 101 return tostring(floor(value/100)/10) .. 'k'
Nick@108 102 else
Nick@108 103 return value
Nick@108 104 end
Nick@108 105 end
Nenue@97 106
Nenue@102 107
Nenue@102 108 local IsBagnonOpen = function()
Nenue@102 109 return ((BagnonFramebank and BagnonFramebank:IsShown()) or (BagnonFrameinventory and BagnonFrameinventory:IsShown()))
Nenue@102 110 end
Nenue@99 111 local addonCompatibility = {
Nenue@99 112 ['Bagnon'] = {
Nenue@99 113 BagFrames = {'BagnonFrameinventory'},
Nenue@99 114 BankFrames = {'BagnonFramebank'},
Nenue@102 115 FrameMethods = {
Nenue@103 116 ['Hide'] = IsBagnonOpen,
Nenue@103 117 ['Show'] = IsBagnonOpen
Nenue@102 118 },
Nenue@103 119 PostHooks = {},
Nenue@99 120 MethodClass = 'Bagnon',
Nenue@102 121 MethodHooks = {'BANK_OPENED', 'BANKFRAME_CLOSED'},
Nenue@102 122
Nenue@99 123 }
Nenue@97 124 }
Nenue@97 125
Nenue@103 126
Nenue@103 127
Nenue@103 128 local queued_hooks = {}
Nenue@103 129 local function CreateHook(...)
Nenue@103 130 if select('#', ...) >= 2 then
Nenue@103 131 tinsert(queued_hooks, {...})
Nenue@103 132 end
Nenue@103 133 if not InCombatLockdown() then
Nenue@103 134 local info = tremove(queued_hooks)
Nenue@103 135 while info do
Nick@111 136 --[[local oFunc = tremove(info, #info)
Nick@111 137 local args = info
Nick@111 138
Nick@111 139 local func = function(...)
Nick@111 140 print('|cFFFF0088Callback:|r', unpack(args))
Nick@111 141
Nick@111 142 oFunc(...)
Nick@111 143 end
Nick@111 144 print('hooking', unpack(info), oFunc, func)
Nick@111 145 hooksecurefunc(unpack(info), func)
Nick@111 146 --]]
Nenue@103 147 hooksecurefunc(unpack(info))
Nenue@103 148 info = tremove(queued_hooks)
Nenue@103 149 end
Nenue@103 150
Nenue@103 151 end
Nenue@103 152 end
Nenue@103 153
Nenue@102 154 local function AddFrameHooks(frame, args)
Nenue@102 155 for funcName, func in pairs(args.FrameMethods) do
Nenue@102 156 print('binding', frame:GetName(), funcName, 'to', tostring(func))
Nenue@103 157 CreateHook(frame, funcName, function()
Nick@111 158 print(frame:GetName(), funcName, 'hook')
Nenue@103 159 VeneerArtifactPower:TryToShow()
Nenue@103 160 end)
Nenue@102 161 end
Nenue@102 162 end
Nenue@102 163 local PENDING_HOOKS = {}
Nenue@119 164 local guid = UnitGUID('player')
Nenue@102 165
Nenue@102 166 local function RegisterInventoryFrame(name, listType, args)
Nenue@102 167 print('register', name, 'as inventory frame type =', (listType == BAG_FRAMES) and 'bags' or 'bank')
Nenue@102 168 tinsert(FRAME_LIST, name)
Nenue@102 169 tinsert(listType, name)
Nenue@102 170 if _G[name] then
Nenue@102 171 AddFrameHooks(_G[name], args)
Nenue@102 172 else
Nenue@102 173 PENDING_HOOKS[name] = args
Nenue@102 174 end
Nenue@102 175 end
Nenue@102 176
Nenue@116 177 function Module:Setup()
Nenue@97 178 print(self:GetName()..':Setup()')
Nenue@119 179 guid = UnitGUID('player')
Nenue@97 180 VeneerData.ArtifactPower = VeneerData.ArtifactPower or defaultSettings
Nenue@101 181 self.db = VeneerData.ArtifactPower
Nenue@101 182 self.db[guid] = self.db[guid] or {}
Nenue@101 183 self.db.cache = self.db.cache or {}
Nenue@101 184 self.db.fishingCache = self.db.fishingCache or {}
Nenue@101 185
Nenue@101 186 for i, data in pairs(self.cache) do
Nenue@101 187 -- bring in anything found before player data is active
Nenue@101 188 self.db.cache[i] = data
Nenue@101 189 end
Nenue@101 190 for i, data in pairs(self.fishingCache) do
Nenue@101 191 self.db.fishingCache[i] = data
Nenue@101 192 end
Nenue@101 193
Nenue@101 194 self.profile = self.db[guid]
Nick@108 195 self.profile.cache = self.profile.cache or {}
Nick@108 196 self.profile.cache.bagItems = self.profile.cache.bagItems or {}
Nick@108 197 self.profile.cache.bags = self.profile.cache.bags or {}
Nick@108 198 self.profile.cache.fishing = self.profile.cache.fishing or {}
Nick@108 199 self.profile.cache.items = self.profile.cache.items or {}
Nenue@97 200 self.profile.bagslots = self.profile.bagslots or {}
Nenue@97 201 self.profile.artifacts = self.profile.artifacts or {}
Nenue@97 202 self.updateSummary = true
Nick@108 203 self.cache = self.profile.cache
Nenue@97 204
Nenue@101 205 VeneerArtifactPowerTimer:SetScript('OnUpdate', function()
Nenue@101 206 self:OnUpdate()
Nenue@101 207 end)
Nenue@101 208
Nenue@99 209 local DoTryToShow = function()
Nick@111 210
Nenue@99 211 self:TryToShow()
Nenue@99 212 end
Nenue@103 213 CreateHook("OpenBackpack", DoTryToShow)
Nenue@103 214 CreateHook("CloseBackpack", DoTryToShow)
Nenue@99 215
Nenue@97 216 -- Bagnon compatibility
Nenue@97 217 -- todo: ArkInventory, Elv, etc
Nenue@99 218 for addon, args in pairs(addonCompatibility) do
Nenue@99 219 if IsAddOnLoaded(addon) then
Nenue@102 220
Nenue@99 221 for _, name in ipairs(args.BagFrames) do
Nenue@102 222 RegisterInventoryFrame(name, BAG_FRAMES, args)
Nenue@99 223 end
Nenue@99 224 for _, name in ipairs(args.BankFrames) do
Nenue@102 225 RegisterInventoryFrame(name, BANK_FRAMES, args)
Nenue@99 226 end
Nenue@102 227
Nenue@102 228 -- should only specify non-secure functions in this table
Nenue@99 229 for _, name in ipairs(args.PostHooks) do
Nenue@99 230 local oFunc = _G[name]
Nenue@103 231 print('hook entry', name, tostring(oFunc))
Nenue@103 232 CreateHook(name, function(...)
Nenue@103 233 print('|cFFFF0088' .. name .. '|r', ..., 'original', tostring(oFunc))
Nenue@99 234 oFunc(...)
Nenue@99 235 self:TryToShow()
Nenue@103 236 end)
Nenue@99 237 end
Nenue@99 238 local frame = _G[args.MethodClass]
Nenue@99 239 if frame then
Nenue@103 240 print()
Nenue@99 241 for _, name in ipairs(args.MethodHooks) do
Nenue@103 242 CreateHook(frame, name, DoTryToShow)
Nenue@99 243 end
Nenue@97 244 end
Nenue@97 245 end
Nenue@97 246 end
Nenue@101 247
Nenue@101 248 if self.db.firstUse then
Nenue@101 249 self.db.firstUse = nil
Nenue@101 250
Nenue@101 251 end
Nenue@99 252 end
Nenue@97 253
Nenue@97 254 local UNDERLIGHT_ANGLER_ID = 133755
Nenue@97 255
Nenue@116 256 function Module:ResetCache()
Nick@111 257 table.wipe(self.cache.items)
Nick@111 258 table.wipe(self.cache.fishing)
Nick@111 259 table.wipe(self.cache.bags)
Nick@111 260 table.wipe(self.cache.bagItems)
Nick@111 261 self:ScanAllBags()
Nick@111 262 end
Nick@111 263
Nenue@116 264 function Module:QueueBag(containerID)
Nenue@97 265 containerID = tonumber(containerID)
Nenue@97 266 if not containerID then
Nenue@97 267 return
Nenue@97 268 end
Nenue@97 269
Nenue@97 270 if not tContains(BAGS_TO_SCAN, containerID) then
Nenue@97 271 print(' queueing', containerID, type(containerID), #BAGS_TO_SCAN , 'in line')
Nenue@97 272 BAGS_TO_SCAN[#BAGS_TO_SCAN + 1] = containerID
Nenue@97 273 end
Nenue@97 274 end
Nenue@97 275
Nenue@116 276 function Module:Reanchor()
Nenue@99 277 if Veneer then
Nenue@99 278 Veneer:DynamicReanchor()
Nenue@99 279 end
Nenue@99 280 end
Nenue@99 281
Nenue@116 282 function Module:OnShow()
Nenue@99 283 print('|cFFFFFF00OnShow()|r')
Nenue@102 284
Nenue@102 285 for name, args in pairs(PENDING_HOOKS) do
Nenue@102 286 if _G[name] then
Nenue@102 287 AddFrameHooks(_G[name], args)
Nenue@102 288 PENDING_HOOKS[name] = nil
Nenue@102 289 end
Nenue@102 290 end
Nenue@102 291
Nenue@119 292 self:UpdateWorldQuestsAP()
Nenue@119 293 self:RegisterEvent('QUEST_LOG_UPDATE')
Nenue@119 294 self.enabled = true
Nenue@102 295
Nenue@99 296 self:ScanAllBags()
Nenue@99 297 self:Reanchor()
Nenue@97 298 end
Nenue@116 299 function Module:OnHide()
Nick@111 300 print('|cFF88FF00OnHide()|r', debugstack())
Nenue@119 301 self:UnregisterEvent('QUEST_LOG_UPDATE')
Nenue@99 302 self:Reanchor()
Nenue@97 303 end
Nenue@116 304 function Module:OnEnter()
Nenue@97 305
Nenue@97 306 GameTooltip:SetOwner(self, 'ANCHOR_CURSOR')
Nenue@97 307
Nenue@99 308
Nenue@97 309 GameTooltip:AddLine(self.bagAP)
Nenue@97 310 GameTooltip:AddLine(self.bankAP)
Nenue@97 311
Nenue@97 312 end
Nenue@97 313
Nenue@116 314 function Module:TryToShow()
Nenue@99 315
Nenue@99 316 print('|cFFFFFF00TryToShow()')
Nenue@99 317
Nenue@99 318 if not InCombatLockdown() then
Nenue@99 319 for _, name in ipairs(FRAME_LIST) do
Nenue@103 320 print('test:', name, (_G[name] and _G[name]:IsShown()))
Nick@111 321 if _G[name] and _G[name]:IsVisible() then
Nenue@99 322 if self:IsShown() then
Nenue@99 323 self:Update()
Nenue@99 324 else
Nenue@99 325 self:Show()
Nenue@99 326 end
Nenue@99 327 return
Nenue@99 328 end
Nenue@99 329 end
Nenue@99 330 end
Nenue@99 331
Nick@111 332 print('failed tests')
Nenue@99 333 self:Hide()
Nenue@99 334 end
Nenue@99 335
Nenue@99 336
Nenue@116 337 function Module:OnEvent(event, ...)
Nenue@99 338 print('|cFF00FF88OnEvent()', event, ...)
Nenue@99 339 if event == 'PLAYER_ENTERING_WORLD' then
Nenue@99 340 self:TryToShow()
Nenue@99 341 elseif event == 'BAG_UPDATE' then
Nenue@97 342 local containerID = ...
Nick@108 343
Nick@108 344
Nenue@97 345 self:QueueBag(containerID)
Nick@108 346 elseif event == 'ITEM_LOCK_CHANGED' then
Nick@108 347
Nick@108 348 local containerID, slotID = ...
Nick@108 349
Nick@108 350 if self.cache.bags[containerID] and self.cache.bags[containerID][slotID] then
Nick@108 351 self.cache.bags[containerID][slotID] = nil
Nick@108 352 self.cache.fishing[containerID][slotID] = nil
Nick@108 353 end
Nick@108 354
Nick@108 355
Nenue@97 356 elseif event == 'PLAYER_BANKSLOTS_CHANGED' then
Nenue@99 357 self:ScanAllBags()
Nenue@97 358 elseif event == 'BAG_UPDATE_DELAYED' then
Nenue@99 359 if not self.firstHit then
Nenue@122 360 -- prevent double call from login
Nenue@99 361 self.firstHit = true
Nenue@99 362 else
Nenue@99 363 self:ScanAllBags()
Nenue@99 364 end
Nenue@97 365 elseif event == 'BANKFRAME_OPENED' then
Nenue@97 366 self.bankAccess = true
Nenue@99 367 self:ScanAllBags()
Nenue@97 368 elseif event == 'BANKFRAME_CLOSED' then
Nenue@99 369 self.bankAccess = nil
Nenue@97 370 elseif event == 'ARTIFACT_UPDATE' then
Nenue@98 371 local newItem = ...
Nenue@98 372 if newItem then
Nenue@98 373 local itemID, _, name, texture, currentXP, pointsSpent = C_ArtifactUI:GetArtifactInfo()
Nenue@122 374 self:UpdateArtifact(itemID, name, texture, currentXP, pointsSpent)
Nenue@122 375 --self:ScanAllBags(self.bankAccess)
Nenue@98 376 end
Nenue@98 377 elseif event == 'ARTIFACT_XP_UPDATE' then
Nenue@98 378 local itemID, _, name, texture, currentXP, pointsSpent = C_ArtifactUI:GetEquippedArtifactInfo()
Nenue@122 379 self:UpdateArtifact(itemID, name, texture, currentXP, pointsSpent)
Nenue@122 380 --self:ScanAllBags(self.bankAccess)
Nenue@97 381 elseif event == 'PLAYER_REGEN_ENABLED' then
Nenue@103 382
Nenue@103 383 if self.queuedScan then
Nenue@103 384 self:ScanAllBags(self.backAccess)
Nenue@103 385 else
Nenue@103 386 self:TryToShow()
Nenue@97 387 end
Nenue@97 388
Nenue@103 389 if #queued_hooks >= 1 then
Nenue@103 390 CreateHook()
Nenue@103 391 end
Nenue@119 392 elseif event == 'QUEST_LOG_UPDATE' then
Nenue@119 393 self:UpdateWorldQuestsAP()
Nenue@97 394 elseif event == 'PLAYER_REGEN_DISABLED' then
Nenue@97 395 self:Hide()
Nenue@97 396 end
Nenue@97 397 end
Nenue@97 398
Nenue@116 399 function Module:OnUpdate()
Nenue@101 400 if #self.scanQueue >= 1 then
Nenue@101 401 local scanInfo = tremove(self.scanQueue, 1)
Nick@111 402 end
Nick@111 403 if IsShiftKeyDown() then
Nick@111 404 self.Refresh:Show()
Nick@111 405 else
Nick@111 406 self.Refresh:Hide()
Nick@111 407 end
Nenue@101 408
Nenue@101 409 end
Nenue@101 410
Nenue@119 411 function Module:OnMouseDown(button)
Nenue@97 412 self.enabled = nil
Nenue@119 413 if button == 'RightButton' then
Nenue@119 414 self:Hide()
Nenue@119 415 end
Nenue@119 416
Nenue@97 417 end
Nenue@97 418
Nenue@116 419 function Module:Update()
Nenue@97 420 if not self:IsShown() then
Nenue@99 421 print('|cFFFF4400Update()|r')
Nenue@97 422 return
Nenue@97 423 end
Nenue@122 424 print('|cFFFFFF00pdate()|r')
Nenue@122 425
Nenue@122 426 local numButtons = 0
Nenue@122 427 local contentsHeight = 16
Nenue@122 428 local contentsWidth = 400
Nenue@122 429 if self.profile.knowledgeMultiplier then
Nenue@122 430 local artifactsWidth = self:UpdateArtifactButtons()
Nenue@122 431
Nenue@122 432 if artifactsWidth ~= 0 then
Nenue@122 433 contentsHeight = contentsHeight + 64
Nenue@122 434 end
Nenue@122 435
Nenue@122 436 contentsWidth = max(contentsWidth, min(artifactsWidth, 400))
Nenue@122 437
Nenue@122 438 local itemsWidth, itemsHeight = self:UpdateItemButtons()
Nenue@122 439 contentsHeight = contentsHeight + itemsHeight
Nenue@122 440 contentsWidth = max(contentsWidth, itemsWidth)
Nenue@122 441 end
Nenue@122 442
Nenue@122 443
Nenue@97 444
Nenue@97 445 local bankText, bagText
Nenue@101 446 if not self.profile.knowledgeMultiplier then
Nenue@101 447 bankText = '|cFF00FF00Shift-Right-Click an artifact weapon to start building data.'
Nenue@101 448 elseif not (self.bankAP and self.bagAP) then
Nenue@97 449 bankText = '|cFFFF0000Open bank frame to count all AP|r '
Nenue@97 450 else
Nick@111 451
Nick@111 452 if self.bagAP and (self.bagAP > 0) then
Nick@111 453 bankText = 'Inventory: |cFFFFFFFF' .. ShortNumberString(self.bagAP) .. '|r'
Nick@111 454 end
Nick@111 455 if self.bankAP and (self.bankAP > 0) then
Nick@111 456 bankText = (bankText and (bankText .. ' | ') or '') .. '|cFFFFFF00'..ShortNumberString(self.bankAP)..' banked|r'
Nick@111 457 end
Nick@111 458 if self.fishingAP and self.fishingAP > 0 then
Nick@111 459 bankText = (bankText and (bankText .. ' | ') or '') .. '|cFF0088FF' .. ShortNumberString(self.fishingAP) .. ' fishing|r'
Nick@111 460 end
Nick@111 461 end
Nick@111 462
Nenue@119 463 if self.worldQuestAP then
Nenue@119 464 bankText = (bankText and (bankText .. '\n') or '') .. '|cFFFFBB00World Quests:|r |cFFFFFFFF' .. ShortNumberString(self.worldQuestAP) .. ''
Nenue@119 465 end
Nick@111 466
Nenue@99 467
Nenue@97 468 self.SummaryHeader:SetText(bankText)
Nenue@122 469 if not self.lastButton then
Nenue@122 470 contentsHeight = contentsHeight + self.SummaryHeader:GetHeight()
Nenue@101 471 end
Nenue@101 472
Nenue@101 473
Nick@111 474 if not self.hasArtifacts then
Nick@111 475 self:SetShown(false)
Nick@111 476 end
Nick@111 477
Nenue@101 478
Nick@108 479 self:SetWidth(contentsWidth)
Nick@108 480 self:SetHeight(contentsHeight)
Nenue@101 481 self:Reanchor()
Nenue@101 482 end
Nenue@101 483
Nenue@119 484 local BROKEN_ISLE_ID = 1007
Nenue@119 485
Nenue@119 486 function Module:UpdateWorldQuestsAP()
Nenue@119 487 self.waitingForQuestRewardData = false
Nenue@119 488 self.worldQuestAP = 0
Nenue@119 489 wipe(self.worldQuestItems)
Nenue@119 490
Nenue@119 491 for zoneIndex = 1, C_MapCanvas.GetNumZones(BROKEN_ISLE_ID) do
Nenue@119 492 local zoneMapID, zoneName, zoneDepth, left, right, top, bottom = C_MapCanvas.GetZoneInfo(BROKEN_ISLE_ID, zoneIndex);
Nenue@119 493 --print(zoneMapID, zoneName)
Nenue@119 494 if zoneDepth <= 1 then -- Exclude subzones
Nenue@119 495 local taskInfo = C_TaskQuest.GetQuestsForPlayerByMapID(zoneMapID, BROKEN_ISLE_ID);
Nenue@119 496
Nenue@119 497 if taskInfo then
Nenue@119 498 for i, info in ipairs(taskInfo) do
Nenue@119 499 local questID = info.questId
Nenue@119 500
Nenue@119 501 local questTitle, factionID, capped = C_TaskQuest.GetQuestInfoByQuestID(questID)
Nenue@119 502 --print(questTitle, HaveQuestRewardData(questID))
Nenue@119 503 if HaveQuestRewardData(questID) then
Nenue@119 504
Nenue@119 505
Nenue@119 506 local numQuestRewards = GetNumQuestLogRewards(questID);
Nenue@119 507
Nenue@119 508 if numQuestRewards > 0 then
Nenue@119 509 for i = 1, numQuestRewards do
Nenue@119 510 local name, texture, numItems, quality, isUsable, itemID = GetQuestLogRewardInfo(i, questID)
Nenue@119 511 if IsArtifactPowerItem(itemID) then
Nenue@119 512 local _, link = GetItemInfo(itemID)
Nenue@119 513 if link then
Nenue@119 514 local ap = self:GetItemAP(itemID, link)
Nenue@119 515 --print('ap =', ap)
Nenue@119 516 if ap then
Nenue@119 517 self.worldQuestAP = self.worldQuestAP + ap
Nenue@119 518
Nenue@119 519 end
Nenue@119 520
Nenue@119 521 self.worldQuestItems[itemID] = (self.worldQuestItems[itemID] or 0) + 1
Nenue@119 522 end
Nenue@119 523
Nenue@119 524 --print(self.worldQuestAP)
Nenue@119 525 end
Nenue@119 526
Nenue@119 527 end
Nenue@119 528
Nenue@119 529 end
Nenue@119 530
Nenue@119 531
Nenue@119 532 else
Nenue@119 533 C_TaskQuest.RequestPreloadRewardData(questID);
Nenue@119 534 self.waitingForQuestRewardData = true
Nenue@119 535 end
Nenue@119 536 end
Nenue@119 537 end
Nenue@119 538 end
Nenue@119 539 end
Nenue@119 540 end
Nenue@119 541
Nenue@116 542 function Module:UpdateArtifactButtons()
Nenue@101 543
Nenue@97 544 -- Artifact icons, in no particular order
Nenue@99 545 self.equippedID = C_ArtifactUI.GetEquippedArtifactInfo()
Nenue@122 546 self.lastButton = nil
Nick@111 547 self.canAddAP = nil
Nick@111 548 self.canAddFishingAP = nil
Nick@111 549 local hasArtifacts
Nenue@97 550 local numButtons = 0
Nenue@99 551 local lastFrame = self
Nenue@99 552 local fishingID, fishingData
Nenue@98 553 local index, button
Nenue@116 554 local equipped =self.profile.artifacts[self.equippedID]
Nenue@116 555 local buttonsWidth = 0
Nenue@116 556 if equipped then
Nenue@116 557 numButtons = numButtons + 1
Nenue@116 558 button = self.Artifact[numButtons]
Nenue@116 559 button.relativeFrame = self
Nenue@122 560 if self.equippedID ~= button.itemID then
Nenue@122 561 button:SetItem(self.equippedID, equipped, numButtons, true, nil)
Nenue@122 562 hasArtifacts = true
Nenue@122 563 end
Nenue@122 564 lastFrame = button
Nenue@116 565 buttonsWidth = EQUIPPED_SIZE + (FRAME_PADDING * 2)
Nenue@116 566 end
Nenue@97 567 for itemID, artifact in pairs(self.profile.artifacts) do
Nenue@116 568 if (itemID == UNDERLIGHT_ANGLER_ID) then
Nenue@116 569 -- only add if we have fishing AP items and it's not being shown in the equipped slot
Nenue@116 570 if VeneerData.ArtifactPower.EnableFishing and (itemID ~= self.equippedID) then
Nenue@98 571 fishingID = itemID
Nenue@98 572 fishingData = artifact
Nenue@98 573 end
Nenue@97 574
Nick@111 575 if artifact.level < FISHING_MAX_TRAITS then
Nick@111 576 if itemID == self.equippedID then
Nick@111 577 self.canAddFishingAP = true
Nick@111 578 end
Nick@111 579 end
Nenue@98 580 else
Nick@111 581 if artifact.level < WEAPON_MAX_TRAITS then
Nick@111 582 if itemID == self.equippedID then
Nick@111 583 self.canAddAP = true
Nenue@116 584 else
Nenue@116 585
Nenue@116 586 hasArtifacts = true
Nenue@116 587 numButtons = numButtons + 1
Nenue@116 588 button = self.Artifact[numButtons]
Nenue@116 589 button.relativeFrame = lastFrame
Nenue@122 590 if button.itemID ~= itemID then
Nenue@122 591 button:SetItem(itemID, artifact, numButtons, (self.equippedID == itemID), nil)
Nenue@122 592 end
Nenue@122 593 lastFrame = button
Nenue@116 594 buttonsWidth = buttonsWidth + lastFrame:GetWidth() + FRAME_PADDING
Nick@111 595 end
Nick@108 596 end
Nenue@97 597 end
Nick@111 598 end
Nenue@97 599
Nenue@122 600 self.lastButton = lastFrame
Nenue@122 601
Nenue@97 602
Nick@108 603 if fishingData and (self.fishingAP and self.fishingAP > 0) then
Nenue@98 604 numButtons = numButtons + 1
Nick@111 605 hasArtifacts = true
Nenue@99 606 local button = self.Artifact[numButtons]
Nenue@99 607 button.relativeFrame = lastFrame
Nick@111 608 button.isFishing = true
Nenue@122 609 button:SetItem(fishingID, fishingData, numButtons, self.equippedID == fishingID)
Nenue@122 610 self.lastButton = button
Nenue@98 611 end
Nenue@97 612
Nick@111 613 self.hasArtifacts = hasArtifacts
Nenue@99 614 for i = numButtons+ 1, #self.Artifact do
Nenue@97 615 print('hide', i)
Nenue@97 616 self.Artifact[i]:Hide()
Nenue@97 617 end
Nenue@97 618
Nenue@122 619 self.SummaryHeader:ClearAllPoints()
Nenue@122 620 if self.lastButton then
Nenue@122 621 self.SummaryHeader:SetPoint('TOPLEFT', self.lastButton, 'TOPRIGHT', 4, -2)
Nenue@122 622 else
Nenue@122 623 self.SummaryHeader:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 4, 4)
Nenue@122 624 end
Nenue@122 625
Nenue@122 626
Nick@111 627
Nenue@116 628 return buttonsWidth
Nenue@97 629 end
Nenue@97 630
Nenue@99 631
Nenue@116 632 function Module:UpdateItemButtons()
Nenue@99 633 print('|cFF00FFFFUpdateItemButtons()|r')
Nick@111 634
Nick@111 635 local apType
Nick@111 636 if self.canAddFishingAP then
Nick@111 637 apType = true
Nick@111 638 elseif not self.canAddAP then
Nick@111 639 for index, button in ipairs(self.Tokens) do
Nick@111 640 button:Hide()
Nick@111 641 end
Nick@111 642 return 0, 0
Nick@111 643 end
Nick@111 644
Nick@111 645
Nenue@99 646 local lastFrame, upFrame
Nenue@99 647 local numButtons = 0
Nenue@101 648 local buttonsHeight = 0
Nick@108 649 local buttonsWidth = 0
Nick@111 650
Nenue@99 651 for index, button in ipairs(self.Tokens) do
Nick@111 652 if (button.numItems >= 1) and (button.isFishingAP == apType) then
Nenue@99 653 if button.itemName then
Nenue@99 654 self:SetItemAction(button)
Nenue@99 655 end
Nenue@99 656
Nenue@99 657 button:ClearAllPoints()
Nenue@99 658 numButtons = numButtons + 1
Nick@111 659 local col = mod(numButtons,8)
Nenue@99 660 print(index, button:GetID(), button.Icon:GetTexture())
Nenue@99 661 if numButtons == 1 then
Nenue@101 662 button:SetPoint('TOPLEFT', self, 'TOPLEFT', 4, -76)
Nenue@99 663 upFrame = button
Nenue@101 664 buttonsHeight = 52
Nenue@99 665 else
Nick@108 666 if col == 1 then
Nick@108 667 button:SetPoint('TOPLEFT', upFrame, 'BOTTOMLEFT', 0, -2)
Nick@108 668 upFrame = button
Nick@108 669 buttonsHeight = buttonsHeight + 52
Nick@108 670
Nick@108 671 else
Nick@108 672 button:SetPoint('TOPLEFT', lastFrame, 'TOPRIGHT', 2, 0)
Nick@108 673
Nick@108 674 end
Nenue@99 675 end
Nick@111 676
Nenue@99 677 button.Count:SetText(button.numItems)
Nenue@99 678 lastFrame = button
Nenue@99 679 button:Show()
Nenue@99 680 else
Nenue@99 681 button:Hide()
Nenue@99 682 end
Nick@111 683 buttonsWidth = min(numButtons, 8) * (BUTTON_SIZE)
Nick@111 684 end
Nick@111 685
Nick@111 686
Nick@111 687
Nick@111 688 if buttonsWidth ~= 0 then
Nick@111 689 buttonsWidth = buttonsWidth + 8+ ((min(numButtons, 8)-1)*2)
Nenue@99 690 end
Nenue@99 691
Nenue@101 692
Nenue@101 693
Nick@108 694 return buttonsWidth, buttonsHeight
Nenue@99 695 end
Nenue@99 696
Nenue@116 697 function Module:SetItemAction(button, name)
Nenue@99 698 name = name or self.itemName
Nenue@99 699 if InCombatLockdown() then
Nenue@99 700 self.itemName = name
Nenue@99 701 return
Nenue@99 702 else
Nenue@99 703 button:SetAttribute('*type*','item')
Nenue@99 704 button:SetAttribute('*item*', name)
Nenue@99 705 end
Nenue@99 706 end
Nenue@99 707
Nenue@116 708 function Module:GetItemButton(itemID, texture, itemAP, fishing)
Nenue@99 709 print('|cFF00FFFFGetItemButton()|r', itemID, texture, itemAP)
Nenue@99 710 local button = self.ItemButtons[itemID]
Nenue@101 711
Nenue@99 712 if not button then
Nenue@99 713 button = CreateFrame('Button', 'VeneerAPToken'..itemID, self, 'VeneerItemButton')
Nenue@101 714 button.baseAP = itemAP
Nenue@101 715
Nenue@99 716 button:SetPushedTexture([[Interface\Buttons\UI-Quickslot-Depress]])
Nenue@99 717 button:SetHighlightTexture([[Interface\Buttons\ButtonHilight-Square]],"ADD")
Nenue@99 718 button:SetID(itemID)
Nenue@99 719 button.numItems = 0
Nenue@99 720 button.Icon:SetTexture(texture)
Nenue@99 721 button:RegisterForClicks("AnyUp")
Nick@111 722 button.isFishingAP = fishing
Nenue@99 723 self:SetItemAction(button, GetItemInfo(itemID))
Nenue@99 724
Nenue@99 725 print(' created')
Nenue@99 726 self.ItemButtons[itemID] = button
Nenue@99 727 self.numItems = self.numItems + 1
Nenue@99 728 end
Nenue@99 729
Nenue@116 730 button.Label:SetText(ShortNumberString(itemAP))
Nenue@101 731
Nenue@99 732 button.numItems = button.numItems + 1
Nenue@99 733 return button
Nenue@99 734 end
Nenue@99 735
Nenue@116 736 function Module:GetItemAP(itemID, itemLink, bagData)
Nick@108 737 if not self.cache.items[itemID] then
Nenue@101 738
Nick@111 739 print('doing tooltip scan', itemLink, itemID)
Nenue@101 740 self.tooltip:SetOwner(self, 'ANCHOR_NONE')
Nenue@101 741 self.tooltip:SetHyperlink(itemLink)
Nenue@101 742 self.tooltip:Show()
Nenue@101 743 local numLines = self.tooltip:NumLines()
Nenue@101 744 if numLines >= 3 then
Nenue@101 745 for i = 3, numLines do
Nenue@101 746 local text = _G[TOOLTIP_NAME .. 'TextLeft'.. i]:GetText()
Nick@111 747 if text then
Nick@111 748
Nick@111 749 text = text:lower():gsub(',', '')
Nenue@116 750
Nick@111 751 if text:match('equipped artifact') then
Nick@111 752 print(itemLink, '-', tonumber(text))
Nenue@116 753
Nenue@116 754 local itemAP = text:match('[%d%.]+')
Nick@111 755 if itemAP then
Nenue@116 756 -- tokens > 1M are described as '%f million'
Nenue@116 757 if text:match("million") then
Nenue@116 758 itemAP = tonumber(itemAP) * 1000000
Nenue@116 759 end
Nenue@116 760
Nick@111 761 itemAP = itemAP
Nick@111 762 self.cache.items[itemID] = tonumber(itemAP)
Nick@111 763 end
Nick@111 764 end
Nick@111 765 if text:match('fishing artifact') then
Nick@111 766 local fishingAP = text:match("%d+")
Nick@111 767 fishingAP = fishingAP
Nick@111 768 print(itemLink, 'fishing', tonumber(text))
Nick@111 769 if fishingAP then
Nick@111 770 self.cache.items[itemID] = tonumber(fishingAP)
Nick@111 771 self.cache.fishing[itemID] = true
Nick@111 772 end
Nenue@101 773 end
Nenue@101 774 end
Nenue@101 775 end
Nenue@101 776 else
Nenue@101 777
Nick@108 778 self.cache.items[itemID] = 0
Nenue@101 779 end
Nenue@101 780 end
Nick@108 781 return self.cache.items[itemID], self.cache.fishing[itemID]
Nenue@101 782 end
Nenue@101 783
Nenue@122 784 function Module:UpdateArtifact(itemID, name, texture, currentXP, pointsSpent)
Nenue@122 785 print('|cFF00FF00UpdateArtifact()|r')
Nenue@103 786 if not self.profile then
Nenue@103 787 return
Nenue@103 788 end
Nenue@103 789 local artifacts = self.profile.artifacts
Nenue@103 790
Nenue@103 791 if itemID then
Nenue@103 792 self.currentEquipped = itemID
Nenue@103 793
Nenue@103 794 artifacts[itemID] = artifacts[itemID] or {}
Nenue@103 795 table.wipe(artifacts[itemID])
Nenue@103 796 local artifact = artifacts[itemID]
Nenue@103 797
Nenue@103 798 artifact.name = name
Nenue@103 799 artifact.texture = texture
Nenue@103 800 artifact.currentXP = currentXP
Nenue@103 801 artifact.level = pointsSpent
Nenue@116 802 artifact.tier = C_ArtifactUI.GetArtifactTier() or ((pointsSpent >= 36) and 2 or 1)
Nenue@122 803 artifact.itemID = itemID
Nenue@116 804
Nenue@116 805 print('tier', artifact.tier)
Nenue@116 806 local cost = C_ArtifactUI.GetCostForPointAtRank(pointsSpent, artifact.tier)
Nick@108 807 artifact.currentCost = cost
Nenue@103 808
Nenue@122 809 for index, frame in pairs(self.Artifact) do
Nenue@122 810 if frame.itemID == itemID then
Nenue@122 811 frame:SetItem(itemID, artifact, index, (itemID == self.equippedID), (itemID == UNDERLIGHT_ANGLER_ID))
Nenue@122 812 end
Nenue@122 813 end
Nenue@103 814
Nenue@103 815 end
Nenue@103 816 end
Nenue@103 817
Nenue@116 818 function Module:ScanBag(id)
Nenue@97 819 print('|cFF00FFFFScanBag()|r', id, IsBagOpen(id), GetContainerNumSlots(id))
Nenue@97 820 local numSlots = GetContainerNumSlots(id)
Nenue@97 821 local requiresUpdate
Nenue@97 822 if numSlots == 0 then
Nenue@97 823 return nil
Nenue@97 824 end
Nenue@97 825
Nenue@97 826
Nenue@97 827 self.profile.bagslots[id] = self.profile.bagslots[id] or {}
Nenue@97 828 table.wipe(self.profile.bagslots[id])
Nenue@97 829 local bagData = self.profile.bagslots[id]
Nenue@97 830 bagData.totalAP = 0
Nenue@99 831 bagData.fishingAP = 0
Nenue@99 832 bagData.items = bagData.items or {}
Nenue@99 833 table.wipe(bagData.items)
Nick@111 834 local c = self.cache
Nenue@99 835
Nick@111 836 c.bagItems[id] = c.bagItems[id] or {}
Nick@111 837 c.bags[id] = c.bags[id] or {}
Nick@111 838 c.fishing[id] = c.fishing[id] or {}
Nick@108 839
Nenue@97 840 for slotID = 1, numSlots do
Nenue@97 841 local texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(id, slotID)
Nenue@101 842 if link then
Nenue@101 843 local itemID = GetContainerItemID(id, slotID)
Nenue@101 844 local name, _, quality, iLevel, reqLevel, class, subclass = GetItemInfo(link)
Nenue@97 845
Nick@111 846 if class == 'Consumable' or subclass == 'Cooking' then
Nenue@102 847 --print(GetItemInfo(link))
Nick@108 848 local itemAP, isFishingAP
Nick@111 849 if c.bags[id][slotID] and (c.bagItems[id][slotID] == itemID) then
Nick@111 850 --print('cached slot', id, slotID, name)
Nick@111 851 itemAP = c.bags[id][slotID]
Nick@111 852 isFishingAP = c.fishing[id] and c.fishing[id][slotID]
Nick@108 853 else
Nick@108 854 itemAP, isFishingAP = self:GetItemAP(itemID, link)
Nick@111 855 c.bagItems[id][slotID] = itemID
Nick@111 856 c.bags[id][slotID] = itemAP
Nick@111 857 c.fishing[id][slotID] = isFishingAP
Nick@108 858 end
Nick@108 859
Nick@108 860
Nenue@102 861 --print(itemAP, isFishingAP)
Nenue@102 862 if itemAP and (itemAP > 0) then
Nick@111 863 local itemButton = self:GetItemButton(itemID, texture, itemAP, isFishingAP)
Nenue@102 864
Nenue@101 865 if isFishingAP then
Nenue@101 866 bagData.fishingItems = (bagData.fishingItems or 0) + 1
Nenue@101 867 bagData.fishingAP = (bagData.fishingAP or 0) + itemAP
Nenue@101 868 else
Nick@108 869 itemAP = itemAP
Nenue@101 870 bagData.numItems = (bagData.numItems or 0) + 1
Nenue@101 871 bagData.totalAP = (bagData.totalAP or 0) + itemAP
Nenue@101 872 end
Nenue@101 873 bagData.items[itemID] = (bagData.items[itemID] or 0) + 1
Nenue@101 874 end
Nenue@101 875 elseif self.profile.artifacts[itemID] then
Nick@111 876 --print('artifact weapon', itemID, link, id, slotID)
Nenue@101 877 self.profile.artifacts[itemID].containerID = id
Nenue@101 878 self.profile.artifacts[itemID].slotID = slotID
Nick@111 879 else
Nick@111 880 --print('skipping', class, subclass, link)
Nenue@101 881 end
Nenue@99 882
Nenue@97 883 end
Nenue@97 884
Nenue@97 885 end
Nenue@97 886
Nenue@97 887 end
Nenue@97 888
Nenue@98 889 local BAG_SLOTS = {0, 1, 2, 3, 4 }
Nenue@98 890 local BANK_SLOTS = {-1, 5, 6,7, 8, 9, 10, 11, 12}
Nenue@99 891 local ItemCounts = {}
Nenue@116 892 function Module:ScanAllBags()
Nenue@99 893 if InCombatLockdown() then
Nenue@99 894 self.queuedScan = true
Nenue@99 895 return
Nenue@99 896 end
Nenue@101 897 if not self.profile.knowledgeMultiplier then
Nenue@101 898 print('need to get knowledge level')
Nenue@101 899 return
Nenue@101 900 end
Nenue@101 901
Nenue@99 902 self.queuedScan = nil
Nenue@98 903
Nenue@101 904 print('|cFFFF0088ScanAllBags()|r', self.profile.knowledgeMultiplier)
Nenue@97 905
Nenue@99 906 for _, button in ipairs(self.Tokens) do
Nenue@99 907 button.numItems = 0
Nenue@99 908 end
Nenue@99 909
Nenue@99 910
Nenue@98 911 for _, bagID in ipairs(BAG_SLOTS) do
Nenue@98 912 self:ScanBag(bagID)
Nenue@97 913 end
Nenue@97 914
Nenue@99 915 if self.bankAccess then
Nenue@98 916 for _, bagID in ipairs(BANK_SLOTS) do
Nenue@98 917 self:ScanBag(bagID)
Nenue@98 918 end
Nenue@98 919 end
Nenue@98 920
Nenue@98 921 self.bankAP = 0
Nenue@98 922 self.bagAP = 0
Nenue@99 923 self.fishingAP = 0
Nenue@99 924
Nenue@99 925 table.wipe(ItemCounts)
Nenue@98 926 for id, bagData in pairs(self.profile.bagslots) do
Nick@111 927 print(id, GetBagName(id), bagData.totalAP, bagData.fishingAP)
Nenue@98 928 id = tonumber(id)
Nenue@98 929 if bagData.totalAP then
Nenue@98 930 if (id == BANK_CONTAINER) or (id >= 5) then
Nenue@98 931 self.bankAP = self.bankAP + bagData.totalAP
Nenue@98 932 else
Nenue@98 933 self.bagAP = self.bagAP + bagData.totalAP
Nenue@97 934 end
Nenue@98 935 end
Nenue@99 936 if bagData.fishingAP then
Nenue@99 937 self.fishingAP = self.fishingAP + bagData.fishingAP
Nenue@99 938 end
Nenue@97 939
Nenue@97 940 end
Nenue@98 941 self.lastUpdate = GetTime()
Nenue@103 942 self.queuedScan = nil
Nenue@99 943 self:TryToShow()
Nenue@97 944 end
Nenue@97 945
Nenue@98 946
Nenue@122 947 function Artifact:SetItem(itemID, artifact, index, equipped, fishing)
Nenue@122 948 print('|cFF00FFFFSetItem()|r', itemID, index)
Nenue@98 949 print(artifact.name, artifact.texture, artifact.currentXP)
Nenue@122 950
Nick@108 951 if not artifact.currentCost then
Nick@108 952 artifact.currentCost = artifact.cost
Nick@108 953 end
Nick@108 954
Nenue@98 955 for k,v in pairs(artifact) do
Nenue@98 956 --print('::',k,v)
Nenue@98 957 self[k] = v
Nenue@98 958 end
Nenue@98 959
Nick@111 960 self.isFishing = fishing
Nenue@98 961 -- this can change between artifact parses
Nenue@117 962 local unusedXP = (itemID ~= UNDERLIGHT_ANGLER_ID) and ((self:GetParent().bankAP or 0) + (self:GetParent().bagAP or 0)) or (self:GetParent().fishingAP or 0)
Nenue@117 963 print('unspent:', unusedXP)
Nenue@99 964
Nenue@117 965 -- current standing artifact XP (what appears in the artifact ui)
Nenue@117 966 -- actual artifact XP after any unlocked points are spent
Nenue@117 967 -- total total of invested and inventory XP
Nenue@117 968 -- totalCost total of costs between current and actual level
Nenue@117 969 local actualXP = artifact.currentXP
Nenue@116 970 local actualLevel = artifact.level
Nenue@116 971 local actualCost = C_ArtifactUI.GetCostForPointAtRank(actualLevel, artifact.tier)
Nenue@119 972 local totalXP = actualXP
Nenue@117 973 local totalCost = actualCost
Nenue@117 974 local totalLevel = actualLevel
Nenue@116 975
Nenue@117 976 print('tier:', artifact.tier)
Nenue@117 977 print('current:', self.level, self.currentXP, '/', self.currentCost)
Nenue@116 978 while actualXP >= actualCost do
Nenue@116 979 actualXP = actualXP - actualCost
Nenue@116 980 actualLevel = actualLevel + 1
Nenue@116 981 actualCost = C_ArtifactUI.GetCostForPointAtRank(actualLevel, artifact.tier)
Nenue@117 982
Nenue@117 983 print('* ', actualLevel, actualXP, actualCost, totalCost)
Nenue@98 984 end
Nenue@117 985 print('actual:', actualLevel, actualXP, '/', actualCost)
Nenue@117 986
Nenue@117 987
Nenue@120 988 local remaining = totalXP + unusedXP
Nenue@120 989 local nextCost = artifact.currentCost
Nenue@120 990 if remaining > nextCost then
Nenue@117 991 totalCost = nextCost
Nenue@120 992 while remaining >= nextCost do
Nenue@117 993 totalLevel = totalLevel + 1
Nenue@119 994 remaining = remaining - nextCost
Nenue@117 995 nextCost = C_ArtifactUI.GetCostForPointAtRank(totalLevel, artifact.tier)
Nenue@119 996 print('|cFFFFFF00+ ', totalLevel, remaining, '/', totalCost)
Nenue@117 997 end
Nenue@119 998 totalXP = remaining
Nenue@119 999 totalCost = nextCost
Nenue@117 1000 end
Nenue@117 1001 print('total:', totalLevel, totalXP, '/', totalCost)
Nenue@117 1002
Nenue@117 1003 self.currentLevel = self.level
Nenue@117 1004
Nenue@117 1005
Nenue@116 1006 self.actualCost = actualCost
Nenue@116 1007 self.actualLevel = actualLevel
Nenue@116 1008 self.actualXP = actualXP
Nenue@117 1009
Nenue@117 1010 self.totalXP = totalXP
Nenue@117 1011 self.totalCost = totalCost
Nenue@117 1012 self.totalLevel = totalLevel
Nenue@117 1013
Nenue@98 1014
Nenue@98 1015
Nenue@99 1016 if index ~= 1 then
Nenue@99 1017 self:ClearAllPoints()
Nenue@99 1018 self:SetPoint('TOPLEFT', self.relativeFrame, 'TOPRIGHT', 4, 0)
Nenue@99 1019 else
Nenue@99 1020 self:ClearAllPoints()
Nenue@99 1021 self:SetPoint('TOPLEFT', self.relativeFrame, 'TOPLEFT', 4, -4)
Nenue@99 1022 end
Nenue@98 1023
Nenue@122 1024 self.itemID = itemID
Nenue@99 1025 self.isEquipped = equipped
Nenue@98 1026 self:Update()
Nenue@98 1027 self:Show()
Nenue@122 1028
Nenue@98 1029 return self
Nenue@98 1030 end
Nenue@98 1031
Nenue@122 1032 function Artifact:UpdateXPBar()
Nenue@122 1033 local r3, g3, b3 = 1, .5, 0 -- main xp bar
Nenue@122 1034 -- current: amount shown in blizz ui
Nenue@122 1035 -- actual: amount contributing the next level, will be same until current point cap is reached
Nenue@122 1036 -- potential: total of ap on hand
Nenue@122 1037 print(self.currentXP, self.actualXP, self.potentialXP)
Nenue@122 1038
Nenue@122 1039 local maxHeight = self:GetHeight() - 8
Nenue@122 1040 local currentHeight = self.CurrentProgress:GetHeight() or 1
Nenue@122 1041 local offHeight = self.AdjustedProgress:GetHeight() or 1
Nenue@122 1042
Nenue@122 1043
Nenue@122 1044 local currentProgress = (self.currentXP < self.currentCost) and (self.currentXP / self.currentCost) or 1
Nenue@122 1045 local projectedProgress = (self.totalXP < self.totalCost) and (self.totalXP / self.totalCost) or 1
Nenue@122 1046 if self.actualLevel ~= self.level then
Nenue@122 1047 r3, g3, b3 = 0, 1, 1
Nenue@122 1048 end
Nenue@122 1049
Nenue@122 1050 print('|cFFFF4400', currentProgress)
Nenue@122 1051 if self.level <= WEAPON_MAX_TRAITS then
Nenue@122 1052 self.CurrentProgress.animateFrom = currentHeight or 1
Nenue@122 1053 self.CurrentProgress.animateTo = currentProgress * maxHeight
Nenue@122 1054 self.CurrentProgress:Show()
Nenue@122 1055 self.ProgressLine:Show()
Nenue@122 1056 else
Nenue@122 1057 self.CurrentProgress:Hide()
Nenue@122 1058 self.ProgressLine:Hide()
Nenue@122 1059 end
Nenue@122 1060
Nenue@122 1061 if self.totalXP ~= self.currentXP then
Nenue@122 1062 print('|cFF00FFFF', projectedProgress)
Nenue@122 1063 if (projectedProgress > currentProgress) then
Nenue@122 1064 self.AdjustedProgress:SetPoint('BOTTOM', self.CurrentProgress, 'TOP')
Nenue@122 1065 projectedProgress = projectedProgress - currentProgress
Nenue@122 1066 print('show projected above', currentProgress, projectedProgress)
Nenue@122 1067 else
Nenue@122 1068 self.CurrentProgress:Hide()
Nenue@122 1069 self.ProgressLine:Hide()
Nenue@122 1070 self.AdjustedProgress:SetPoint('BOTTOM', self, 'BOTTOM', 0 , 4)
Nenue@122 1071 print('show projected at bottom', currentProgress, projectedProgress)
Nenue@122 1072 end
Nenue@122 1073
Nenue@122 1074 self.AdjustedProgress.animateFrom = self.AdjustedProgress:GetHeight() or 1
Nenue@122 1075 self.AdjustedProgress.animateTo = projectedProgress * self:GetHeight()
Nenue@122 1076 self.AdjustedLine:Show()
Nenue@122 1077 self.AdjustedProgress:Show()
Nenue@122 1078 else
Nenue@122 1079 self.CurrentProgress:SetPoint('BOTTOM', self, 'BOTTOM', 0, 4)
Nenue@122 1080 self.AdjustedProgress:Hide()
Nenue@122 1081 self.AdjustedLine:Hide()
Nenue@122 1082 end
Nenue@122 1083 --print(self.CurrentProgress:GetPoint(3))
Nenue@122 1084 --print(self.CurrentProgress:GetSize())
Nenue@122 1085
Nenue@122 1086 self.CurrentProgress:SetColorTexture(r3,g3,b3,1)
Nenue@122 1087
Nenue@122 1088 end
Nenue@122 1089
Nenue@122 1090 function Artifact:OnLoad()
Nenue@122 1091 print('|cFFFF4400OnLoad()|r', self:GetName(), self:GetID())
Nenue@122 1092 self:RegisterEvent('ARTIFACT_UPDATE')
Nenue@122 1093 self:RegisterEvent('PLAYER_LOGIN')
Nenue@122 1094 end
Nenue@122 1095
Nenue@122 1096 function Artifact:OnEvent(event)
Nenue@122 1097 local itemID, _, _, nextCost = C_ArtifactUI.GetEquippedArtifactInfo()
Nenue@122 1098 print(self:GetID(), '|cFFFF4400OnEvent()|r', event, itemID, '=', self.itemID, (itemID == self.itemID))
Nenue@122 1099 if itemID == self.itemID then
Nenue@122 1100 self:Update()
Nenue@122 1101 end
Nenue@122 1102 end
Nenue@122 1103
Nenue@116 1104 function Artifact:Update()
Nenue@122 1105 if not self.itemID then
Nenue@122 1106 return
Nenue@122 1107 end
Nenue@122 1108
Nenue@122 1109 print(self:GetName(), '|ff00FFFFUpdate()|r')
Nenue@122 1110 local r1, g1, b1 = 1, 1, 1 -- top text
Nenue@122 1111 local r2, g2, b2 = 1, 1, 0 -- bottom text
Nenue@99 1112 local levelText = self.level
Nenue@116 1113 local xpText = ShortNumberString(self.currentXP)
Nenue@116 1114 local costText = ShortNumberString(self.currentCost)
Nenue@116 1115 local remainingText = ShortNumberString(self.currentCost - self.currentXP)
Nenue@122 1116
Nenue@122 1117 local maxHeight = self:GetHeight() - 4
Nenue@122 1118 local currentHeight = self.CurrentProgress:GetHeight() or 1
Nenue@122 1119 local offHeight = self.AdjustedProgress:GetHeight() or 1
Nenue@122 1120
Nenue@97 1121 if self.actualLevel ~= self.level then
Nenue@116 1122 levelText = self.actualLevel
Nenue@116 1123 r1, g1, b1 = 0, 1, 0
Nenue@116 1124 xpText = ShortNumberString(self.actualXP)
Nenue@116 1125 costText = ShortNumberString(self.actualCost)
Nenue@116 1126 remainingText = ShortNumberString(self.actualCost-self.actualXP)
Nenue@116 1127 --[[elseif self.potentialLevel ~= self.level then
Nenue@116 1128 r1, g1, b1 = 0, 1, 1
Nenue@116 1129 r2, g2, b2 = 0, 1, 1
Nenue@116 1130 costText = ShortNumberString(self.potentialCost)
Nenue@116 1131 remainingText = ShortNumberString(self.potentialCost-self.potentialXP)
Nenue@116 1132 --]]
Nenue@97 1133 end
Nenue@97 1134
Nenue@99 1135 self.Level:SetText(levelText)
Nenue@116 1136 self.CurrentXP:SetText( xpText )
Nenue@116 1137 self.RemainingCost:SetText(remainingText)
Nenue@116 1138 self.Level:SetTextColor(r1, g1, b1)
Nenue@116 1139 self.CurrentXP:SetTextColor(r1, g1, b1)
Nenue@99 1140
Nenue@97 1141 if self.isEquipped then
Nenue@116 1142 self:SetSize(64,64)
Nenue@97 1143 self:SetNormalTexture([[Interface\Buttons\ButtonHilight-Square]])
Nenue@97 1144 self:GetNormalTexture():SetBlendMode('ADD')
Nenue@97 1145 self:GetNormalTexture():SetVertexColor(0,1,0)
Nenue@97 1146 else
Nenue@116 1147 self:SetSize(48,48)
Nenue@97 1148 self:SetNormalTexture(nil, 'ADD')
Nenue@97 1149 end
Nenue@97 1150
Nenue@122 1151 self:UpdateXPBar()
Nenue@116 1152
Nenue@117 1153 if self.actualLevel ~= self.currentLevel then
Nenue@117 1154 self:SetNormalTexture([[Interface\Buttons\UI-Quickslot-Depress]], 'ADD')
Nenue@117 1155 self:GetNormalTexture():SetBlendMode('BLEND')
Nenue@117 1156 self:GetNormalTexture():SetVertexColor(1,1,1)
Nenue@117 1157 else
Nenue@117 1158 self:SetNormalTexture(nil, 'ADD')
Nenue@117 1159 end
Nenue@97 1160 self.Icon:SetTexture(self.texture)
Nenue@97 1161 end
Nenue@97 1162
Nenue@119 1163 local XP_SCALING_DURATION = .5
Nenue@116 1164 function Artifact:AnimateProgress(region)
Nenue@98 1165 local cTime = GetTime()
Nenue@98 1166 if not region.animateStart then
Nenue@98 1167 region.animateStart = cTime
Nenue@98 1168 end
Nenue@98 1169 local progressTo, progressFrom = region.animateTo, region.animateFrom
Nenue@98 1170 local elapsed = cTime - region.animateStart
Nenue@119 1171 if elapsed >= XP_SCALING_DURATION then
Nenue@98 1172 region:SetHeight(progressTo)
Nenue@98 1173 region.animateTo = nil
Nenue@98 1174 region.animateStart = nil
Nenue@98 1175 region.animateFrom = nil
Nenue@98 1176 else
Nenue@119 1177 local progress = elapsed / XP_SCALING_DURATION
Nenue@98 1178 local height = (progressFrom + (progressTo - progressFrom) * progress)
Nenue@98 1179 --print(self:GetName(), progressTo, progressFrom, (progressTo - progressFrom), ceil(progress*10)/10, ceil(height))
Nenue@98 1180 region:SetHeight(height)
Nenue@98 1181 end
Nenue@98 1182 end
Nenue@98 1183
Nenue@116 1184 function Artifact:OnUpdate(sinceLast)
Nenue@98 1185 if self.CurrentProgress.animateTo then
Nenue@98 1186 self:AnimateProgress(self.CurrentProgress)
Nenue@98 1187 end
Nenue@98 1188
Nenue@98 1189 if self.AdjustedProgress.animateTo then
Nenue@98 1190 self:AnimateProgress(self.AdjustedProgress)
Nenue@98 1191 end
Nenue@98 1192 end
Nenue@98 1193
Nenue@116 1194 function Artifact:OnEnter()
Nenue@97 1195 GameTooltip:SetOwner(self, 'ANCHOR_CURSOR')
Nenue@97 1196 GameTooltip:SetText(self.name)
Nenue@119 1197 GameTooltip:AddLine(ShortNumberString(self.currentXP) .. ' / '..ShortNumberString(self.currentCost), 1, 1, 1)
Nenue@99 1198 if self.actualLevel ~= self.level then
Nenue@119 1199 GameTooltip:AddLine(ShortNumberString(self.actualLevel - self.level) .. ' points unlocked', 1, 1, 0)
Nick@108 1200 end
Nick@108 1201 if self.currentXP < self.currentCost then
Nenue@117 1202 GameTooltip:AddLine(ShortNumberString(self.currentCost - self.currentXP) .. ' for level ' .. (self.currentLevel+1), 1, 1, 0)
Nenue@117 1203 else
Nenue@117 1204 GameTooltip:AddLine(ShortNumberString(self.actualCost - self.actualXP) .. ' for level ' .. (self.actualLevel+1), 0, 1, 0)
Nenue@117 1205 end
Nenue@117 1206 if self.totalLevel ~= self.actualLevel then
Nenue@117 1207 GameTooltip:AddLine('Level ' .. self.totalLevel .. ' with unspent tokens', 0, 1, 1)
Nenue@99 1208 end
Nenue@99 1209
Nenue@97 1210 GameTooltip:Show()
Nenue@97 1211 end
Nenue@116 1212 function Artifact:OnLeave()
Nenue@97 1213 if GameTooltip:IsOwned(self) then
Nenue@97 1214 GameTooltip:Hide()
Nenue@97 1215 end
Nenue@97 1216 end
Nenue@116 1217 function Artifact:OnHide()
Nick@108 1218
Nick@108 1219 if GameTooltip:IsOwned(self) then
Nick@108 1220 GameTooltip:Hide()
Nick@108 1221 end
Nick@108 1222 end
Nenue@97 1223
Nenue@116 1224 function Artifact:OnClick(button, down)
Nenue@97 1225 if self.isEquipped then
Nenue@97 1226 SocketInventoryItem(16)
Nenue@97 1227 else
Nick@108 1228 if IsShiftKeyDown() then
Nenue@119 1229 SocketContainerItem(self.containerID, self.slotID)
Nick@108 1230 else
Nick@108 1231
Nick@108 1232 end
Nenue@97 1233 end
Nenue@122 1234 end