annotate Modules/ArtifactPower.lua @ 116:ddfe19d70a34

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