annotate Modules/ArtifactPower.lua @ 120:5f1ba488c395

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